Initial commit

fetch-following
Jason Raimondi 4 years ago
commit 364e981c74
No known key found for this signature in database
GPG Key ID: 1744B4C3466E56E5

@ -0,0 +1,2 @@
.env
*.md

2
.gitignore vendored

@ -0,0 +1,2 @@
.idea/
.env

@ -0,0 +1,9 @@
FROM hayd/alpine-deno
WORKDIR /app
COPY . /app
RUN deno bundle main.ts bundle.js
ENTRYPOINT ["deno", "run", "--allow-net", "--allow-read", "/app/bundle.js"]

@ -0,0 +1,6 @@
```
docker run --rm jasonraimondi/gitea-sync \
--GITEA_API_URL="http://theserver.localdomain:3000/api/v1/"
--GITEA_ACCESS_TOKEN=""
--GITHUB_ACCESS_TOKEN=""
```

@ -0,0 +1,37 @@
import { env } from "./constants.ts";
const client = (
url: string,
{ body, ...customConfig }: RequestInit = {},
): Promise<Response> => {
const headers: HeadersInit = {
"content-type": "application/json",
Authorization: `token ${env.GITEA_ACCESS_TOKEN}`,
};
const config: RequestInit = {
method: body ? "POST" : "GET",
...customConfig,
headers: {
...headers,
...customConfig.headers,
},
};
if (body) {
config.body = body;
}
return fetch(url, config);
};
export const githubClient = (
query: string,
variables: { [key: string]: any },
) =>
client(env.GITHUB_GRAPHQL_URL, {
headers: {
Authorization: `bearer ${env.GITHUB_ACCESS_TOKEN}`,
},
body: JSON.stringify({ query, variables }),
});
export const giteaClient = (url: string, request?: RequestInit) =>
client(`${env.GITEA_API_URL}${url}`, request);

@ -0,0 +1,19 @@
import { red } from "https://deno.land/std/fmt/colors.ts";
import { exists } from "https://deno.land/std/fs/exists.ts";
import { readFileStr } from "https://deno.land/std/fs/read_file_str.ts";
if (Deno.args.length === 0) {
console.error(red("pass me some args dawg"));
}
const [firstArg, ...rest] = Deno.args;
if (typeof firstArg === "string" && await exists(firstArg)) {
const fileContent = await readFileStr(firstArg);
const fileArray = fileContent.trim().split("\n");
for await (const result of convertArray(fileArray)) {
console.log(result);
}
} else {
console.log("nothing");
}

@ -0,0 +1,9 @@
import { parse } from "https://deno.land/std/flags/mod.ts";
export const env = {
GITHUB_GRAPHQL_URL: "https://api.github.com/graphql",
GITEA_API_URL: "http://localhost:3000/api/v1",
GITEA_ACCESS_TOKEN: "",
GITHUB_ACCESS_TOKEN: "",
...parse(Deno.args),
};

@ -0,0 +1,77 @@
import { giteaClient } from "./client.ts";
import { blue, red } from "https://deno.land/std/fmt/colors.ts";
type Fields = {
repo_name: string;
clone_addr: string;
auth_password?: string;
auth_username?: string;
description?: string;
};
type CreateMigrationRequest = {
auth_password: string;
auth_username: string;
clone_addr: string;
description: string;
issues: boolean;
labels: boolean;
milestones: boolean;
mirror: boolean;
private: boolean;
pull_requests: boolean;
releases: boolean;
repo_name: string;
uid: number;
wiki: boolean;
};
export const mergeBody = (
createMigrationRequest: Partial<CreateMigrationRequest>,
) => ({
issues: true,
labels: true,
milestones: true,
mirror: true,
private: false,
pull_requests: true,
releases: true,
wiki: true,
uid: 2,
...createMigrationRequest,
});
export const createMigrationFromGithub = async (
user: string,
repo: string,
): Promise<Response | undefined> => {
if (await alreadyExists(user, repo)) {
console.warn(red(`repo exists (${user}/${repo})`));
return;
}
return createMigration(
{
repo_name: `${user}__${repo}`,
clone_addr: `https://github.com/${user}/${repo}`,
},
)
.then((res) => {
console.log(blue(`repo created (${user}/${repo})`));
return res;
})
.catch((e) => {
return undefined;
});
};
const createMigration = (fields: Fields) => {
const body = JSON.stringify(mergeBody(fields));
return giteaClient("repos/migrate", { body });
};
const alreadyExists = async (user: string, repo: string) => {
const response = await giteaClient(`repos/mirrors/${user}__${repo}`).catch(
() => ({ status: 500 }),
);
return response.status === 200;
};

@ -0,0 +1,66 @@
import { createMigrationFromGithub } from "./gitea_api.ts";
import { githubClient } from "./client.ts";
import { env } from "./constants.ts";
const isURL = (s: string) => {
try {
new URL(s);
return true;
} catch (_) {
return false;
}
};
export async function* convertArray(fileArray: string[]) {
for (let repo of fileArray) {
if (isURL(repo)) {
repo = repo.replace("https://github.com/", "");
}
const [username, repository] = repo.split("/");
const response = await createMigrationFromGithub(username, repository);
yield [repo, response?.status === 201 ? "success" : "fail"];
}
}
const query = `
query ($userLogin: String!, $cursor: String) {
user(login: $userLogin) {
starredRepositories(first:100,after:$cursor) {
totalCount
pageInfo {
startCursor
endCursor
hasNextPage
hasPreviousPage
}
edges {
node {
nameWithOwner
}
}
}
}
}`;
for (const username of env._) {
let cursor: string | undefined = undefined;
let hasNextPage = false;
do {
const response = await githubClient(query, { userLogin: username, cursor });
const jsonResponse = await response.json();
const { totalCount, pageInfo, edges }: any = jsonResponse?.data?.user?.starredRepositories;
console.log({ totalCount });
const repositories = edges.map(({ node }: any) => node.nameWithOwner);
cursor = pageInfo.endCursor;
for await (const result of convertArray(repositories)) {
console.log(result);
}
hasNextPage = pageInfo.hasNextPage;
console.log({ hasNextPage });
} while (hasNextPage);
}

@ -0,0 +1,25 @@
const { test } = Deno;
import { assertEquals } from "https://deno.land/std/testing/asserts.ts";
import { mergeBody } from "./gitea_api.ts";
test("mergeBody", function (): void {
const result = mergeBody({
clone_addr: "http://github.com/jasonraimondi/jasonraimondi.com",
repo_name: "jasonraimondi__jasonraimondi.com",
});
assertEquals(result, {
issues: true,
labels: true,
milestones: true,
mirror: true,
private: false,
pull_requests: true,
releases: true,
wiki: true,
uid: 2,
clone_addr: "http://github.com/jasonraimondi/jasonraimondi.com",
repo_name: "jasonraimondi__jasonraimondi.com",
});
});
Loading…
Cancel
Save