Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ npx giget@latest bitbucket:unjs/template
# Clone from sourcehut
npx giget@latest sourcehut:pi0/unjs-template

# Clone from codeberg
npx giget@latest codeberg:unjs/template

# Clone from https URL (tarball)
npx giget@latest https://api.github.com/repos/unjs/template/tarball/main

Expand Down Expand Up @@ -142,7 +145,7 @@ const { source, dir } = await downloadTemplate("github:unjs/template");
- `source`: (string) Input source in format of `[provider]:repo[/subpath][#ref]`.
- `options`: (object) Options are usually inferred from the input string. You can customize them.
- `dir`: (string) Destination directory to clone to. If not provided, `user-name` will be used relative to the current directory.
- `provider`: (string) Either `github`, `gitlab`, `bitbucket` or `sourcehut`. The default is `github`.
- `provider`: (string) Either `github`, `gitlab`, `bitbucket`, `sourcehut` or `codeberg`. The default is `github`.
- `force`: (boolean) Extract to the existing dir even if already exists.
- `forceClean`: (boolean) ⚠️ Clean up any existing directory or file before cloning.
- `offline`: (boolean) Do not attempt to download and use the cached version.
Expand Down
17 changes: 17 additions & 0 deletions src/providers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,22 @@ export const sourcehut: TemplateProvider = (input, options) => {
};
};

export const codeberg: TemplateProvider = (input, options) => {
const parsed = parseGitURI(input);
return {
name: parsed.repo.replace("/", "-"),
version: parsed.ref,
subdir: parsed.subdir,
headers: {
// TODO: Check https://forgejo.org/docs/latest/user/api-usage/#authentication, https://codeberg.org/api/swagger
authorization: options.auth ? `Bearer ${options.auth}` : undefined,
},
// TODO: branch or commit or tag vs. omit (like in Bitbucket)
url: `https://codeberg.org/${parsed.repo}/src/branch/${parsed.ref}${parsed.subdir}`,
tar: `https://codeberg.org/${parsed.repo}/archive/${parsed.ref}.tar.gz`,
};
};

export const providers: Record<string, TemplateProvider> = {
http,
https: http,
Expand All @@ -136,4 +152,5 @@ export const providers: Record<string, TemplateProvider> = {
gitlab,
bitbucket,
sourcehut,
codeberg,
};
2 changes: 1 addition & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export interface GitInfo {
provider: "github" | "gitlab" | "bitbucket" | "sourcehut";
provider: "github" | "gitlab" | "bitbucket" | "sourcehut" | "codeberg";
repo: string;
subdir: string;
ref: string;
Expand Down
29 changes: 20 additions & 9 deletions test/getgit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,32 @@ import { resolve } from "pathe";
import { downloadTemplate } from "../src";

describe("downloadTemplate", () => {
const tests = [
{ input: "gh:unjs/template" },
{ input: "codeberg:unjs/template" },
];

beforeAll(async () => {
await rm(resolve(__dirname, ".tmp"), { recursive: true, force: true });
});

it("clone unjs/template", async () => {
const destinationDirectory = resolve(__dirname, ".tmp/cloned");
const { dir } = await downloadTemplate("gh:unjs/template", {
dir: destinationDirectory,
preferOffline: true,
for (const test of tests) {
it(`clone ${test.input}`, async () => {
const destinationDirectory = resolve(
__dirname,
".tmp/cloned",
test.input.split(":")[0],
);
const { dir } = await downloadTemplate(test.input, {
dir: destinationDirectory,
preferOffline: true,
});
expect(existsSync(resolve(dir, "package.json")));
});
expect(await existsSync(resolve(dir, "package.json")));
});
}

it("do not clone to exisiting dir", async () => {
const destinationDirectory = resolve(__dirname, ".tmp/exisiting");
it("do not clone to existing dir", async () => {
const destinationDirectory = resolve(__dirname, ".tmp/existing");
await mkdir(destinationDirectory).catch(() => {});
await writeFile(resolve(destinationDirectory, "test.txt"), "test");
await expect(
Expand Down