Рубрики
Без рубрики

Как совершить целые каталоги на Github прямо из вашего браузера с помощью GitHub.js

Иллии Колодиажные Как совершать целые каталоги на Github прямо из вашего браузера, используя github.jsdid, вы знаете, вы можете разбирать веб-сайт базы данных фильма, затем сохранить свои данные в своем собственном репозитории GitHub – не оставляя свой браузер? Вы также можете сделать такие вещи, как изменение веб-страницы

Иллии Колодиажны

Знаете ли вы, что вы можете анализировать веб-сайт базы данных фильма, затем хранит свои данные в своем собственном репозитории GitHub – не выходя из браузера?

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

HTTP API GitHub Позволяет вам использовать почти всю инфраструктуру GitHub. В большинстве случаев это прозрачно и легко понять. Но есть одно, что не так легко сделать на первый взгляд – приготовление приятных коммит с большим количеством файлов одновременно, как работает Git push от вашего терминала делает.

Но не волнуйся. К тому времени, когда вы закончите чтение этой статьи, вы сможете использовать набор вызовов низкого уровня для достижения этого.

Установка

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

pushFiles(    'Making a commit with my adorable files',    [        {content: 'You are a Wizard, Harry', path: 'harry.txt'},        {content: 'May the Force be with you', path: 'jedi.txt'}    ]);

Есть несколько важных вещей, которые следует отметить, хотя:

  • Я собираюсь использовать Github-js Библиотека для упрощения вещей. Это удобная обертка вокруг вызовов на API.
  • Хотя будет только одна функция для выполнения работы, она сделает много запросов под капотом. Это связано с тем, как создан API GitHub – он должен сделать хотя бы один запрос на файл, представленный, затем несколько дополнительных запросов.
  • Обязательные двоичные файлы (например, изображения) потребуют немного более настроек. У меня есть специальный раздел ниже, который охватывает это.

Алгоритм для успеха

Посмотрите на внутреннюю структуру репозитория GitHub:

Вот краткое объяснение того, как это работает: верхний указатель каждой ветви указывает на определенный коммит, который указывает на дерево, который указывает на версию файла. Это в основном тип предметов, о которых вы должны заботиться: Совершать С Дерево а также Blob (Содержание файла).

Каждый содержит хеш-строку, называемую SHA – это на самом деле контрольно-контрольный хеш объекта. Таким образом, объекты указывают друг на друга, используя эти значения SHA.

На Страница данных Git API, вы можете найти описание алгоритма для достижения именно вашей цели. Но вот как это работает подробно:

  1. Извлекает текущий самый свежий Совершать и помнит свою шату. Позже нужно будет разместить новый Совершать на вершине старого.
  2. Извлекает Дерево текущего Совершать И помнит свою шату тоже. Это потребуется для создания нового Дерево основывать его на старом.
  3. Создает новый Blobs Для каждого из ваших файлов, затем сохраняет их SHA.
  4. Создает новый Дерево и передает информацию о Blobs это создано на шаге 3 и SHA Старый Дерево Получено на шаге 2. Это создаст отношение между старым Совершать и новый.
  5. Создает новый Совершать Использование: SHA старого Совершать Извлечено на шаге 1, SHA Дерево Создано на шаге 4, и сообщение Commit для нового Совершать Отказ
  6. Наконец, обновляет указатель ветви, чтобы указать на вновь созданные Совершать Отказ

Кроме того, обратите внимание, что есть также шаг аутентификации, а шаг, в котором GitHub устанавливает репозиторий и ветвь, которую вы хотели бы нажать.

Теперь, когда у вас есть концептуальное понимание того, как это работает, давайте погрузимся в веселую часть – получение вещей с кодом!

Святой код!

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

function GithubAPI(auth) {    let repo;    let filesToCommit = [];    let currentBranch = {};    let newCommit = {};
    this.gh = new GitHub(auth);
    this.setRepo = function() {}    this.setBranch = function() {}    this.pushFiles = function() {}
    function getCurrentCommitSHA() {}    function getCurrentTreeSHA() {}    function createFiles() {}    function createFile() {}    function createTree() {}    function createCommit() {}    function updateHead() {}};

setrepo () Просто передает аргументы в базовую библиотеку и спасает Репозиторий объект:

this.setRepo = function(userName, repoName) {    repo = this.gh.getRepo(userName, repoName);}

setbranch () немного сложнее в логике:

this.setBranch = function(branchName) {    return repo.listBranches()        .then((branches) => {            let branchExists = branches.data                .find( branch => branch.name === branchName );            if (!branchExists) {                return repo.createBranch('master', branchName)                    .then(() => {                        currentBranch.name = branchName;                    });            } else {                currentBranch.name = branchName;            }        });}

Здесь вы получаете все ветви Репозиторий и попробуйте найти тот, кого вы хотите совершить. Если он не найден, новый филиал создан на основе Мастер Отказ

Когда вы используете pushfiles () Функция, она проходит все шаги, которые мы обсуждали выше:

this.pushFiles = function(message, files) {    return getCurrentCommitSHA()        .then(getCurrentTreeSHA)        .then( () => createFiles(files) )        .then(createTree)        .then( () => createCommit(message) )        .then(updateHead)        .catch((e) => {            console.error(e);        });}

Он использует цепочку обещаний, так как каждый шаг сделает реальный запрос на API GitHub.

Шаг 1 и 2 алгоритма не очень интересны. Они просто называют методами API и сохраняют SHAS нынешнего Совершать и Дерево :

function getCurrentCommitSHA() {    return repo.getRef('heads/' + currentBranch.name)        .then((ref) => {            currentBranch.commitSHA = ref.data.object.sha;        });}
function getCurrentTreeSHA() {    return repo.getCommit(currentBranch.commitSHA)        .then((commit) => {            currentBranch.treeSHA = commit.data.tree.sha;        });}

Теперь на шаге 3 вам нужно создать Blob Объекты для каждого файла:

function createFiles(files) {    let promises = [];    let length = filesInfo.length;
    for (let i = 0; i < length; i++) {        promises.push(createFile(files[i]));    }
    return Promise.all(promises);}
function createFile(file) {    return repo.createBlob(file.content)        .then((blob) => {            filesToCommit.push({                sha: blob.data.sha,                path: fileInfo.path,                mode: '100644',                type: 'blob'            });        });}

Два пункта, чтобы отметить здесь:

  1. Вам нужно ждать всех Blobs Создать – следовательно, Обещание. Все выражение
  2. Режим файла должен быть установлен на 100644 Для обозначения простого файла. GitHub позволяет Другие виды , но вам не нужны их здесь.

Шаг 4 и 5 о создании нового Дерево С файлами ( Blobs ) и A Совершать С этим Дерево :

function createTree() {    return repo.createTree(filesToCommit, currentBranch.treeSHA)        .then((tree) => {            newCommit.treeSHA = tree.data.sha;        });}
function createCommit(message) {    return repo.commit(currentBranch.commitSHA, newCommit.treeSHA, message)        .then((commit) => {            newCommit.sha = commit.data.sha;        });}

И единственное, что осталось шаг 6 – Обновите ветку, чтобы указать на Новый Совершать :

function updateHead() {    return repo.updateHead(        'heads/' + currentBranch.name,        newCommit.sha    );}

Вот и все! Теперь вы можете использовать эту красоту, чтобы нажать на ваши файлы:

let api = new GithubAPI({token: 'API_TOKEN'});api.setRepo('GITHUB_USER', 'REPOSITORY');api.setBranch('AWESOME_BRANCH')    .then( () => api.pushFiles(        'Making a commit with my adorable files',        [            {content: 'You are a Wizard, Harry', path: 'harry.txt'},            {content: 'May the Force be with you', path: 'jedi.txt'}        ])    )    .then(function() {        console.log('Files committed!');    });

Вы можете найти готовую к полученной реализации в этом Гист Отказ

Как насчет двоичных файлов?

К сожалению, в момент написания этой статьи (январь 2017 года) Библиотека, используемая здесь, не позволяет отправлять двоичные данные в Github.

Я создал Выпуск с ними, чтобы попытаться решить проблему. Но пока он не успокоится, нам придется найти обходной путь для этого.

Затруднение лежит в createblob () Функция, которая должна отправлять контент в формате Base64 с правильной структурой запроса. Но вместо этого библиотека обрабатывает ее как простой строку.

Таким образом, временный обходной путь я придумал, включает в себя высказывание библиотеки и меняется эта линия к следующему:

if (typeof content === 'object') {    postBody = content;} else {    postBody = this._getContentObject(content);}

По сути, вы бы хотели, чтобы библиотека позволит вам указать правильный объект самостоятельно.

Используя эту настраиваемую версию библиотеки, теперь вы можете протолкнуть двоичные файлы с:

createBlob({content: base64Content, encoding: 'base64'})

Где Base64content генерируется так:

let fileReader = new FileReader();fileReader.onload = function(e) {    let content = e.target.result;    //remove the header and leave only the Base64 content itself    base64Content = content.replace(/^(.+,)/, '');}fileReader.readAsDataURL(file);

Я признаю, что это хаки, но это, вероятно, самый простой способ достичь необходимого поведения.

Теперь иди и совершите код

GitHub дает вам возможность плавно работать со своим сервисом и из почти любой окружающей среды. Я надеюсь, что эта статья помогла уточнить некоторые важные концепции в отношении использования API GitHUB в браузере с помощью JavaScript.

Удачи всем вам! И дайте мне знать, что вы думаете об этом в комментариях.

Оригинал: “https://www.freecodecamp.org/news/pushing-a-list-of-files-to-the-github-with-javascript-b724c8c09b66/”