Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: replace simple-git with octokit to load fiddle #50

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@
},
"dependencies": {
"@electron/get": "^2.0.0",
"@octokit/rest": "^19.0.4",
"debug": "^4.3.3",
"env-paths": "^2.2.1",
"extract-zip": "^2.0.1",
"fs-extra": "^10.0.0",
"getos": "^3.2.1",
"node-fetch": "^2.6.1",
"semver": "^7.3.5",
"simple-git": "^2.48.0"
"semver": "^7.3.5"
},
"devDependencies": {
"@continuous-auth/semantic-release-npm": "^3.0.0",
Expand Down
86 changes: 70 additions & 16 deletions src/fiddle.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import * as fs from 'fs-extra';
import * as path from 'path';
import debug from 'debug';
import simpleGit from 'simple-git';
import fetch from 'node-fetch';
import { createHash } from 'crypto';

import { DefaultPaths } from './paths';
import { getOctokit } from './utils/octokit';

function hashString(str: string): string {
const md5sum = createHash('md5');
Expand Down Expand Up @@ -32,10 +33,43 @@ export class Fiddle {
export type FiddleSource = Fiddle | string | Iterable<[string, string]>;

export class FiddleFactory {
private readonly VALID_FILES: Array<string> = [
'main.js',
'renderer.js',
'index.html',
'preload.js',
'styles.css',
];
// Thanks to https://serverfault.com/a/917253
private readonly GITHUB_URL_REGEX = new RegExp(
'^(https|git)(://|@)([^/:]+)[/:]([^/:]+)/(.+).git$',
);

constructor(private readonly fiddles: string = DefaultPaths.fiddles) {}

public async fromGist(gistId: string): Promise<Fiddle> {
return this.fromRepo(`https://gist.github.com/${gistId}.git`);
public async fromGist(gistId: string) {
// stores in format [filename, content]
const gistContents: [string, string][] = [];
const octokit = getOctokit(process.env.FIDDLE_CORE_GITHUB_TOKEN);
const gist = await octokit.gists.get({ gist_id: gistId });

if (gist.data.files === undefined) {
return;
}

for (const [, data] of Object.entries(gist.data.files)) {
const fileName = data?.filename;
const content = data?.content;

if (fileName === undefined || content === undefined) {
continue;
}
if (this.VALID_FILES.includes(fileName)) {
gistContents.push([fileName, content]);
}
}

return this.fromEntries(gistContents);
}

public async fromFolder(source: string): Promise<Fiddle> {
Expand All @@ -55,23 +89,43 @@ export class FiddleFactory {
return new Fiddle(path.join(folder, 'main.js'), source);
}

public async fromRepo(url: string, checkout = 'master'): Promise<Fiddle> {
public async fromRepo(url: string) {
const d = debug('fiddle-core:FiddleFactory:fromRepo');
const folder = path.join(this.fiddles, hashString(url));
d({ url, checkout, folder });

// get the repo
if (!fs.existsSync(folder)) {
d(`cloning "${url}" into "${folder}"`);
const git = simpleGit();
await git.clone(url, folder, { '--depth': 1 });
const match = this.GITHUB_URL_REGEX.exec(url);
if (match === null) {
throw new Error(`Invalid github URL`);
}
// This has to be done because octokit expects an owner and repo
// params to be passed instead of just HTTPs/SSH git link.
const owner = match[4];
const repo = match[5];
const repoContents: [string, string][] = [];

d({ url, owner, repo });
const octokit = getOctokit(process.env.FIDDLE_CORE_GITHUB_TOKEN);
const folder = await octokit.repos.getContent({
owner,
repo,
path: '.', // Look for in the base directory only
});

if (!Array.isArray(folder.data)) {
return;
}

const git = simpleGit(folder);
await git.checkout(checkout);
await git.pull('origin', checkout);
for (const file of folder.data) {
if (!this.VALID_FILES.includes(file.name)) {
continue;
}

if (file.download_url) {
const resp = await fetch(file.download_url);
const content = await resp.text();
repoContents.push([file.name, content]);
}
}

return new Fiddle(path.join(folder, 'main.js'), url);
return this.fromEntries(repoContents);
}

public async fromEntries(src: Iterable<[string, string]>): Promise<Fiddle> {
Expand Down
3 changes: 3 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
compareVersions,
} from './versions';
import { runFromCommandLine } from './command-line';
import { setGithubToken, removeGithubToken } from './utils/env';

export {
BaseVersions,
Expand All @@ -41,6 +42,8 @@ export {
TestResult,
Versions,
compareVersions,
setGithubToken,
removeGithubToken,
runFromCommandLine,
};

Expand Down
7 changes: 7 additions & 0 deletions src/utils/env.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export function setGithubToken(githubToken: string) {
process.env.FIDDLE_CORE_GITHUB_TOKEN = githubToken;
}

export function removeGithubToken() {
delete process.env.FIDDLE_CORE_GITHUB_TOKEN;
}
20 changes: 20 additions & 0 deletions src/utils/octokit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Octokit } from '@octokit/rest';

let _octo: Octokit;
/**
* Returns a loaded Octokit. If state is passed and authentication
* is available, we'll token-authenticate.
* @returns {Octokit}
*/
export function getOctokit(token?: string): Octokit {
// It's possible to load Gists without being authenticated,
// but we get better rate limits when authenticated.
_octo =
_octo || token
? new Octokit({
auth: token,
})
: new Octokit();

return _octo;
}
10 changes: 9 additions & 1 deletion tests/fiddle.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,15 @@ describe('FiddleFactory', () => {
expect(fiddle).toBe(fiddleIn);
});

it.todo('reads fiddles from git repositories');
it('reads fiddles from git repositories', async () => {
const repo = 'https://github.com/electron/electron-quick-start.git';
const fiddle = await fiddleFactory.create(repo);
expect(fiddle).toBeTruthy();
expect(fs.existsSync(fiddle!.mainPath)).toBe(true);
expect(path.basename(fiddle!.mainPath)).toBe('main.js');
expect(path.dirname(path.dirname(fiddle!.mainPath))).toBe(fiddleDir);
});

it.todo('refreshes the cache if given a previously-cached git repository');

it('returns undefined for unknown input', async () => {
Expand Down
23 changes: 1 addition & 22 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -789,18 +789,6 @@
"@types/yargs" "^16.0.0"
chalk "^4.0.0"

"@kwsites/file-exists@^1.1.1":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@kwsites/file-exists/-/file-exists-1.1.1.tgz#ad1efcac13e1987d8dbaf235ef3be5b0d96faa99"
integrity sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==
dependencies:
debug "^4.1.1"

"@kwsites/promise-deferred@^1.1.1":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz#8ace5259254426ccef57f3175bc64ed7095ed919"
integrity sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==

"@microsoft/[email protected]":
version "7.15.3"
resolved "https://registry.yarnpkg.com/@microsoft/api-extractor-model/-/api-extractor-model-7.15.3.tgz#cf76deeeb2733d974da678f530c2dbaceb18a065"
Expand Down Expand Up @@ -1119,7 +1107,7 @@
node-fetch "^2.6.7"
universal-user-agent "^6.0.0"

"@octokit/rest@^19.0.0":
"@octokit/rest@^19.0.0", "@octokit/rest@^19.0.4":
version "19.0.4"
resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-19.0.4.tgz#fd8bed1cefffa486e9ae46a9dc608ce81bcfcbdd"
integrity sha512-LwG668+6lE8zlSYOfwPj4FxWdv/qFXYBpv79TWIQEpBLKA9D/IMcWsF/U9RGpA3YqMVDiTxpgVpEW3zTFfPFTA==
Expand Down Expand Up @@ -6101,15 +6089,6 @@ signale@^1.2.1:
figures "^2.0.0"
pkg-conf "^2.1.0"

simple-git@^2.48.0:
version "2.48.0"
resolved "https://registry.yarnpkg.com/simple-git/-/simple-git-2.48.0.tgz#87c262dba8f84d7b96bb3a713e9e34701c1f6e3b"
integrity sha512-z4qtrRuaAFJS4PUd0g+xy7aN4y+RvEt/QTJpR184lhJguBA1S/LsVlvE/CM95RsYMOFJG3NGGDjqFCzKU19S/A==
dependencies:
"@kwsites/file-exists" "^1.1.1"
"@kwsites/promise-deferred" "^1.1.1"
debug "^4.3.2"

sisteransi@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed"
Expand Down