Skip to content

Commit

Permalink
feat: open tabs and files
Browse files Browse the repository at this point in the history
  • Loading branch information
mdonnalley committed Aug 25, 2021
1 parent a092bb3 commit 653e5d2
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 47 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ One the main advantages of using `multi` is that you can define your own command
```yaml
open-circle: multi exec . open https://app.circleci.com/pipelines/github/{repo.fullName}
done-with-branch: |
local current_branch=$(git branch 2> /dev/null | sed -e "/^[^*]/d" -e "s/* \(.*\)/\1/")
local current_branch=$(git rev-parse --abbrev-ref HEAD)
multi exec . git checkout {repo.defaultBranch}
git pull
git remote prune origin
Expand Down Expand Up @@ -162,7 +162,7 @@ USAGE
$ multi alias resolve [ALIAS]

ARGUMENTS
ALIAS Name of alias to resolve..
ALIAS Name of alias to resolve.

DESCRIPTION
Return the value of an alias.
Expand Down
7 changes: 7 additions & 0 deletions src/autocomplete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ _multi_autocomplete()
COMPREPLY=($( compgen -W "$(_get_repo_autocomplete)" -- $cur ))
;;
esac
case \${aliases} in
*"$prev"*)
COMPREPLY=($( compgen -W "$(_get_repo_autocomplete)" -- $cur ))
;;
esac
;;
*)
COMPREPLY=()
Expand Down
61 changes: 57 additions & 4 deletions src/commands/open.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,50 @@
import * as path from 'path';
import { Command } from '@oclif/core';
import { Command, Flags } from '@oclif/core';
import * as open from 'open';
import { exec } from 'shelljs';
import { Repos } from '../repos';

enum GithubTab {
ISSUES = 'issues',
PULLS = 'pulls',
DISCUSSIONS = 'discussions',
ACTIONS = 'actions',
WIKI = 'wiki',
SECURITY = 'security',
PULSE = 'pulse',
SETTINGS = 'settings',
}

export default class Open extends Command {
public static description = 'Open a github repository.';
public static examples = [
{
description: 'Open the main page of a github repository',
command: '<%= config.bin %> <%= command.id %> my-repo',
},
{
description: 'Open the issues tab of a github repository',
command: '<%= config.bin %> <%= command.id %> my-repo --tab issues',
},
{
description: 'Open a specific file in a github repository',
command: '<%= config.bin %> <%= command.id %> my-repo --file path/to/my/code.ts',
},
];
public static disableJsonFlag = true;
public static flags = {};
public static flags = {
file: Flags.string({
description: 'File to open in github.',
char: 'f',
exclusive: ['tab'],
}),
tab: Flags.string({
description: 'Tab to open in github.',
char: 't',
options: Object.values(GithubTab),
exclusive: ['file'],
}),
};
public static args = [
{
name: 'repo',
Expand All @@ -18,9 +56,24 @@ export default class Open extends Command {
public static aliases = ['o'];

public async run(): Promise<void> {
const { args } = await this.parse(Open);
const { args, flags } = await this.parse(Open);
const repoName = (args.repo === '.' ? path.basename(process.cwd()) : args.repo) as string;
const repo = (await Repos.create()).getOne(repoName);
await open(repo.urls.html, { wait: false });
if (!flags.file && !flags.tab) {
await open(repo.urls.html, { wait: false });
return;
}

if (flags.file) {
const branch = exec('git rev-parse --abbrev-ref HEAD', { silent: true }).stdout ?? repo.defaultBranch;
const url = `${repo.urls.html}/blob/${branch.trim()}/${flags.file}`;
await open(url, { wait: false });
return;
}

if (flags.tab) {
await open(`${repo.urls.html}/${flags.tab}`, { wait: false });
return;
}
}
}
46 changes: 5 additions & 41 deletions src/repos.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint-disable camelcase */

import * as path from 'path';
import { mkdir, readFile } from 'fs/promises';
import { mkdir } from 'fs/promises';
import { Octokit } from '@octokit/core';
import { Duration } from '@salesforce/kit';
import { exec } from 'shelljs';
Expand All @@ -27,11 +27,6 @@ export type Repository = {
archived: boolean;
defaultBranch: string;
location?: string;
npm?: {
name: string;
version?: string;
tags?: Record<string, string>;
};
};

export type RepositoryResponse = {
Expand Down Expand Up @@ -90,19 +85,10 @@ export class Repos extends ConfigFile<RepoIndex> {
public async fetch(org: string, repo?: string | null): Promise<Repository[]> {
if (repo) {
const response = await this.octokit.request('GET /repos/{owner}/{repo}', { owner: org, repo });
let transformed = this.transform(response.data);
if (transformed.location) {
transformed = await this.addAdditionalInfo(transformed);
}
return [transformed];
return [this.transform(response.data)];
} else {
const response = await this.octokit.request('GET /orgs/{org}/repos', { org });
const transformed = response.data.map((r) => this.transform(r as RepositoryResponse));
const promises = transformed.map(async (t) => {
if (t.location) return this.addAdditionalInfo(t);
else return t;
});
return Promise.all(promises);
return response.data.map((r) => this.transform(r as RepositoryResponse));
}
}

Expand All @@ -113,7 +99,7 @@ export class Repos extends ConfigFile<RepoIndex> {
exec(`git -C ${orgDir} clone ${url}`, { silent: true });

try {
this.set(repo.fullName, await this.addAdditionalInfo(repo));
this.set(repo.fullName, repo);
} catch {
// do nothing
}
Expand Down Expand Up @@ -160,30 +146,8 @@ export class Repos extends ConfigFile<RepoIndex> {
ssh: repo.ssh_url,
},
defaultBranch: repo.default_branch,
location: path.join(this.directory.name, repo.owner.login, repo.name),
};
return transformed;
}

private async addAdditionalInfo(repo: Repository): Promise<Repository> {
const location = repo.location || path.join(this.directory.name, repo.org, repo.name);
repo.location = location;
const pkgJsonPath = path.join(location, 'package.json');
if (await this.exists(pkgJsonPath)) {
try {
const pkgJson = JSON.parse(await readFile(pkgJsonPath, 'utf-8')) as { name: string };
repo.npm = { name: pkgJson.name };

const npmInfoRaw = exec(`npm view ${pkgJson.name} --json`, { silent: true }).stdout;
const npmInfo = JSON.parse(npmInfoRaw) as {
'dist-tags': Record<string, string>;
versions: string[];
};
repo.npm.version = npmInfo['dist-tags']['latest'] ?? npmInfo.versions.reverse()[0];
repo.npm.tags = npmInfo['dist-tags'];
} catch {
// likely not an npm package, which is okay
}
}
return repo;
}
}

0 comments on commit 653e5d2

Please sign in to comment.