Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(cli): reworks --mst to --state=mst #2731

Merged
merged 2 commits into from
Aug 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/cli/Ignite-CLI.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,11 @@ Starts the interactive prompt for generating a new Ignite project. Any options n
- `--overwrite` overwrite the target directory if it exists
- `--targetPath` string, specify a target directory where the project should be created
- `--removeDemo` will remove the boilerplate demo code after project creation
- `--mst` flag to specify whether to include MobX-State-Tree in project (can only be set to `false` if `--removeDemo=true`)
- `--state` string, one of `mst` or `none` to include MobX-State-Tree in project (can only be set to `none` if `--removeDemo=true`)
- `--useCache` flag specifying to use dependency cache for quicker installs
- `--no-timeout` flag to disable the timeout protection (useful for slow internet connections)
- `--yes` accept all prompt defaults
- `--workflow` string, one of `expo`, `cng` or `manual` for project initialization
- `--workflow` string, one of `cng` or `manual` for project initialization
- `--experimental` comma separated string, indicates experimental features (which may or may not be stable) to turn on during installation. **A CNG workflow is require for these flags** `--workflow=cng`
- `expo-router` converts the project to [Expo Router](https://docs.expo.dev/router/introduction/) from React Navigation
- `new-arch` enables [The New Architecture](https://reactnative.dev/docs/new-architecture-intro)
Expand Down
4 changes: 2 additions & 2 deletions docs/concept/MobX-State-Tree.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ We also recognize no state management solution is perfect. MST has some known do

### Remove MST Option

We understand that state management is a highly opinionated topic with various options available. To accommodate this, we've added an option in Ignite CLI to remove MobX-State-Tree if you choose so! When Igniting a new project, provide `--mst=false` to remove MobX-State-Tree code from the boilerplate. This option only works when also removing demo code.
We understand that state management is a highly opinionated topic with various options available. To accommodate this, we've added an option in Ignite CLI to remove MobX-State-Tree if you choose so! When Igniting a new project, provide `--state=none` to remove MobX-State-Tree code from the boilerplate. This option only works when also removing demo code.

```
npx ignite-cli@latest new PizzaApp --removeDemo=true --mst=false
npx ignite-cli@latest new PizzaApp --removeDemo=true --state=none
```

## Learning MobX-State-Tree
Expand Down
93 changes: 37 additions & 56 deletions src/commands/new.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import { findAndRemoveDependencies } from "../tools/dependencies"
import { demoDependenciesToRemove } from "../tools/demo"

type Workflow = "cng" | "manual"
type StateMgmt = "mst" | "none"

export interface Options {
/**
Expand Down Expand Up @@ -137,6 +138,7 @@ export interface Options {
* and include them in .gitignore or not
*
* Input Source: `prompt.ask`| `parameter.option`
* @default cng
*/
workflow?: Workflow
/**
Expand All @@ -149,9 +151,9 @@ export interface Options {
* Whether or not to include MobX-State-Tree boilerplate code
*
* Input Source: `prompt.ask` | `parameter.option`
* @default true
* @default mst
*/
mst?: boolean
state?: StateMgmt
}

module.exports = {
Expand Down Expand Up @@ -287,7 +289,7 @@ module.exports = {
const defaultWorkflow = "cng"
let workflow = useDefault(options.workflow) ? defaultWorkflow : options.workflow
if (workflow === undefined) {
const useExpoResponse = await prompt.ask<{ workflow: "cng" | "manual" }>(() => ({
const useExpoResponse = await prompt.ask<{ workflow: Workflow }>(() => ({
type: "select",
name: "workflow",
message: "How do you want to manage Native code?",
Expand Down Expand Up @@ -348,31 +350,31 @@ module.exports = {
// #endregion

// #region Prompt to Remove MobX-State-Tree code
const defaultMST = true
let includeMST = useDefault(options.mst) ? defaultMST : boolFlag(options.mst)
const defaultMST = "mst"
let stateMgmt = useDefault(options.state) ? defaultMST : options.state

if (includeMST === undefined) {
if (stateMgmt === undefined) {
if (!removeDemo) {
includeMST = true
stateMgmt = "mst"
} else {
// only ask if we're removing the demo code
const includeMSTResponse = await prompt.ask<{ includeMST: boolean }>(() => ({
const includeMSTResponse = await prompt.ask<{ includeMST: StateMgmt }>(() => ({
type: "confirm",
name: "includeMST",
message: "Include MobX-State-Tree code? (recommended)",
initial: defaultMST,
format: prettyPrompt.format.boolean,
prefix,
}))
includeMST = includeMSTResponse.includeMST
stateMgmt = includeMSTResponse.includeMST
}
}

if (!removeDemo && includeMST === false) {
if (!removeDemo && stateMgmt === "none") {
p()
p(yellow(`Warning: You can't remove MobX-State-Tree code without removing demo code.`))
p(yellow(`Setting --mst=true`))
includeMST = true
p(yellow(`Setting --state=mst`))
stateMgmt = "mst"
}
// #endregion

Expand Down Expand Up @@ -658,7 +660,7 @@ module.exports = {
packageJsonRaw = findAndRemoveDependencies(packageJsonRaw, demoDependenciesToRemove)
}

if (!includeMST) {
if (stateMgmt === "none") {
log(`Removing MST dependencies... ${mstDependenciesToRemove.join(", ")}`)
packageJsonRaw = findAndRemoveDependencies(packageJsonRaw, mstDependenciesToRemove)
}
Expand Down Expand Up @@ -817,9 +819,7 @@ module.exports = {
const CMD = removeDemo === true ? "remove-demo" : "remove-demo-markup"

log(`Ignite bin path: ${IGNITE}`)
await system.run(`${IGNITE} ${CMD} "${targetPath}"`, {
onProgress: log,
})
await system.run(`${IGNITE} ${CMD} "${targetPath}"`, { onProgress: log })
} catch (e) {
log(e)
p(yellow(`Unable to remove demo ${removeDemoPart}.`))
Expand Down Expand Up @@ -854,46 +854,27 @@ module.exports = {
// #endregion

// #region Remove MST code
if (includeMST) {
// remove MST markup only
startSpinner(`Removing MobX-State-Tree markup`)
try {
const IGNITE = "node " + filesystem.path(__dirname, "..", "..", "bin", "ignite")
log(`Ignite bin path: ${IGNITE}`)
await system.run(
`${IGNITE} remove-mst-markup "${targetPath}" "${
experimentalExpoRouter ? "src" : "app"
}"`,
{
onProgress: log,
},
)
} catch (e) {
log(e)
p(yellow(`Unable to remove MobX-State-Tree markup`))
}
stopSpinner(`Removing MobX-State-Tree markup`, "🌳")
} else {
startSpinner(`Removing MobX-State-Tree code`)
try {
const IGNITE = "node " + filesystem.path(__dirname, "..", "..", "bin", "ignite")
log(`Ignite bin path: ${IGNITE}`)
await system.run(
`${IGNITE} remove-mst "${targetPath}" "${experimentalExpoRouter ? "src" : "app"}"`,
{
onProgress: log,
},
)
} catch (e) {
log(e)
p(
yellow(
`Unable to remove MobX-State-Tree code. To perform updates manually, check out the recipe with full instructions: https://ignitecookbook.com/docs/recipes/RemoveMobxStateTree`,
),
)
}
stopSpinner(`Removing MobX-State-Tree code`, "🌳")
const removeMstPart = stateMgmt === "none" ? "code" : "markup"
startSpinner(`Removing MobX-State-Tree ${removeMstPart}`)
try {
const IGNITE = "node " + filesystem.path(__dirname, "..", "..", "bin", "ignite")
const CMD = stateMgmt === "none" ? "remove-mst" : "remove-mst-markup"

log(`Ignite bin path: ${IGNITE}`)
await system.run(
`${IGNITE} ${CMD} "${targetPath}" "${experimentalExpoRouter ? "src" : "app"}"`,
{ onProgress: log },
)
} catch (e) {
log(e)
const additionalInfo =
stateMgmt === "none"
? ` To perform updates manually, check out the recipe with full instructions: https://ignitecookbook.com/docs/recipes/RemoveMobxStateTree`
: ""
p(yellow(`Unable to remove MobX-State-Tree ${removeMstPart}.${additionalInfo}`))
}
stopSpinner(`Removing MobX-State-Tree ${removeMstPart}`, "🌳")
// #endregion

// #region Format generator templates EOL for Windows
let warnAboutEOL = false
Expand Down Expand Up @@ -985,7 +966,7 @@ module.exports = {
y: yname,
yes: yname,
noTimeout,
mst: includeMST,
state: stateMgmt,
},
projectName,
toolbox,
Expand Down
14 changes: 7 additions & 7 deletions test/vanilla/ignite-new-expo-router.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ const APP_NAME = "Foo"
const originalDir = process.cwd()

describe(`ignite new with expo-router`, () => {
describe(`ignite new ${APP_NAME} --debug --packager=bun --install-deps=false --experimental=expo-router --mst --yes`, () => {
describe(`ignite new ${APP_NAME} --debug --packager=bun --install-deps=false --experimental=expo-router --state=mst --yes`, () => {
let tempDir: string
let result: string
let appPath: string

beforeAll(async () => {
tempDir = tempy.directory({ prefix: "ignite-" })
result = await runIgnite(
`new ${APP_NAME} --debug --packager=bun --install-deps=false --experimental=expo-router --mst --yes`,
`new ${APP_NAME} --debug --packager=bun --install-deps=false --experimental=expo-router --state=mst --yes`,
{
pre: `cd ${tempDir}`,
post: `cd ${originalDir}`,
Expand All @@ -29,7 +29,7 @@ describe(`ignite new with expo-router`, () => {
})

it("should convert to Expo Router with MST", async () => {
expect(result).toContain("--mst")
expect(result).toContain("--state=mst")

// make sure src/navigators, src/screens, app/, app.tsx is gone
const dirs = filesystem.list(appPath)
Expand Down Expand Up @@ -99,15 +99,15 @@ describe(`ignite new with expo-router`, () => {
})
})

describe(`ignite new ${APP_NAME} --debug --packager=bun --install-deps=false --experimental=expo-router --mst-false --yes`, () => {
describe(`ignite new ${APP_NAME} --debug --packager=bun --install-deps=false --experimental=expo-router --state-none --yes`, () => {
let tempDir: string
let result: string
let appPath: string

beforeAll(async () => {
tempDir = tempy.directory({ prefix: "ignite-" })
result = await runIgnite(
`new ${APP_NAME} --debug --packager=bun --install-deps=false --experimental=expo-router --mst=false --remove-demo --yes`,
`new ${APP_NAME} --debug --packager=bun --install-deps=false --experimental=expo-router --state=none --remove-demo --yes`,
{
pre: `cd ${tempDir}`,
post: `cd ${originalDir}`,
Expand All @@ -122,8 +122,8 @@ describe(`ignite new with expo-router`, () => {
})

it("should convert to Expo Router without MST", async () => {
expect(result).toContain("--mst=false")
expect(result).not.toContain("Setting --mst=true")
expect(result).toContain("--state=none")
expect(result).not.toContain("Setting --state=mst")

// check the contents of ignite/templates
const templates = filesystem.list(`${appPath}/ignite/templates`)
Expand Down