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

feat: improve create-solana-dapp args handling #8

Merged
merged 10 commits into from
Nov 10, 2023
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ For example, this one-liner will create a new app with the latest version of the
React preset and yarn as the package manager:

```shell
npx --yes create-solana-dapp@local --name app-"$(date +%s)" --preset react --package-manager yarn
npx --yes create-solana-dapp@local app-"$(date +%s)" --preset react --package-manager yarn
```

To check all the options, run:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,37 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`create-solana-dapp should print the help command 1`] = `
"┌ create-solana-dapp 1.0.0
Usage: create-solana-dapp [options]
"┌ create-solana-dapp 2.0.0
Usage: create-solana-dapp [options] [name]
Arguments:
name Name of the project (default: <prompt>)
Options:
-V, --version output the version number
-n, --name <name>
Name of the workspace
--app-name <name>
Name of the frontend project (default: web)
-V, --version
Output the version number
-p, --preset <preset>
Preset to use (options: next, react)
-d, --dry-run
Dry run (default: false)
-a, --anchor
Include anchor in the project (default: true)
--anchor-name <anchor-name>
Preset to use (default: <prompt>, options: next, react)
--ui <ui-library>
UI library to use (default: <prompt>)
-a, --anchor <template>
Name of the Anchor template to use (default: <prompt>, set to "none" to prevent adding Anchor)
--anchor-build
Build the anchor project (default: false)
--anchor-name <name>
Anchor project name (default: anchor)
--anchor-template <anchor-template>
Anchor template (default: counter)
--web-name <name>
Web project name (default: web)
-pm, --package-manager <package-manager>
Package manager to use (default: npm)
-h, --help display help for command
--yarn
Use yarn as the package manager (default: false)
--pnpm
Use pnpm as the package manager (default: false)
-d, --dry-run
Dry run (default: false)
-h, --help
Display help for command
Examples:
$ create-solana-dapp --name my-app --preset react
$ create-solana-dapp --name my-app --preset react --package-manager yarn
$ create-solana-dapp --name my-app --preset react --anchor-template hello-world"
$ create-solana-dapp my-app --preset react
$ create-solana-dapp my-app --preset react --package-manager yarn
$ create-solana-dapp my-app --preset react --anchor hello-world"
`;
68 changes: 47 additions & 21 deletions packages/create-solana-dapp/bin/index.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,59 @@
#!/usr/bin/env node
import { intro, note, outro } from '@clack/prompts'
import { createWorkspace } from 'create-nx-workspace'
import { app, getArgs } from '../lib/get-args'
import { intro, log, note, outro, spinner } from '@clack/prompts'
import { execAndWait } from 'create-nx-workspace/src/utils/child-process-utils'
import { detectInvokedPackageManager } from 'create-nx-workspace/src/utils/package-manager'
import { getAppInfo } from '../lib/get-app-info'
import { getArgs } from '../lib/get-args'
import { customCreateWorkspace } from '../lib/custom-create-workspace'
import { join } from 'node:path'

async function main() {
const app = getAppInfo()
intro(`${app.name} ${app.version}`)
const args = await getArgs()
const pm = detectInvokedPackageManager()
const args = await getArgs(process.argv, pm)

if (!args.dryRun) {
const { directory } = await createWorkspace(`${args.package}`, {
name: args.name,
nxCloud: false,
packageManager: args.packageManager,
commit: {
name: 'Solana Developers',
email: '[email protected]',
message: 'chore: initial commit',
const s = spinner()
s.start(`Creating workspace...`)
const { directory } = await customCreateWorkspace(
`${args.package}`,
{
anchor: args.anchor,
anchorName: args.anchorName,
commit: {
name: 'Solana Developers',
email: '[email protected]',
message: 'chore: initial commit',
},
dryRun: args.dryRun,
name: args.name,
nxCloud: false,
packageManager: args.packageManager,
ui: args.ui,
webName: args.webName,
},
withAnchor: args.anchor,
anchorName: args.anchorName,
anchorTemplate: args.anchorTemplate,
appName: args.appName,
})
async () => {
s.stop('Workspace created.')
if (args.anchor === 'none' || !args.anchorBuild) {
s.message('No anchor template to build.')
return
}
s.start('Building anchor...')
try {
await execAndWait(`anchor keys sync`, join(args.name, args.anchorName))
await execAndWait(`npx nx run ${args.anchorName}:build`, join(args.name))
s.stop('Anchor built.')
} catch (e) {
s.stop('Anchor build failed.')
log.warn('Do you have Rust and Anchor installed?')
}
},
)

note(`Successfully created the workspace: ${directory}.`)
outro(`Run \`cd ${directory}\` to get started.`)
outro(`Run \`cd ${directory.replace(process.cwd(), '.')}\` to get started.`)
} else {
note('Dry run, no changes were made.')
note(JSON.stringify(args, null, 2))
note(JSON.stringify(args, null, 2), 'Dry run, no changes were made.')
outro(`Would have created the workspace: ${args.name} with preset: ${args.preset}.`)
}
}
Expand Down
205 changes: 205 additions & 0 deletions packages/create-solana-dapp/lib/__snapshots__/get-args.spec.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`get-args expected args should get args with minimal parameters 1`] = `
{
"anchor": "counter",
"anchorBuild": false,
"anchorName": "anchor",
"dryRun": false,
"name": "my-app",
"package": "@solana-developers/[email protected]",
"packageManager": "npm",
"pnpm": false,
"preset": "next",
"ui": "tailwind",
"webName": "web",
"yarn": false,
}
`;

exports[`get-args expected args should get args with minimal parameters and package manager npm 1`] = `
{
"anchor": "counter",
"anchorBuild": false,
"anchorName": "anchor",
"dryRun": false,
"name": "my-app",
"package": "@solana-developers/[email protected]",
"packageManager": "npm",
"pnpm": false,
"preset": "next",
"ui": "tailwind",
"webName": "web",
"yarn": false,
}
`;

exports[`get-args expected args should get args with minimal parameters and package manager pnpm 1`] = `
{
"anchor": "counter",
"anchorBuild": false,
"anchorName": "anchor",
"dryRun": false,
"name": "my-app",
"package": "@solana-developers/[email protected]",
"packageManager": "pnpm",
"pnpm": false,
"preset": "next",
"ui": "tailwind",
"webName": "web",
"yarn": false,
}
`;

exports[`get-args expected args should get args with minimal parameters and package manager yarn 1`] = `
{
"anchor": "counter",
"anchorBuild": false,
"anchorName": "anchor",
"dryRun": false,
"name": "my-app",
"package": "@solana-developers/[email protected]",
"packageManager": "yarn",
"pnpm": false,
"preset": "next",
"ui": "tailwind",
"webName": "web",
"yarn": false,
}
`;

exports[`get-args expected args should get args with preset: --preset next --ui tailwind --anchor counter 1`] = `
{
"anchor": "counter",
"anchorBuild": false,
"anchorName": "anchor",
"dryRun": false,
"name": "my-app",
"package": "@solana-developers/[email protected]",
"packageManager": "npm",
"pnpm": false,
"preset": "next",
"ui": "tailwind",
"webName": "web",
"yarn": false,
}
`;

exports[`get-args expected args should get args with preset: --preset react --anchor counter --anchor-name program --ui tailwind 1`] = `
{
"anchor": "counter",
"anchorBuild": false,
"anchorName": "program",
"dryRun": false,
"name": "my-app",
"package": "@solana-developers/[email protected]",
"packageManager": "npm",
"pnpm": false,
"preset": "react",
"ui": "tailwind",
"webName": "web",
"yarn": false,
}
`;

exports[`get-args expected args should get args with preset: --preset react --anchor none --ui none --pnpm 1`] = `
{
"anchor": "none",
"anchorBuild": false,
"anchorName": "program",
"dryRun": false,
"name": "my-app",
"package": "@solana-developers/[email protected]",
"packageManager": "pnpm",
"pnpm": true,
"preset": "react",
"ui": "none",
"webName": "web",
"yarn": false,
}
`;

exports[`get-args expected args should get args with preset: --preset react --anchor none --ui none --yarn 1`] = `
{
"anchor": "none",
"anchorBuild": false,
"anchorName": "program",
"dryRun": false,
"name": "my-app",
"package": "@solana-developers/[email protected]",
"packageManager": "yarn",
"pnpm": false,
"preset": "react",
"ui": "none",
"webName": "web",
"yarn": true,
}
`;

exports[`get-args expected args should get args with preset: --preset react --anchor none --ui none 1`] = `
{
"anchor": "none",
"anchorBuild": false,
"anchorName": "anchor",
"dryRun": false,
"name": "my-app",
"package": "@solana-developers/[email protected]",
"packageManager": "npm",
"pnpm": false,
"preset": "react",
"ui": "none",
"webName": "web",
"yarn": false,
}
`;

exports[`get-args expected args should get args with preset: --preset react --ui tailwind --anchor counter 1`] = `
{
"anchor": "counter",
"anchorBuild": false,
"anchorName": "anchor",
"dryRun": false,
"name": "my-app",
"package": "@solana-developers/[email protected]",
"packageManager": "npm",
"pnpm": false,
"preset": "react",
"ui": "tailwind",
"webName": "web",
"yarn": false,
}
`;

exports[`get-args expected args should get args with preset: --preset=react --anchor=counter --anchor-name=program --anchor-build --ui=tailwind 1`] = `
{
"anchor": "counter",
"anchorBuild": true,
"anchorName": "program",
"dryRun": false,
"name": "my-app",
"package": "@solana-developers/[email protected]",
"packageManager": "npm",
"pnpm": false,
"preset": "react",
"ui": "tailwind",
"webName": "web",
"yarn": false,
}
`;

exports[`get-args expected args should get args with preset: --preset=react --anchor=counter --anchor-name=program --ui=tailwind 1`] = `
{
"anchor": "counter",
"anchorBuild": false,
"anchorName": "program",
"dryRun": false,
"name": "my-app",
"package": "@solana-developers/[email protected]",
"packageManager": "npm",
"pnpm": false,
"preset": "react",
"ui": "tailwind",
"webName": "web",
"yarn": false,
}
`;
1 change: 1 addition & 0 deletions packages/create-solana-dapp/lib/anchor-templates.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const anchorTemplates = ['counter', 'hello-world', 'none']
Loading