程序问答   发布时间:2022-06-01  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了从 GitHub 存储库克隆/下载特定文件大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决从 GitHub 存储库克隆/下载特定文件?

开发过程中遇到从 GitHub 存储库克隆/下载特定文件的问题如何解决?下面主要结合日常开发的经验,给出你关于从 GitHub 存储库克隆/下载特定文件的解决方法建议,希望对你解决从 GitHub 存储库克隆/下载特定文件有所启发或帮助;

GitHub 上有一个名为 platform_frameworks_base 的 Git 存储库,其中包含部分 AndroID 源代码。
我编写了一个应用程序,该应用程序会回复该项目中的所有 .aIDl 文件,因此它会在第一次启动时下载所有文件。
到目前为止,我通过从项目根目录下载文件 Android.bp,从该文件中提取所有以 .aIDl 结尾的文件路径,然后明确地将它们一一下载。

例如,如果我找到了这个文件路径:

@H_648_9@media/java/androID/media/IAudioservice.aIDl

我知道我可以像这样下载它:

wget https://raw.githubusercontent.com/aosp-mirror/platform_frameworks_base/androID-10.0.0_r47/media/java/androID/media/IAudioservice.aIDl

这在 AndroID 10 之前都可以正常工作(git 标签:androID-10.0.0_r47)。
从 AndroID 11(例如 git tag: androID-11.0.0_r33)开始,文件路径使用通配符而不是完整路径。请参阅此Android.bp。

它现在只包含通配符/glob 文件路径,例如:

@H_648_9@media/java/**/*.aIDl
LOCATIOn/java/**/*.aIDl

等等...

我目前的“解决方案”:

  1. 克隆 repo(仅我们关心的分支的最后一次提交):

    git clone --depth=1 -b androID-11.0.0_r33 https://github.com/aosp-mirror/platform_frameworks_base.git

  2. 从 AndroID.bp 中提取通配符/glob 路径。

    cat AndroID.bp | grep '\.aIDl"' | cut -d'"' -f2

  3. 查找与通配符/glob 路径匹配的所有文件。

    例如shopt -s globstar && echo media/java/**/*.aIDl

但是下载过程需要很长时间,因为存储库包含超过 千兆字节 的二进制文件。即使我只是克隆了我关心的分支的最后一次提交。

现在我的实际问题是:
如何只下载我真正关心的 .aIDl 文件? (理想情况下不解析 GitHub 中每个文件夹的 HTML。)

如何在没有所有二进制文件的情况下下载/克隆存储库? (可能用 git 不可能?)

编辑:

我尝试使用 GitHub API 递归遍历所有目录,但我立即收到 API rate limit exceeded 错误:

g_aIDlfiles=""

# Recursively go through all directorIEs @R_197_6296@e paths to all found .aIDl files in the global g_aIDlfile variable
GetAIDlfilesFromGithub() {
    l_dirUrl="${1-}"
    if [ "$l_dirUrl" == "" ]; then
        echo "ERROR: Directory URL not provIDed in GetAIDlfilesFromGithub"
        exit 1
    fi
    
    echo "l_dirUrl: ${l_dirUrl}"
    
    l_rawRes="$(curl -s -i $l_dirUrl)"
    l_statusCode="$(echo "$l_rawRes" | grep http | head -1 | cut -d' ' -f2)"
    l_resBody="$(echo "$l_rawRes" | sed '1,/^\s*$/d')"
    if [[ $l_statusCode == 4* ]] || [[ $l_statusCode == 5* ]]; then
        echo "ERROR: request Failed!"
        echo "Response status: $l_statusCode"
        echo "Reponse body:"
        echo "$l_resBody"
        exit 1
    fi
    
    l_currentDirjson="$(echo "$l_resBody")"
    if [ "$l_currentDirjson" == "" ]; then
        echo "ERROR: l_currentDirjson is empty"
        exit 1
    fi
    
    l_newAIDlfiles="$(echo "$l_currentDirjson" | jq '.[] | @R_673_10288@ct(.type=="file") | @R_673_10288@ct(.path | endswith(".aIDl")) | .path')"
    
    if [ "$l_newAIDlfiles" != "" ]; then
        echo "l_newAIDlfiles: ${l_newAIDlfiles}"
        g_aIDlfiles="${g_aIDlfiles}\n${l_newAIDlfiles}"
    fi

    l_subDirUrls="$(echo "$l_currentDirjson" | jq '.[] | @R_673_10288@ct(.type=="dir") | .url')"
    if [ "$l_subDirUrls" != "" ]; then
        echo "$l_subDirUrls" | while IFS= read -r l_subDirUrl ; do 
            (GetAIDlfilesFromGithub "$l_subDirUrl")
        done
    else
        echo "No subdirs found."
    fi
}

GetAIDlfilesFromGithub "https://API.github.com/repos/aosp-mirror/platform_frameworks_base/contents?ref=androID-11.0.0_r33"

据我所知,我的所有用户都必须创建一个 GitHub 帐户并创建一个 OAUTH 机密才能提高限制。这绝对不是我的选择。我希望我的应用程序易于使用。

解决方法

由于 GitHub 上的存储库支持过滤器,因此最简单的方法可能是使用其过滤器支持。

git clone --no-checkout --depth=1 --filter=blob:none \
        https://github.com/aosp-mirror/platform_frameworks_base
cd platform_frameworks_base
git reset -q -- \*.aidl
git checkout-index -a

为了将文件发送到一个包中,而不是生成的一次一次获取,这可能会被巧妙地处理很多。

例如,与其说 blob:noneblob:limit=16384,不如说是将其中大部分放在前面。

要在您自己的代码中执行此操作,而不依赖于 Git 安装,您需要实现 git 协议。 Here's the onlinE intro with pointers to the actual Git docs。这并不难,你来回发送文本行,直到服务器吐出你想要的大量数据,然后你选择它。你不需要使用 https,github 支持普通的 git 协议。尝试使用 GIT_TRACE=1 GIT_PACKET_TRACE=1 运行该克隆命令。

,

不确定这是否是您想要的:

#!/usr/bin/env bash
  
get_github_file_list(){
    local user=$1 repo=$2 branch=$3
    curl -s "https://api.github.com/repos/$user/$repo/git/trees/$branch?recursive=1"
}

get_github_file_list aosp-mirror platform_frameworks_base android-11.0.0_r33 |\
    jq -r '.tree|map(.path|@R_673_10288@ct(test("\\.aidl")))[]'
,

您可以使用 GitHub API 代码搜索端点来获取路径,然后使用 wget raw.githubusercontent 方法下载它们:

apiurlbase='https://api.github.com/search/code?per_page=100&q=repo:aosp-mirror/platform_frameworks_base+extension:aidl'
dlurlbase='https://raw.githubusercontent.com/aosp-mirror/platform_frameworks_base/android-10.0.0_r47/'
apiurl1="$apiurlbase+path:/media/java/"
apiurl2="$apiurlbase+path:/LOCATIOn/java/"
for apiurl in "$apiurl1" "$apiurl2"; do
  page=1
  while paths=$(
    curl -s "$apiurl&page=$page" | grep '"path": ' | grep -o '[^"]\+\.aidl'
  ); do
    # do your stuff with the $paths
    page=$(($page + 1))
  done
done

不幸的是,GitHub API 代码搜索端点仅搜索默认分支(在本例中为 master),而您需要 android-10.0.0_r47 标签。 android-10.0.0_r47 中可能有文件,但 master 中没有,此代码无法找到并下载这些文件。

另一种解决方案是对您感兴趣的每个标签进行非常小的克隆,然后使用 git ls-tree 获取每个标签的路径,例如,

for tag in 'android-10.0.0_r47' 'android-11.0.0_r33'; do
  git clone --branch "$tag" --depth=1 --bare --no-checkout \
    --filter=blob:limit=0 git@github.com:aosp-mirror/platform_frameworks_base.git
  # only a 1.8M download
  mv platform_frameworks_base.git "$tag"
  cd "$tag"
  paths=$(git ls-tree -r HEAD --name-only | grep '\.aidl$')
  # do your stuff with the paths
  cd ..
done

如果这是自用,我可能不会使用这两种方法中的任何一种。我只会克隆整个巨大的 repo 一次,然后在本地使用它,例如,

if [ -e platform_frameworks_base ]; then
  cd platform_frameworks_base
  git pull
else
  git clone git@github.com:aosp-mirror/platform_frameworks_base.git
  cd platform_frameworks_base
fi
tags=$(git tag | grep '^android')
for tag in $tags; do
  git checkout $tag
  paths=$(git ls-tree -r HEAD --name-only | grep '\.aidl$')
  # do your stuff with the paths
done
,

假设我会维护一个文本文件,该文件会在每次提交之前自动更新为最新的 repo 文件树。

脚本应该易于编写且运行速度快,因为所有这些都在本地发生。它可以通过引入新的工作流程手动调用,也可以集成到您的测试/CI 自动化流程中。

然后您知道在您的最终用户应用程序中做什么,首先下载此文件,使用 Android.bp 过滤掉它,然后使用 Github 原始内容链接提取您想要的文件。

大佬总结

以上是大佬教程为你收集整理的从 GitHub 存储库克隆/下载特定文件全部内容,希望文章能够帮你解决从 GitHub 存储库克隆/下载特定文件所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签: