Skip to content

Commit

Permalink
More work on danger init
Browse files Browse the repository at this point in the history
  • Loading branch information
orta committed Dec 2, 2017
1 parent 8a6ef0a commit 0dc7ae1
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 55 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ docs/doc_generate/
docs/docs_generate/
docs/js_ref_dsl_docs.json

static/source/images/js/danger-logo-hero-cachable@2x.png

types/index.d.ts
.jest/
test-results.json
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
"dependencies": {
"babel-polyfill": "7.0.0-alpha.19",
"chalk": "^2.0.0",
"cli-interact": "^0.1.9",
"commander": "^2.9.0",
"debug": "^3.0.0",
"get-stdin": "^5.0.1",
Expand Down
1 change: 1 addition & 0 deletions source/ambient.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ declare module "*/package.json"
declare module "require-from-string"
declare module "node-eval"
declare module "node-cleanup"
declare module "cli-interact"

// declare module "require-from-string" {
// export interface RequireOptions {
Expand Down
143 changes: 88 additions & 55 deletions source/commands/danger-init.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import * as fs from "fs"

import * as program from "commander"
import * as chalk from "chalk"

import * as fs from "fs"
import * as cliInteract from "cli-interact"
import { setTimeout } from "timers"

program
.description("Helps you get set up through to your first Danger.")
Expand All @@ -10,8 +12,9 @@ program

interface InitUI {
header: (msg: String) => void
command: (command: string) => void
say: (msg: String) => void
pause: (secs: number) => void
pause: (secs: number) => Promise<{}>
waitForReturn: () => void
link: (name: string, href: string) => string
askWithAnswers: (message: string, answers: string[]) => string
Expand All @@ -27,24 +30,37 @@ interface State {
supportsHLinks: boolean
}

// const mainUI = {
// header: (msg: String) => {},
// say: (msg: String) => {},
// pause: (secs: number) => {},
// }
class UI {
say = (msg: String) => {
console.log(msg)
}
header = (msg: String) => this.say(chalk.bold("## " + msg))
command = (command: string) => this.say(chalk.gray.bold("> " + command))

link = (_name: string, href: string) => "-> " + href

pause = async (secs: number) => new Promise(done => setTimeout(done, secs / 1000))
waitForReturn = () => cliInteract.getChar("aaa")

askWithAnswers = (message: string, answers: string[]) => {
const a = cliInteract.getChoice(message, answers)
console.log(a)
return a
}
}

// re: link
// echo -e '\e]8;;http://example.com\aThis is a link\e]8;;\a'
//

const checkForTypeScript = () => fs.readFileSync("node_modules/typescript/package.json")
const checkForBabel = () =>
fs.readFileSync("node_modules/babel-core/package.json") || fs.readFileSync("node_modules/@babel/core/package.json")
// const _checkForBabel = () =>
// fs.readFileSync("node_modules/babel-core/package.json") || fs.readFileSync("node_modules/@babel/core/package.json")

const generateInitialState = (): State => {
const isMac = process.platform === "darwin"
const isWindows = process.platform === "win32"
const isIterm = process.env["ITERM_SESSION_ID"] !== undefined
const generateInitialState = (osProcess: NodeJS.Process): State => {
const isMac = osProcess.platform === "darwin"
const isWindows = osProcess.platform === "win32"
const isIterm = osProcess.env["ITERM_SESSION_ID"] !== undefined
const isVTE = false
return {
isMac,
Expand All @@ -57,36 +73,46 @@ const generateInitialState = (): State => {
}
}

const initialState = generateInitialState()
const go = async () => {
const initialState = generateInitialState(process)
const ui: InitUI = new UI()

await showTodoState(ui, initialState)
await setupDangerfile(ui, initialState)
await setupGitHubAccount(ui, initialState)
await setupGHAccessToken(ui, initialState)
await wrapItUp(ui, initialState)
await thanks(ui, initialState)
}

const showTodoState = (ui: InitUI, state: State) => {
const showTodoState = async (ui: InitUI, state: State) => {
ui.say("We need to do the following:\n")
ui.pause(0.6)
await ui.pause(0.6)
ui.say(" - [ ] Create a Dangerfile and add a few simple rules.")
ui.pause(0.6)
await ui.pause(0.6)
ui.say(` - [${state.hasSetUpAccount ? "x" : " "}] Create a GitHub account for Danger to use, for messaging.`)
ui.pause(0.6)
await ui.pause(0.6)
ui.say(" - [ ] Set up an access token for Danger.")
ui.pause(0.6)
await ui.pause(0.6)
ui.say(" - [ ] Set up Danger to run on your CI.\n\n")
}

const setupDangerfile = (ui: InitUI, state: State) => {
const setupDangerfile = async (ui: InitUI, state: State) => {
ui.header("Step 1: Creating a starter Dangerfile")
ui.say("I've set up an example Dangerfile for you in this folder.\n")
ui.pause(1)
await ui.pause(1)

const content = "default dangerfile"
// File.write("Dangerfile", content)

ui.header("Step 1: Creating a starter Dangerfile")
ui.say("I've set up an example Dangerfile for you in this folder.\n")
ui.pause(1)
await ui.pause(1)

ui.say(`cat ${process.cwd()}/${state.filename}\n`)
ui.say(chalk.bold(`> cat ${process.cwd()}/${state.filename}\n`))
content.split("\n").forEach(l => ui.say(` ` + chalk.green(l)))
ui.say("")
ui.pause(2)
await ui.pause(2)

ui.say("There's a collection of small, simple ideas in here, but Danger is about being able to easily")
ui.say("iterate. The power comes from you having the ability to codify fixes for some of the problems")
Expand All @@ -97,23 +123,26 @@ const setupDangerfile = (ui: InitUI, state: State) => {
ui.waitForReturn()
}

const setupGitHubAccount = (ui: InitUI, state: State) => {
const setupGitHubAccount = async (ui: InitUI, state: State) => {
ui.header("Step 2: Creating a GitHub account")

ui.say("In order to get the most out of Danger, I'd recommend giving her the ability to post in")
ui.say("the code-review comment section.\n\n")
ui.pause(1)
await ui.pause(1)

ui.say("IMO, it's best to do this by using the private mode of your browser. Create an account like")
ui.say(`${state.botName}, and don't forget a cool robot avatar.\n\n`)
ui.pause(1)
await ui.pause(1)
ui.say("Here are great resources for creative commons images of robots:")
const flickr = ui.link("flickr", "https://www.flickr.com/search/?text=robot&license=2%2C3%2C4%2C5%2C6%2C9")
const googImages = ui.link(
"googleimages",
"https://www.google.com/search?q=robot&tbs=sur:fmc&tbm=isch&tbo=u&source=univ&sa=X&ved=0ahUKEwjgy8-f95jLAhWI7hoKHV_UD00QsAQIMQ&biw=1265&bih=1359"
)
ui.pause(1)
ui.say(" - " + flickr)
ui.say(" - " + googImages)
ui.say("")
await ui.pause(1)

if (state.isAnOSSRepo) {
ui.say(`${state.botName} does not need privileged access to your repo or org. This is because Danger will only`)
Expand All @@ -125,17 +154,17 @@ const setupGitHubAccount = (ui: InitUI, state: State) => {

ui.say("")
// note_about_clicking_links
ui.pause(1)
await ui.pause(1)
ui.say("\nCool, please press return when you have your account ready (and you've verified the email...)")
ui.waitForReturn()
}

const stepThree = (ui: InitUI, state: State) => {
const setupGHAccessToken = async (ui: InitUI, state: State) => {
ui.header("Step 3: Configuring a GitHub Personal Access Token")

ui.say("Here's the link, you should open this in the private session where you just created the new GitHub account")
ui.link("New GitHub Token", "https://github.com/settings/tokens/new")
ui.pause(1)
await ui.pause(1)

state.isAnOSSRepo =
ui.askWithAnswers(
Expand All @@ -145,8 +174,8 @@ const stepThree = (ui: InitUI, state: State) => {

if (state.isAnOSSRepo) {
ui.say("For Open Source projects, I'd recommend giving the token the smallest scope possible.")
ui.say("This means only providing access to " + "public_repo".yellow + " in the token.\n\n")
ui.pause(1)
ui.say("This means only providing access to " + chalk.yellow("public_repo") + " in the token.\n\n")
await ui.pause(1)
ui.say("This token limits Danger's abilities to just writing comments on OSS projects. I recommend")
ui.say("this because the token can quite easily be extracted from the environment via pull requests.")

Expand All @@ -155,51 +184,55 @@ const stepThree = (ui: InitUI, state: State) => {
)
} else {
ui.say("For Closed Source projects, I'd recommend giving the token access to the whole repo scope.")
ui.say("This means only providing access to " + "repo".yellow + ", and its children in the token.\n\n")
ui.pause(1)
ui.say("It's worth noting that you " + "should not".bold.white + " re-use this token for OSS repos.")
ui.say("Make a new one for those repos with just " + "public_repo".yellow + ".")
ui.pause(1)
ui.say("This means only providing access to " + chalk.yellow("repo") + ", and its children in the token.\n\n")
await ui.pause(1)
ui.say("It's worth noting that you " + chalk.bold.white("should not") + " re-use this token for OSS repos.")
ui.say("Make a new one for those repos with just " + chalk.yellow("public_repo") + ".")
await ui.pause(1)
ui.say("Additionally, don't forget to add your new GitHub account as a collaborator to your Closed Source project.")
}

ui.say("\n👍, please press return when you have your token set up...")
ui.waitForReturn()
}

const noteAboutClickingLinks = (ui: InitUI, state: State) => {
const modifier_key = state.isMac ? "cmd ( ⌘ )" : "ctrl"
const clicks = state.isWindows ? "clicking" : "double clicking"
// const noteAboutClickingLinks = (ui: InitUI, state: State) => {
// const modifier_key = state.isMac ? "cmd ( ⌘ )" : "ctrl"
// const clicks = state.isWindows ? "clicking" : "double clicking"

ui.say(`Note: Holding ${modifier_key} and ${clicks} a link will open it in your browser.`)
}
// ui.say(`Note: Holding ${modifier_key} and ${clicks} a link will open it in your browser.`)
// }

const noteAboutClickingLinks = (ui: InitUI, state: State) => {
const wrapItUp = async (ui: InitUI, _state: State) => {
ui.header("Useful info")
ui.say("- One of the best ways to test out new rules locally is via " + "bundle exec danger pr".yellow + ".")
ui.pause(0.6)
ui.say("- You can have Danger output all of her variables to the console via the " + "--verbose".yellow + " option.")
ui.pause(0.6)
ui.say("- One of the best ways to test out new rules locally is via " + chalk.yellow("bundle exec danger pr") + ".")
await ui.pause(0.6)
ui.say(
"- You can have Danger output all of her variables to the console via the " + chalk.yellow("--verbose") + " option."
)
await ui.pause(0.6)
ui.say("- You can look at the following Dangerfiles to get some more ideas:")
ui.pause(0.6)
await ui.pause(0.6)
// ui.link("https://github.com/danger/danger/blob/master/Dangerfile")
// ui.link("https://github.com/artsy/eigen/blob/master/Dangerfile")
ui.pause(1)
await ui.pause(1)
}

const thanks = (ui: InitUI, state: State) => {
const thanks = async (ui: InitUI, _state: State) => {
ui.say("\n\n🎉")
ui.pause(0.6)
await ui.pause(0.6)

ui.say(
"And you're good to go. Danger is a collaboration between Orta Therox, Gem 'Danger' Maslen, and all the people."
)
ui.say(
"If you like Danger, let others know. If you want to know more, follow " +
"@orta".yellow +
chalk.yellow("@orta") +
" and " +
"@KrauseFx".yellow +
chalk.yellow("@DangerSystems") +
" on Twitter."
)
ui.say("If you don't like something about Danger, help us improve the project - it's all volunteer time! xxx")
}

go()
4 changes: 4 additions & 0 deletions source/dsl/GitHubDSL.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,10 @@ export interface GitHubUser {
* Whether the user is an org, or a user
*/
type: "User" | "Organization"
/**
* The url for a users's image
*/
avatar_url: string
}

/**
Expand Down
10 changes: 10 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1245,6 +1245,12 @@ cli-cursor@^2.1.0:
dependencies:
restore-cursor "^2.0.0"

cli-interact@^0.1.9:
version "0.1.9"
resolved "https://registry.yarnpkg.com/cli-interact/-/cli-interact-0.1.9.tgz#e58ae8505bbf7ed2e12671057cd559b12fdce28f"
dependencies:
readline-sync "~0.4.9"

cli-spinners@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-0.1.2.tgz#bb764d88e185fb9e1e6a2a1f19772318f605e31c"
Expand Down Expand Up @@ -4233,6 +4239,10 @@ readdirp@^2.0.0:
readable-stream "^2.0.2"
set-immediate-shim "^1.0.1"

readline-sync@~0.4.9:
version "0.4.10"
resolved "https://registry.yarnpkg.com/readline-sync/-/readline-sync-0.4.10.tgz#bef03d993eca3585fd064f5d56d7276765dfc121"

rechoir@^0.6.2:
version "0.6.2"
resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384"
Expand Down

0 comments on commit 0dc7ae1

Please sign in to comment.