laconic-registry-cli/demo/scripts/create-repo-record.ts

184 lines
4.2 KiB
TypeScript

import yargs from 'yargs';
import path from 'path';
import fs from 'fs';
import assert from 'assert';
import { hideBin } from 'yargs/helpers';
import { Octokit } from '@octokit/rest';
interface RepoRecord {
type: string
version: string
schema: string
name: string
url: string
clone_url: string
owner: {
name: string
type: 'Organization' | 'User'
url: string
}
is_private: boolean
is_archived: boolean
default_branch: string
latest_tag: {
tag_name: string
url: string
} | null
is_fork: boolean
fork_source: {
name: string
url: string
} | null
license: {
name: string
spdx_id: string
} | null
}
async function main () {
const argv = getArgs();
const repoRecord = await createRepoRecord(argv.repoUrl);
const jsonData = JSON.stringify(repoRecord, null, 2);
const recordsDir = path.resolve(argv.recordsDir);
const recordFile = `${recordsDir}/${repoRecord.name}.json`;
fs.writeFileSync(recordFile, jsonData, 'utf8');
console.log(`Repo record written to ${recordFile}`);
}
async function createRepoRecord (repoUrl: string): Promise<RepoRecord> {
const githubPAT = process.env.GITHUB_TOKEN;
assert(githubPAT, 'GITHUB_TOKEN not provided');
const octokit = new Octokit({
auth: githubPAT
});
const { owner, repo } = extractOwnerAndRepo(repoUrl);
// fetch repo details
const data = await getRepoDetails(octokit, owner, repo);
const repoRecord: RepoRecord = {
type: 'RepositoryRecord',
version: '0.1.0', // fetch from registry and increment if exists
schema: '',
name: data.name,
url: data.html_url,
clone_url: data.clone_url,
owner: {
name: data.owner.login,
type: data.owner.type,
url: data.owner.html_url
},
is_private: data.private,
is_archived: data.archived,
default_branch: data.default_branch,
latest_tag: null,
is_fork: data.fork,
fork_source: null,
license: null
};
// populate fork source
if (data.fork) {
repoRecord.fork_source = {
name: data.source.name,
url: data.source.html_url
};
}
// populate license
if (data.license) {
repoRecord.license = {
name: data.license.name,
spdx_id: data.license.spdx_id
};
}
// fetch and populate latest_tag
const latestTag = await getRepoLatestTag(octokit, owner, repo);
if (latestTag) {
repoRecord.latest_tag = {
tag_name: latestTag.tag_name,
url: latestTag.html_url
};
}
return repoRecord;
}
// async function getRepoDetails (octokit: Octokit, repoUrl: string): Promise<RestEndpointMethodTypes["repos"]["get"]["response"]> {
async function getRepoDetails (octokit: Octokit, owner: string, repo: string): Promise<any> {
try {
const response = await octokit.repos.get({
owner: owner,
repo: repo
});
return response.data;
} catch (error) {
console.error('Error fetching repository:', error);
}
}
async function getRepoLatestTag (octokit: Octokit, owner: string, repo: string): Promise<any> {
try {
const response = await octokit.repos.getLatestRelease({
owner: owner,
repo: repo
});
return response.data;
} catch (error: any) {
if ((error as Error).message.includes('Not Found')) {
return null;
}
console.error('Error fetching repository:', error);
}
}
function extractOwnerAndRepo (url: string): { owner: string; repo: string } {
// eslint-disable-next-line no-useless-escape
const match = url.match(/github\.com\/([^\/]+)\/([^\/]+)(\/|$)/);
if (!match) {
throw new Error(`Unable to extract repo owner and name from the given URL: ${url}`);
}
return { owner: match[1], repo: match[2] };
}
function getArgs (): any {
return yargs(hideBin(process.argv)).parserConfiguration({
'parse-numbers': false
}).usage('Usage: $0 [options]')
.option('config', {
alias: 'c',
describe: 'Config',
type: 'string'
})
.option('repoUrl', {
alias: 'r',
describe: 'Repository URL',
type: 'string',
demandOption: true
})
.option('recordsDir', {
alias: 'd',
describe: 'Directory to export the repo record to',
type: 'string',
demandOption: true
})
.help().argv;
}
main()
.catch(err => {
console.error(err);
});