Как извлечь общее количество страниц коммитов для репозитория github - PullRequest
0 голосов
/ 10 апреля 2019

Я настраиваю скрипт для экспорта всех коммитов и запросов на извлечение для большего списка репозиториев github (около 4000).

После того, как основная идея скрипта сработает, мне нужен способ перебрать все страницы коммитов для репозитория.

Я обнаружил, что могу экспортировать 100 коммитов на страницу. Для некоторых репозиториев есть еще коммиты (например, 8000), так что мне нужно 80 страниц, чтобы пройти через них.

Я не могу найти способ извлечь количество страниц из API github.

То, что я сделал до сих пор, - это установил скрипт, который проходит через все коммиты и экспортирует их в файл txt / csv.

Что мне нужно сделать, это узнать общее количество страниц, прежде чем я начну циклически повторять коммиты репо.

Здесь приведено количество страниц, которое я не могу использовать.

curl -u "user:password" -I https://api.github.com/repos/0chain/rocksdb/commits?per_page=100

РЕЗУЛЬТАТ:

Ссылка: https://api.github.com/repositories/152923130/commits?per_page=100&page=2; rel = "next", https://api.github.com/repositories/152923130/commits?per_page=100&page=75; rel = "last"

Мне нужно, чтобы значение 75 (или любое другое значение из других репо) использовалось в качестве переменной в цикле.

Вот так:

repolist=`cat repolist.txt`
repolistarray=($(echo $repolist))
repolength=$(echo "${#repolistarray[@]}")

for (( i = 0; i <= $repolength; i++ )); do
    #here i need to extract the pagenumber
    pagenumber=$(curl -u "user:password" -I https://api.github.com/repos/$(echo "${repolistarray[i]}")/commits?per_page=100)

    for (( n = 1; n <= $pagenumber; n++ )); do
        curl -u "user:password" -s https://api.github.com/repos/$(echo "${repolistarray[i]}")/commits?per_page=100&page$(echo "$n") >committest.txt
    done
done

done

Как я могу получить "75" или любой другой результат из этого

Ссылка: https://api.github.com/repositories/152923130/commits?per_page=100&page=2; rel = "next", https://api.github.com/repositories/152923130/commits?per_page=100&page=75; rel = "last"

будет использоваться как "n"?

Ответы [ 2 ]

1 голос
/ 10 апреля 2019

Вот что-то вроде того, что прокомментировал @Poshi: цикл бесконечно запрашивает следующую страницу, пока вы не нажмете пустую страницу, затем вырвитесь из внутреннего цикла, перейдя к следующему репо.

# this is the contents of a page past the last real page:
emptypage='[

]'

# here's a simpler way to iterate over each repo than using a bash array
cat repolist.txt | while read -d' ' repo; do

  # loop indefinitely
  page=0
  while true; do
    page=$((page + 1))

    # minor improvement: use a variable, not a file.
    # also, you don't need to echo variables, just use them
    result=$(curl -u "user:password" -s \ 
      "https://api.github.com/repos/$repo/commits?per_page=100&page=$n")

    # if the result is empty, break out of the inner loop
    [ "$result" = "$emptypage" ] && break

    echo "$result" > committest.txt
    # note that > overwrites (whereas >> appends),
    # so committest.txt will be overwritten with each new page.
    #
    # in the final version, you probably want to process the results here,
    # and then
    #
    #       echo "$processed_results"
    #     done > repo1.txt
    #   done
    #
    # to ouput once per repo, or
    #
    #       echo "$processed_results"
    #     done
    #   done > all_results.txt
    #
    # to output all results to a single file

  done
done
0 голосов
/ 10 апреля 2019

Ну, метод, который вы запрашиваете, не самый распространенный, обычно это делается путем выборки страниц, пока больше нет данных.Но чтобы ответить на ваш конкретный вопрос, мы должны разобрать строку, содержащую информацию.Быстрый и грязный способ сделать это может быть:

response="Link: https://api.github.com/repositories/152923130/commits?per_page=100&page=2; rel=\"next\", https://api.github.com/repositories/152923130/commits?per_page=100&page=75; rel=\"last\""

<<< "$response" cut -f2- -d: | # First, get the contents of "Link": everything after the first colon
tr "," $'\n' |      # Separate the different parts in different lines
grep 'rel="last"' | # Select the line with last page information
cut -f1 -d';' |     # Keep only the URL
tr "?&" $'\n' |     # Split URL and its parameters, one per line
grep -e "^page" |   # Select the "page" parameter
cut -f2 -d=         # Finally, extract the number we are interested in

Есть несколько других способов сделать это, с меньшим количеством команд, может быть, проще, но этот позволяет мне идти шаг за шагом с объяснением.Одним из этих других способов может быть:

<<< "$response" sed 's/.*&page=\(.*\); rel="last".*/\1/'

В этом случае делаются некоторые предположения, например, page всегда будет последним параметром.

...