Skip to content

Instantly share code, notes, and snippets.

@jazerix
Created March 9, 2023 10:34
Show Gist options
  • Save jazerix/e8133df0e95499303a5080272f65a6ed to your computer and use it in GitHub Desktop.
Save jazerix/e8133df0e95499303a5080272f65a6ed to your computer and use it in GitHub Desktop.
GitLab Group Downloader - Downloads all projects from a given group in GitLab. Takes two arguments: id of the group and then a folder name to save the projects to
var fs = require('fs');
var path = require('path');
const https = require('https');
const cliProgress = require('cli-progress');
const decompress = require("decompress");
async function download()
{
if (!fs.existsSync(path.join(__dirname, "downloads")))
fs.mkdirSync(path.join(__dirname, "downloads"));
let groupId = process.argv[2]
let name = process.argv[3]
if (groupId == null)
throw new Error("No group id passed");
if (name == null)
throw new Error("No download name specified")
if (fs.existsSync(path.join(__dirname, "downloads", name)))
throw new Error("A folder with this name already exists!")
fs.mkdirSync(path.join(__dirname, "downloads", name))
const accessToken = "--REPLACE_ACCESS_TOKEN--";
let projects = [];
let response = null;
let page = 1;
do
{
response = await (await fetch(`https://gitlab.com/api/v4/groups/${groupId}/projects?access_token=${accessToken}&page=${page}`)).json();
projects.push(...response.map(x => ({id: x.id, name: x.name})))
page++;
}
while(response?.length == 20)
const bar = new cliProgress.SingleBar({}, cliProgress.Presets.shades_classic);
bar.start(projects.length, 0);
let counter = 0;
for(let project of projects)
{
const fileStream = fs.createWriteStream(path.join(__dirname, "temp.zip"));
await new Promise((resolve, reject) => {
https.get(`https://gitlab.com/api/v4/projects/${project.id}/repository/archive.zip?access_token=${accessToken}`, function(response) {
response.pipe(fileStream);
fileStream.on("finish", resolve);
}).on('error', reject);
});
await decompress("temp.zip", "temp")
let folder = fs.readdirSync(path.join(__dirname, "temp"))[0];
fs.renameSync(path.join(__dirname, "temp", folder), path.join(__dirname, "downloads", name, project.name))
fs.rmdirSync("temp");
fs.rmSync("temp.zip");
counter++;
bar.update(counter);
await new Promise(r => setTimeout(r, 10000));
}
bar.stop();
console.log("Download finished!");
}
download();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment