Skip to content

Commit d11ccdf

Browse files
authored
Merge pull request #20 from winstonwumbo/main
[hax party] gh support for onboarding (plus fixing some old bugs)
2 parents 8014841 + b166b7a commit d11ccdf

File tree

3 files changed

+108
-45
lines changed

3 files changed

+108
-45
lines changed

CONTRIBUTING.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Contributing
22

33
- [Communication](#communication)
4+
- [Setting up a Development Environment](#setting-up-your-development-environment)
45
- [GitHub workflow](#github-workflow)
56
- [Open a Pull Request](#opening-a-pull-request)
67
- [Code Review](#code-review)
@@ -17,11 +18,21 @@ Please do not ever hesitate to ask a question or send a pull request.
1718

1819
Beginner focused information can be found below in [Open a Pull Request](#opening-a-pull-request) and [Code Review](#code-review).
1920

20-
### Communication
21+
## Communication
2122

2223
Reporting issues? Our unified issue queue is a good place for this: https://github.com/haxtheweb/issues/issues
2324
Need to discuss something via chat? Our [Discord can be joined here](https://bit.ly/hax-discord).
2425

26+
## Setting up a Development Environment
27+
HAX has a built-in module for onboarding `hax party`! It'll get you up and running with tooling, repositories, and the community.
28+
29+
### System dependencies
30+
* [git](https://git-scm.com/)
31+
* [gh](https://cli.github.com/) (optional)
32+
* [yarn](https://yarnpkg.com/)
33+
34+
`hax party` works great with just `git`, but contributors can get some extra convenience with GitHub's own `gh` utility. (You can fork repos directly from the CLI, rather than visiting the browser every time!)
35+
2536
## GitHub workflow
2637

2738
We work primarily using pull requests and forks. In order to work most effectively, we ask that you FORK any project you are wanting to contribute to in our ecosystem. After taking a fork, submit a pull request while pointing to the associated issue tied to this pull request.

src/create.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,7 @@ async function main() {
384384
auditCommandDetected(commandRun, customPath)
385385
}
386386
else if (commandRun.command === 'party') {
387+
commandRun.options.author = author;
387388
await partyCommandDetected(commandRun);
388389
}
389390
// CLI works within context of the site if one is detected, otherwise we can do other things

src/lib/programs/party.js

Lines changed: 95 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,22 @@ import * as p from '@clack/prompts';
66
import color from 'picocolors';
77
import { merlinSays } from "../statements.js";
88

9+
const osPathCmd = process.platform === "win32" ? "where.exe" : "which";
10+
911
let sysGit = true;
10-
exec('which git', error => {
12+
exec(`${osPathCmd} git`, error => {
1113
if (error) {
1214
sysGit = false;
1315
}
1416
});
1517

18+
let sysGh = true;
19+
exec(`${osPathCmd} gh`, error => {
20+
if (error) {
21+
sysGh = false;
22+
}
23+
});
24+
1625
let sysSSH = true;
1726

1827
export function partyActions(){
@@ -56,7 +65,8 @@ export async function partyCommandDetected(commandRun) {
5665
command: null,
5766
arguments: {},
5867
options: {
59-
// npmClient: `${operation.npmClient}`
68+
npmClient: `${operation.npmClient}`,
69+
author: `${operation.author}`
6070
}
6171
}
6272
operation = await p.group(
@@ -207,27 +217,41 @@ export async function partyCommandDetected(commandRun) {
207217

208218
async function cloneHAXRepositories(commandRun) {
209219
let s = p.spinner();
210-
211220
// check for system dependencies: ssh, yarn, etc.
212221
if(!sysGit) {
213222
console.error(`${color.red(`Git is not installed. The Git CLI is required to access GitHub with ${color.bold('hax party')}.`)}
214223
Please follow the instructions at:
215224
${color.underline(color.cyan(`https://git-scm.com/book/en/v2/Getting-Started-Installing-Git`))}`);
216225
process.exit(1);
217226
}
218-
await interactiveExec('ssh -T git@github.com', (error, stdout, stderr) => {
219-
const output = stdout + stderr;
220-
// The GitHub SSH test always returns as stderr
221-
if (!output.includes('successfully authenticated')) {
222-
sysSSH = false;
227+
228+
if(!sysGh){
229+
try {
230+
const { stdout, stderr } = await exec('ssh -T git@github.com');
231+
} catch(error) {
232+
// The GitHub SSH test always returns as stderr
233+
if (!error.stderr.includes('successfully authenticated')) {
234+
sysSSH = false;
235+
}
223236
}
224-
});
225237

226-
if(!sysSSH) {
227-
console.error(`${color.red(`SSH keys are not set up correctly. SSH is required to access GitHub with ${color.bold('hax party')}.`)}
228-
Please follow the instructions at:
229-
${color.underline(color.cyan(`https://docs.github.com/en/authentication/connecting-to-github-with-ssh`))}`);
230-
process.exit(1);
238+
if(!sysSSH) {
239+
console.error(`${color.red(`SSH keys are not set up correctly. SSH is required to access GitHub with ${color.bold('hax party')}.`)}
240+
Please follow the instructions at:
241+
${color.underline(color.cyan(`https://docs.github.com/en/authentication/connecting-to-github-with-ssh`))}`);
242+
process.exit(1);
243+
}
244+
} else {
245+
// gh cli can make new ssh keys and push them to GitHub
246+
try {
247+
await exec('gh auth status')
248+
} catch {
249+
console.log(`${color.red(`You have GitHub CLI installed, but it is not properly authenticated.`)}
250+
To access GitHub with ${color.bold('hax party')}, please follow this guided login:
251+
Select the ${color.cyan(`Generate a new SSH key`)} and ${color.cyan(`Login with a web browser`)} options`);
252+
253+
await interactiveExec('gh', ['auth', 'login', '-p', 'ssh', '--clipboard'])
254+
}
231255
}
232256

233257
try {
@@ -237,22 +261,13 @@ async function cloneHAXRepositories(commandRun) {
237261
}
238262

239263
for (const item of commandRun.options.repos) {
240-
// while loop keeps HAX active until the user is ready
241-
let isForked = false;
242-
let firstRun = true;
243-
while(!isForked) {
264+
// If GitHub CLI is installed
265+
if(sysGh){
244266
try {
245267
// ssh link is used since https prompts for password
246-
if(firstRun){
247-
s.start(`Cloning ${color.bold(item)} to ${color.bold(process.cwd())}`);
248-
} else {
249-
s.start(`Trying again... Cloning ${item} to ${color.bold(process.cwd())}`);
250-
}
251-
268+
s.start(`Cloning ${color.bold(item)} to ${color.bold(process.cwd())}`);
252269
await exec(`git clone git@github.com:${commandRun.options.author}/${item}.git`);
253270
s.stop(`${color.green("Successfully")} cloned ${color.bold(item)} to ${color.bold(process.cwd())}`);
254-
255-
isForked = true;
256271
} catch (e) {
257272
// skip the loop if the repo already exists
258273
if(e.stderr.includes("already exists and is not an empty directory")){
@@ -262,27 +277,63 @@ async function cloneHAXRepositories(commandRun) {
262277

263278
s.stop(`${color.red("Failed")} to clone ${color.bold(item)} to ${color.bold(process.cwd())}`);
264279

265-
p.note(`${color.red(`Error: HAX cannot find a personal ${color.bold("fork")} of the ${color.bold(item)} repository on your GitHub account`)}
266-
Use the following link to fork ${color.bold(item)}: ${color.underline(color.cyan(`https://github.com/haxtheweb/${item}/fork`))}`);
280+
p.note(`${color.red(`Error: HAX could not find your personal ${color.bold("fork")} of the ${color.bold(item)} repository on GitHub`)}`)
281+
282+
s.start(`Using ${color.bold(`gh repo`)} utility to fork and clone ${color.bold(item)}`);
283+
await exec(`gh repo fork haxtheweb/${item} --clone`)
284+
s.stop(`${color.green("Successfully")} cloned ${color.bold(item)} to ${color.bold(process.cwd())}`);
285+
}
286+
}
287+
// Standard git, not GitHub CLI
288+
else {
289+
// while loop keeps HAX active until the user is ready
290+
let isForked = false;
291+
let firstRun = true;
292+
293+
while(!isForked) {
294+
try {
295+
// ssh link is used since https prompts for password
296+
if(firstRun){
297+
s.start(`Cloning ${color.bold(item)} to ${color.bold(process.cwd())}`);
298+
} else {
299+
s.start(`Trying again... Cloning ${item} to ${color.bold(process.cwd())}`);
300+
}
267301

268-
// We don't want to spam the link every time
269-
if(firstRun){
270-
p.intro(`${merlinSays("The link will open in your browser in a few seconds")}`)
271-
setTimeout(async () => {
272-
await open(`https://github.com/haxtheweb/${item}/fork`)
273-
}, 3000);
274-
firstRun = false;
275-
}
302+
await exec(`git clone git@github.com:${commandRun.options.author}/${item}.git`);
303+
s.stop(`${color.green("Successfully")} cloned ${color.bold(item)} to ${color.bold(process.cwd())}`);
276304

277-
let response = await p.confirm({
278-
message: `Have you forked the repository? Would you like to try again?`,
279-
initialValue: true,
280-
});
305+
isForked = true;
306+
} catch (e) {
307+
// skip the loop if the repo already exists
308+
if(e.stderr.includes("already exists and is not an empty directory")){
309+
s.stop(`${color.yellow(`${color.bold(`${item}`)} already exists in ${color.bold(process.cwd())}`)}`);
310+
break;
311+
}
281312

282-
// Multiple ways to quit (select no, ctrl+c, etc)
283-
if(p.isCancel(response) || !response) {
284-
p.cancel('🧙 Merlin: Canceling CLI.. HAX ya later 🪄');
285-
process.exit(0);
313+
s.stop(`${color.red("Failed")} to clone ${color.bold(item)} to ${color.bold(process.cwd())}`);
314+
315+
p.note(`${color.red(`Error: HAX cannot find a personal ${color.bold("fork")} of the ${color.bold(item)} repository on your GitHub account`)}
316+
Use the following link to fork ${color.bold(item)}: ${color.underline(color.cyan(`https://github.com/haxtheweb/${item}/fork`))}`);
317+
318+
// We don't want to spam the link every time
319+
if(firstRun){
320+
p.intro(`${merlinSays("The link will open in your browser in a few seconds")}`)
321+
setTimeout(async () => {
322+
await open(`https://github.com/haxtheweb/${item}/fork`)
323+
}, 3000);
324+
firstRun = false;
325+
}
326+
327+
let response = await p.confirm({
328+
message: `Have you forked the repository? Would you like to try again?`,
329+
initialValue: true,
330+
});
331+
332+
// Multiple ways to quit (select no, ctrl+c, etc)
333+
if(p.isCancel(response) || !response) {
334+
p.cancel('🧙 Merlin: Canceling CLI.. HAX ya later 🪄');
335+
process.exit(0);
336+
}
286337
}
287338
}
288339
}

0 commit comments

Comments
 (0)