Skip to content

Commit

Permalink
refactor: easier API for prompts
Browse files Browse the repository at this point in the history
  • Loading branch information
felixfbecker committed Sep 10, 2018
1 parent 3065cc7 commit c18948d
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 45 deletions.
49 changes: 21 additions & 28 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ import 'source-map-support/register'

import chalk from 'chalk'
import exec = require('execa')
import { prompt } from 'inquirer'
import { exists, mkdir, readFile, writeFile } from 'mz/fs'
import * as path from 'path'
import { createBuildkiteClient, initBuildkite } from './buildkite'
import { CodeCovRepo, createCodeCovClient, getCodeCovBadge } from './codecov'
import { createGitHubClient } from './github'
import { JsonSchemaForNpmPackageJsonFiles } from './package-schema'
import * as prompt from './prompt'
import { createTravisClient, initTravis } from './travis'
import { JsonSchemaForTheTypeScriptCompilersConfigurationFile } from './tsconfig-schema'
import { JsonSchemaForTheTsLintConfigurationFiles } from './tslint-schema'
Expand Down Expand Up @@ -73,41 +73,35 @@ async function main(): Promise<void> {
if (packageName) {
console.log(`Package name is "${packageName}"`)
} else {
;({ packageName } = await prompt<{ packageName: string }>({
name: 'packageName',
packageName = await prompt.input({
message:
'What should the name of the package be? Examples: @sourcegraph/codeintellify, @sourcegraph/react-loading-spinner, cxp',
default: '@sourcegraph/' + path.basename(process.cwd()),
}))
})
}
if (description) {
console.log(`Description is "${description}"`)
} else {
;({ description } = await prompt<{ description: string }>({
name: 'description',
message: 'Description',
}))
description = await prompt.input('Description')
}

const { visibility } = await prompt<{ visibility: 'public' | 'private' }>({
type: 'list',
name: 'visibility',
enum Visibility {
Public = 'Public',
Private = 'Private',
}
const visibility = await prompt.choices({
message: '🔐 Should this package be public or private?',
choices: ['public', 'private'],
choices: [Visibility.Public, Visibility.Private],
})

let repoName = packageName.replace(/^@sourcegraph\//, '')
if (!(await exec('git', ['remote'])).stdout) {
;({ repoName } = await prompt<{ repoName: string }>({
name: 'repoName',
message: 'Repository name',
default: repoName,
}))
repoName = await prompt.input({ message: 'Repository name', default: repoName })
try {
await githubClient.post(`orgs/sourcegraph/repos`, {
body: {
name: repoName,
private: visibility === 'private',
private: visibility === Visibility.Private,
description,
has_wiki: false,
has_projects: false,
Expand Down Expand Up @@ -143,11 +137,14 @@ async function main(): Promise<void> {
},
})

const { licenseName } = await prompt<{ licenseName: string }>({
enum LicenseName {
Unlicensed = 'UNLICENSED',
Mit = 'MIT',
}
const licenseName = await prompt.choices({
message: 'License?',
choices: ['UNLICENSED', 'MIT'],
default: { private: 'UNLICENSED', public: 'MIT' }[visibility],
name: 'licenseName',
default: { [Visibility.Private]: LicenseName.Unlicensed, [Visibility.Public]: LicenseName.Mit }[visibility],
})
if (licenseName !== 'UNLICENSED') {
console.log('📄 Adding LICENSE')
Expand All @@ -158,11 +155,7 @@ async function main(): Promise<void> {
await writeFile('LICENSE', licenseText)
}

const { hasTests } = await prompt<{ hasTests: boolean }>({
type: 'confirm',
message: 'Does this package have tests?',
name: 'hasTests',
})
const hasTests = await prompt.confirm('Does this package have tests?')

if (await exists('tsconfig.json')) {
console.log('📄 tsconfig.json already exists, skipping creation')
Expand Down Expand Up @@ -313,7 +306,7 @@ async function main(): Promise<void> {
const codeCovImageToken = codeCovRepo.repo.image_token
let buildBadge: string
if (visibility === 'private') {
if (visibility === Visibility.Private) {
const { badgeUrl, webUrl } = await initBuildkite({
hasTests,
repoName,
Expand All @@ -334,7 +327,7 @@ async function main(): Promise<void> {
const readme = [
`# ${packageName}`,
'',
...(visibility === 'public'
...(visibility === Visibility.Public
? [
`[![npm](https://img.shields.io/npm/v/${packageName}.svg)](https://www.npmjs.com/package/${packageName})`,
`[![downloads](https://img.shields.io/npm/dt/${packageName}.svg)](https://www.npmjs.com/package/${packageName})`,
Expand Down
16 changes: 4 additions & 12 deletions src/github.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { prompt } from 'inquirer'
import _request = require('request-promise')
import * as prompt from './prompt'
const request = _request.defaults({ resolveWithFullResponse: true })

export type GitHubClient = typeof request
Expand All @@ -24,17 +24,9 @@ export async function createSourcegraphBotGitHubToken({
console.log(
'See credentials in https://team-sourcegraph.1password.com/vaults/dnrhbauihkhjs5ag6vszsme45a/allitems/7s46bqcnl5hxzbutupu44va7gu'
)
const { password, otp } = await prompt<{ password: string; otp: string }>([
{
name: 'password',
type: 'password',
message: '@sourcegraph-bot GitHub password',
},
{
name: 'otp',
message: '@sourcegraph-bot GitHub 2FA code',
},
])
const password = await prompt.password('@sourcegraph-bot GitHub password')
const otp = await prompt.input('@sourcegraph-bot GitHub 2FA code')

const response = await githubClient.post('authorizations', {
headers: {
Authorization: 'Basic ' + Buffer.from('sourcegraph-bot:' + password).toString('base64'),
Expand Down
8 changes: 3 additions & 5 deletions src/npm.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
import { prompt } from 'inquirer'
// @ts-ignore
import NpmRegistryClient = require('npm-registry-client')
import * as prompt from './prompt'

export async function createSourcegraphBotNpmToken(): Promise<string> {
const client = new NpmRegistryClient()
console.log(
'See credentials in https://team-sourcegraph.1password.com/vaults/dnrhbauihkhjs5ag6vszsme45a/allitems/oye4u4faaxmxxesugzqxojr4q4'
)
const { password, otp } = await prompt<{ password: string; otp: string }>([
{ name: 'password', type: 'password', message: '@sourcegraph-bot npm password' },
{ name: 'otp', message: '@sourcegraph-bot npm 2FA code' },
])
const password = await prompt.password('@sourcegraph-bot npm password')
const otp = await prompt.input('@sourcegraph-bot npm 2FA code')

const body = {
_id: `org.couchdb.user:sourcegraph-bot`,
Expand Down
43 changes: 43 additions & 0 deletions src/prompt.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import * as inquirer from 'inquirer'

interface BaseOptions<T> {
message: string
default?: T
}

interface InputOptions extends BaseOptions<string> {}

export async function input(question: string | InputOptions): Promise<string> {
if (typeof question === 'string') {
question = { message: question }
}
const { answer } = await inquirer.prompt<{ answer: string }>({ ...question, name: 'answer' })
return answer
}

export async function password(question: string | InputOptions): Promise<string> {
if (typeof question === 'string') {
question = { message: question }
}
const { answer } = await inquirer.prompt<{ answer: string }>({ ...question, name: 'answer', type: 'password' })
return answer
}

interface ChoicesOptions<T extends string> extends BaseOptions<T> {
choices: ReadonlyArray<T>
}

export async function choices<T extends string>(question: ChoicesOptions<T>): Promise<T> {
const { answer } = await inquirer.prompt<{ answer: T }>({ ...question, name: 'answer', type: 'list' })
return answer
}

interface ConfirmOptions extends BaseOptions<boolean> {}

export async function confirm(question: string | ConfirmOptions): Promise<boolean> {
if (typeof question === 'string') {
question = { message: question }
}
const { answer } = await inquirer.prompt<{ answer: boolean }>({ ...question, name: 'answer', type: 'confirm' })
return answer
}

0 comments on commit c18948d

Please sign in to comment.