1import chalk from 'chalk'; 2import spawn from 'cross-spawn'; 3import githubUsername from 'github-username'; 4import ora from 'ora'; 5 6export type StepOptions = ora.Options; 7 8export async function newStep<Result>( 9 title: string, 10 action: (step: ora.Ora) => Promise<Result> | Result, 11 options: StepOptions = {} 12): Promise<Result> { 13 const disabled = process.env.CI || process.env.EXPO_DEBUG; 14 const step = ora({ 15 text: chalk.bold(title), 16 isEnabled: !disabled, 17 stream: disabled ? process.stdout : process.stderr, 18 ...options, 19 }); 20 21 step.start(); 22 23 try { 24 return await action(step); 25 } catch (error) { 26 step.fail(); 27 console.error(error); 28 process.exit(1); 29 } 30} 31 32/** 33 * Finds user's name by reading it from the git config. 34 */ 35export async function findMyName(): Promise<string> { 36 try { 37 return spawn.sync('git', ['config', '--get', 'user.name']).stdout.toString().trim(); 38 } catch { 39 return ''; 40 } 41} 42 43/** 44 * Finds user's email by reading it from the git config. 45 */ 46export async function findGitHubEmail(): Promise<string> { 47 try { 48 return spawn.sync('git', ['config', '--get', 'user.email']).stdout.toString().trim(); 49 } catch { 50 return ''; 51 } 52} 53 54/** 55 * Get the GitHub username from an email address if the email can be found in any commits on GitHub. 56 */ 57export async function findGitHubProfileUrl(email: string): Promise<string> { 58 try { 59 const username = (await githubUsername(email)) ?? ''; 60 return `https://github.com/${username}`; 61 } catch { 62 return ''; 63 } 64} 65 66/** 67 * Guesses the repository URL based on the author profile URL and the package slug. 68 */ 69export async function guessRepoUrl(authorUrl: string, slug: string) { 70 if (/^https?:\/\/github.com\/[^/]+/.test(authorUrl)) { 71 const normalizedSlug = slug.replace(/^@/, '').replace(/\//g, '-'); 72 return `${authorUrl}/${normalizedSlug}`; 73 } 74 return ''; 75} 76