Skip to content
This repository has been archived by the owner on Jan 13, 2023. It is now read-only.

Commit

Permalink
feat: Prettier-ize & lint Bowser and generated projects (#214)
Browse files Browse the repository at this point in the history
* Add prettier & npm-run-all to bowser itself
* Bump dependency versions
* Prettier-ize and fix lint complaints
* Run tests in-band, to get jest to run our long-running tests without complaining
* Do test git initialization manually, so we can set up the git user for ci
* Lint and format new apps; test to make sure they format & lint cleanly
  • Loading branch information
bryanstearns authored Jul 4, 2019
1 parent c7c595e commit 381a900
Show file tree
Hide file tree
Showing 47 changed files with 366 additions and 355 deletions.
149 changes: 77 additions & 72 deletions boilerplate.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const { merge, pipe, assoc, omit, __ } = require('ramda')
const { getReactNativeVersion } = require('./lib/react-native-version')
const { merge, pipe, assoc, omit, __ } = require("ramda")
const { getReactNativeVersion } = require("./lib/react-native-version")

/**
* Is Android installed?
Expand All @@ -10,9 +10,9 @@ const { getReactNativeVersion } = require('./lib/react-native-version')
* @returns {boolean}
*/
const isAndroidInstalled = function(context) {
const androidHome = process.env['ANDROID_HOME']
const androidHome = process.env["ANDROID_HOME"]
const hasAndroidEnv = !context.strings.isBlank(androidHome)
const hasAndroid = hasAndroidEnv && context.filesystem.exists(`${androidHome}/tools`) === 'dir'
const hasAndroid = hasAndroidEnv && context.filesystem.exists(`${androidHome}/tools`) === "dir"

return Boolean(hasAndroid)
}
Expand All @@ -32,22 +32,22 @@ async function install(context) {
system,
template,
prompt,
patching
patching,
} = context
const { colors } = print
const { red, yellow, bold, gray, blue, cyan } = colors
const isWindows = process.platform === 'win32'
const isMac = process.platform === 'darwin'
const { red, yellow, bold, gray, cyan } = colors
const isWindows = process.platform === "win32"
const isMac = process.platform === "darwin"

const perfStart = new Date().getTime()

const name = parameters.first
const spinner = print
.spin(`using the ${red('Infinite Red')} boilerplate v3 (code name 'Bowser')`)
.spin(`using the ${red("Infinite Red")} boilerplate v3 (code name 'Bowser')`)
.succeed()

// attempt to install React Native or die trying
let rnInstall = undefined
let rnInstall
rnInstall = await reactNative.install({
name,
version: getReactNativeVersion(context),
Expand All @@ -56,14 +56,14 @@ async function install(context) {
if (rnInstall.exitCode > 0) process.exit(rnInstall.exitCode)

// remove the __tests__ directory, App.js, and unnecessary config files that come with React Native
const filesToRemove = ['__tests__', 'App.js', '.babelrc', '.flowconfig', '.buckconfig']
const filesToRemove = ["__tests__", "App.js", ".babelrc", ".flowconfig", ".buckconfig"]
filesToRemove.map(filesystem.remove)

let includeDetox = false
if (isMac) {
const askAboutDetox = parameters.options.detox === undefined
includeDetox = askAboutDetox
? await prompt.confirm('Would you like to include Detox end-to-end tests?')
? await prompt.confirm("Would you like to include Detox end-to-end tests?")
: parameters.options.detox === true

if (includeDetox) {
Expand All @@ -85,50 +85,50 @@ async function install(context) {
}

// copy our App, Tests & storybook directories
spinner.text = '▸ copying files'
spinner.text = "▸ copying files"
spinner.start()
filesystem.copy(`${__dirname}/boilerplate/app`, `${process.cwd()}/app`, {
overwrite: true,
matching: '!*.ejs'
matching: "!*.ejs",
})
filesystem.copy(`${__dirname}/boilerplate/test`, `${process.cwd()}/test`, {
overwrite: true,
matching: '!*.ejs'
matching: "!*.ejs",
})
filesystem.copy(`${__dirname}/boilerplate/storybook`, `${process.cwd()}/storybook`, {
overwrite: true,
matching: '!*.ejs'
matching: "!*.ejs",
})
filesystem.copy(`${__dirname}/boilerplate/bin`, `${process.cwd()}/bin`, {
overwrite: true
overwrite: true,
})
includeDetox &&
filesystem.copy(`${__dirname}/boilerplate/e2e`, `${process.cwd()}/e2e`, {
overwrite: true,
matching: '!*.ejs'
matching: "!*.ejs",
})
spinner.stop()

// generate some templates
spinner.text = '▸ generating files'
spinner.text = "▸ generating files"
//
const templates = [
{ template: 'index.js.ejs', target: 'index.js' },
{ template: 'README.md', target: 'README.md' },
{ template: '.gitignore.ejs', target: '.gitignore' },
{ template: '.prettierignore', target: '.prettierignore' },
{ template: '.solidarity', target: '.solidarity' },
{ template: '.babelrc', target: '.babelrc' },
{ template: 'tsconfig.json', target: 'tsconfig.json' },
{ template: 'app/app.tsx.ejs', target: 'app/app.tsx' },
{ template: "index.js.ejs", target: "index.js" },
{ template: "README.md", target: "README.md" },
{ template: ".gitignore.ejs", target: ".gitignore" },
{ template: ".prettierignore", target: ".prettierignore" },
{ template: ".solidarity", target: ".solidarity" },
{ template: ".babelrc", target: ".babelrc" },
{ template: "tsconfig.json", target: "tsconfig.json" },
{ template: "app/app.tsx.ejs", target: "app/app.tsx" },
{
template: 'app/screens/welcome-screen/welcome-screen.tsx.ejs',
target: 'app/screens/welcome-screen/welcome-screen.tsx'
template: "app/screens/welcome-screen/welcome-screen.tsx.ejs",
target: "app/screens/welcome-screen/welcome-screen.tsx",
},
{
template: 'app/screens/demo-screen/demo-screen.tsx.ejs',
target: 'app/screens/demo-screen/demo-screen.tsx'
}
template: "app/screens/demo-screen/demo-screen.tsx.ejs",
target: "app/screens/demo-screen/demo-screen.tsx",
},
]
const templateProps = {
name,
Expand All @@ -137,18 +137,18 @@ async function install(context) {
vectorIcons: false,
animatable: false,
i18n: false,
includeDetox
includeDetox,
}
await ignite.copyBatch(context, templates, templateProps, {
quiet: true,
directory: `${ignite.ignitePluginPath()}/boilerplate`
directory: `${ignite.ignitePluginPath()}/boilerplate`,
})

/**
* Append to files
*/
// https://github.com/facebook/react-native/issues/12724
filesystem.appendAsync('.gitattributes', '*.bat text eol=crlf')
filesystem.appendAsync(".gitattributes", "*.bat text eol=crlf")

/**
* Merge the package.json from our template into the one provided from react-native init.
Expand All @@ -157,75 +157,75 @@ async function install(context) {
// transform our package.json in case we need to replace variables
const rawJson = await template.generate({
directory: `${ignite.ignitePluginPath()}/boilerplate`,
template: 'package.json.ejs',
props: templateProps
template: "package.json.ejs",
props: templateProps,
})
const newPackageJson = JSON.parse(rawJson)

// read in the react-native created package.json
const currentPackage = filesystem.read('package.json', 'json')
const currentPackage = filesystem.read("package.json", "json")

// deep merge, lol
const newPackage = pipe(
assoc('dependencies', merge(currentPackage.dependencies, newPackageJson.dependencies)),
assoc("dependencies", merge(currentPackage.dependencies, newPackageJson.dependencies)),
assoc(
'devDependencies',
merge(currentPackage.devDependencies, newPackageJson.devDependencies)
"devDependencies",
merge(currentPackage.devDependencies, newPackageJson.devDependencies),
),
assoc('scripts', merge(currentPackage.scripts, newPackageJson.scripts)),
merge(__, omit(['dependencies', 'devDependencies', 'scripts'], newPackageJson))
assoc("scripts", merge(currentPackage.scripts, newPackageJson.scripts)),
merge(__, omit(["dependencies", "devDependencies", "scripts"], newPackageJson)),
)(currentPackage)

// write this out
filesystem.write('package.json', newPackage, { jsonIndent: 2 })
filesystem.write("package.json", newPackage, { jsonIndent: 2 })
}
await mergePackageJsons()
spinner.stop()

// pass long the debug flag if we're running in that mode
const debugFlag = parameters.options.debug ? '--debug' : ''
const debugFlag = parameters.options.debug ? "--debug" : ""

try {
// boilerplate adds itself to get plugin.js/generators etc
// Could be directory, npm@version, or just npm name. Default to passed in values
const boilerplate = parameters.options.b || parameters.options.boilerplate || 'ignite-bowser'
const boilerplate = parameters.options.b || parameters.options.boilerplate || "ignite-bowser"

await system.spawn(`ignite add ${boilerplate} ${debugFlag}`, { stdio: 'inherit' })
await system.spawn(`ignite add ${boilerplate} ${debugFlag}`, { stdio: "inherit" })

// react native link -- must use spawn & stdio: ignore or it hangs!! :(
spinner.text = `▸ linking native libraries`
spinner.start()
await system.spawn('react-native link', { stdio: 'ignore' })
await system.spawn("react-native link", { stdio: "ignore" })
spinner.stop()

await ignite.addModule('react-native-gesture-handler', { version: '1.1.0', link: true })
await ignite.addModule("react-native-gesture-handler", { version: "1.1.0", link: true })

ignite.patchInFile(
`${process.cwd()}/android/app/src/main/java/com/${name.toLowerCase()}/MainActivity.java`,
{
after: 'import com.facebook.react.ReactActivity;',
after: "import com.facebook.react.ReactActivity;",
insert: `
import com.facebook.react.ReactActivityDelegate;
import com.facebook.react.ReactRootView;
import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView;`
}
import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView;`,
},
)

ignite.patchInFile(
`${process.cwd()}/android/app/src/main/java/com/${name.toLowerCase()}/MainActivity.java`,
{
after: `public class MainActivity extends ReactActivity {`,
insert:
'\n @Override\n' +
' protected ReactActivityDelegate createReactActivityDelegate() {\n' +
' return new ReactActivityDelegate(this, getMainComponentName()) {\n' +
' @Override\n' +
' protected ReactRootView createRootView() {\n' +
' return new RNGestureHandlerEnabledRootView(MainActivity.this);\n' +
' }\n' +
' };\n' +
' }'
}
"\n @Override\n" +
" protected ReactActivityDelegate createReactActivityDelegate() {\n" +
" return new ReactActivityDelegate(this, getMainComponentName()) {\n" +
" @Override\n" +
" protected ReactRootView createRootView() {\n" +
" return new RNGestureHandlerEnabledRootView(MainActivity.this);\n" +
" }\n" +
" };\n" +
" }",
},
)
} catch (e) {
ignite.log(e)
Expand All @@ -236,33 +236,38 @@ async function install(context) {
}

// re-run yarn
const installDeps = ignite.useYarn ? 'yarn' : 'npm install'
const installDeps = ignite.useYarn ? "yarn" : "npm install"
await system.run(installDeps)
spinner.succeed(`Installed dependencies`)

// re-run react-native link
await system.spawn('react-native link', { stdio: 'ignore' })
await system.spawn("react-native link", { stdio: "ignore" })
spinner.succeed(`Linked dependencies`)

// for Windows, fix the settings.gradle file. Ref: https://github.com/oblador/react-native-vector-icons/issues/938#issuecomment-463296401
// for ease of use, just replace any backslashes with forward slashes
if (isWindows) {
await patching.update(`${process.cwd()}/android/settings.gradle`, contents => {
return contents.split('\\').join('/')
return contents.split("\\").join("/")
})
}

// let eslint and prettier clean things up
await system.spawn(`${ignite.useYarn ? "yarn" : "npm run"} lint`)
await system.spawn(`${ignite.useYarn ? "yarn" : "npm run"} format`)
spinner.succeed("Linted and formatted")

const perfDuration = parseInt((new Date().getTime() - perfStart) / 10) / 100
spinner.succeed(`ignited ${yellow(name)} in ${perfDuration}s`)

const androidInfo = isAndroidInstalled(context)
? ''
? ""
: `\n\nTo run in Android, make sure you've followed the latest react-native setup instructions at https://facebook.github.io/react-native/docs/getting-started.html before using ignite.\nYou won't be able to run ${bold(
'react-native run-android'
"react-native run-android",
)} successfully until you have.`

const successMessage = `
${red('Ignite CLI')} ignited ${yellow(name)} in ${gray(`${perfDuration}s`)}
${red("Ignite CLI")} ignited ${yellow(name)} in ${gray(`${perfDuration}s`)}
To get started:
Expand All @@ -271,18 +276,18 @@ async function install(context) {
react-native run-android${androidInfo}
ignite --help
${cyan('Need additional help? Join our Slack community at http://community.infinite.red.')}
${cyan("Need additional help? Join our Slack community at http://community.infinite.red.")}
${bold('Now get cooking! 🍽')}
${bold("Now get cooking! 🍽")}
${gray(
'(Running yarn install one last time to make sure everything is installed -- please be patient!)'
"(Running yarn install one last time to make sure everything is installed -- please be patient!)",
)}
`

print.info(successMessage)
}

module.exports = {
install
install,
}
1 change: 1 addition & 0 deletions boilerplate/.prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ node_modules
ios
android
.vscode
ignite/ignite.json
package.json
2 changes: 1 addition & 1 deletion boilerplate/app/components/bullet-item/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export * from "./bullet-item"
export * from "./bullet-item"
12 changes: 3 additions & 9 deletions boilerplate/app/components/button/button.story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,9 @@ import { storiesOf } from "@storybook/react-native"
import { StoryScreen, Story, UseCase } from "../../../storybook/views"
import { Button } from "./"

const buttonStyleArray: ViewStyle[] = [
{paddingVertical: 100},
{borderRadius: 0},
]
const buttonStyleArray: ViewStyle[] = [{ paddingVertical: 100 }, { borderRadius: 0 }]

const buttonTextStyleArray: TextStyle[] = [
{fontSize: 20},
{color: "#a511dc"},
]
const buttonTextStyleArray: TextStyle[] = [{ fontSize: 20 }, { color: "#a511dc" }]

storiesOf("Button", module)
.addDecorator(fn => <StoryScreen>{fn()}</StoryScreen>)
Expand All @@ -24,7 +18,7 @@ storiesOf("Button", module)
<UseCase text="Disabled" usage="The disabled behaviour of the primary button.">
<Button text="Click It" preset="primary" onPress={() => Alert.alert("pressed")} disabled />
</UseCase>
<UseCase text="Array Style" usage="Button with array style" >
<UseCase text="Array Style" usage="Button with array style">
<Button
text="Click It"
preset="primary"
Expand Down
14 changes: 12 additions & 2 deletions boilerplate/app/components/button/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,20 @@ import { mergeAll, flatten } from "ramda"
*/
export function Button(props: ButtonProps) {
// grab the props
const { preset = "primary", tx, text, style: styleOverride, textStyle: textStyleOverride, children, ...rest } = props
const {
preset = "primary",
tx,
text,
style: styleOverride,
textStyle: textStyleOverride,
children,
...rest
} = props

const viewStyle = mergeAll(flatten([viewPresets[preset] || viewPresets.primary, styleOverride]))
const textStyle = mergeAll(flatten([textPresets[preset] || textPresets.primary, textStyleOverride]))
const textStyle = mergeAll(
flatten([textPresets[preset] || textPresets.primary, textStyleOverride]),
)

const content = children || <Text tx={tx} text={text} style={textStyle} />

Expand Down
Loading

0 comments on commit 381a900

Please sign in to comment.