Skip to content

Commit

Permalink
Add --quickstart flag to init command (#1822)
Browse files Browse the repository at this point in the history
* Add --quickstart flag to init command

* Improve quickstart success messaging

Remove extraneous help links in success message

prettier

* Test, format, manifest, changeset

Build with updated Oclif manifest

Changeset
  • Loading branch information
gfscott committed Mar 13, 2024
1 parent 7e8832c commit 5bb4330
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 44 deletions.
6 changes: 6 additions & 0 deletions .changeset/pretty-gifts-rest.md
@@ -0,0 +1,6 @@
---
'@shopify/cli-hydrogen': patch
'@shopify/create-hydrogen': patch
---

Add `--quickstart` flag option to init/create command
7 changes: 7 additions & 0 deletions packages/cli/oclif.manifest.json
Expand Up @@ -765,6 +765,13 @@
"name": "git",
"allowNo": true,
"type": "boolean"
},
"quickstart": {
"description": "Scaffolds a new Hydrogen project with a set of sensible defaults.",
"env": "SHOPIFY_HYDROGEN_FLAG_QUICKSTART",
"name": "quickstart",
"allowNo": false,
"type": "boolean"
}
},
"hasDynamicHelp": false,
Expand Down
48 changes: 46 additions & 2 deletions packages/cli/src/commands/hydrogen/init.test.ts
Expand Up @@ -196,7 +196,6 @@ describe('init', () => {
expect(output).not.toMatch('warning');
expect(output).not.toMatch('Routes');
expect(output).toMatch(/Language:\s*TypeScript/);
expect(output).toMatch('Help');
expect(output).toMatch('Next steps');
expect(output).toMatch(
// Output contains banner characters. USe [^\w]*? to match them.
Expand Down Expand Up @@ -368,7 +367,6 @@ describe('init', () => {
expect(output).toMatch(basename(tmpDir));
expect(output).not.toMatch('Routes');
expect(output).toMatch(/Language:\s*TypeScript/);
expect(output).toMatch('Help');
expect(output).toMatch('Next steps');
expect(output).toMatch(
// Output contains banner characters. USe [^\w]*? to match them.
Expand Down Expand Up @@ -824,5 +822,51 @@ describe('init', () => {
});
});
});

describe('Quickstart options', () => {
it('Scaffolds Quickstart project with expected values', async () => {
await inTemporaryDirectory(async (tmpDir) => {
await runInit({
path: tmpDir,
quickstart: true,
installDeps: false,
});

const templateFiles = await glob('**/*', {
cwd: getSkeletonSourceDir().replace(
'skeleton',
'hydrogen-quickstart',
),
ignore: ['**/node_modules/**', '**/dist/**'],
});
const resultFiles = await glob('**/*', {cwd: tmpDir});
const nonAppFiles = templateFiles.filter(
(item) => !item.startsWith('app/'),
);

expect(resultFiles).toEqual(expect.arrayContaining(nonAppFiles));

expect(resultFiles).toContain('app/root.jsx');
expect(resultFiles).toContain('app/entry.client.jsx');
expect(resultFiles).toContain('app/entry.server.jsx');
expect(resultFiles).toContain('app/components/Layout.jsx');
expect(resultFiles).toContain('app/routes/_index.jsx');
expect(resultFiles).not.toContain('app/routes/($locale)._index.jsx');

// await expect(readFile(`${tmpDir}/package.json`)).resolves.toMatch(
// `"name": "hello-world"`,
// );

const output = outputMock.info();
expect(output).not.toMatch('warning');
expect(output).toMatch('success');
expect(output).toMatch(/Shopify:\s+Mock.shop/);
expect(output).toMatch(/Language:\s+JavaScript/);
expect(output).toMatch(/Styling:\s+Tailwind/);
expect(output).toMatch('Routes');
expect(output).toMatch('Next steps');
});
});
});
});
});
22 changes: 22 additions & 0 deletions packages/cli/src/commands/hydrogen/init.ts
Expand Up @@ -64,6 +64,12 @@ export default class Init extends Command {
default: true,
allowNo: true,
}),
quickstart: Flags.boolean({
description:
'Scaffolds a new Hydrogen project with a set of sensible defaults.',
env: 'SHOPIFY_HYDROGEN_FLAG_QUICKSTART',
default: false,
}),
};

async run(): Promise<void> {
Expand Down Expand Up @@ -103,6 +109,22 @@ export async function runInit(

options.git ??= true;

/**
* Quickstart options. A set of sensible defaults to streamline documentation.
* Logical OR assignment means you can still override individual options by flag:
* $ h2 init --quickstart --language ts
*/
if (options.quickstart) {
options.i18n ||= 'none';
options.installDeps ||= true;
options.language ||= 'js';
options.mockShop ||= true;
options.path ||= './hydrogen-quickstart';
options.routes ||= true;
options.shortcut ||= true;
options.styling ||= 'tailwind';
}

const showUpgrade = await checkHydrogenVersion(
// Resolving the CLI package from a local directory might fail because
// this code could be run from a global dependency (e.g. on `npm create`).
Expand Down
41 changes: 8 additions & 33 deletions packages/cli/src/lib/onboarding/common.ts
Expand Up @@ -75,6 +75,7 @@ export type InitOptions = {
shortcut?: boolean;
installDeps?: boolean;
git?: boolean;
quickstart?: boolean;
};

export const LANGUAGES = {
Expand Down Expand Up @@ -625,6 +626,13 @@ export async function renderProjectReady(

const render = hasErrors ? renderWarning : renderSuccess;

// Dynamically set "Next steps" for success message
const nextSteps = [];

if (true) {
nextSteps.push(['Dependencies', 'were installed']);
}

render({
headline:
`Storefront setup complete` +
Expand Down Expand Up @@ -664,39 +672,6 @@ export async function renderProjectReady(
},
],
},
{
title: 'Help\n',
body: {
list: {
items: [
{
link: {
label: 'Guides',
url: 'https://h2o.fyi/building',
},
},
{
link: {
label: 'API reference',
url: 'https://shopify.dev/docs/api/storefront',
},
},
{
link: {
label: 'Demo Store code',
url: 'https://github.com/Shopify/hydrogen/tree/HEAD/templates/demo-store',
},
},
[
'Run',
{
command: `${cliCommand} --help`,
},
],
],
},
},
},
{
title: 'Next steps\n',
body: [
Expand Down
30 changes: 21 additions & 9 deletions packages/cli/src/lib/onboarding/local.ts
Expand Up @@ -108,15 +108,22 @@ export async function setupLocalStarterTemplate(
)
.catch(abort);

// Note: Async task titles automatically have '...' appended
const initMsg = {
create: 'Creating storefront',
setup: `Setting up ${options.quickstart ? 'Quickstart ' : ''}project`,
install: 'Installing dependencies. This could take a few minutes',
};

const tasks = [
{
title: 'Creating storefront',
title: initMsg.create,
task: async () => {
await createStorefrontPromise;
},
},
{
title: 'Setting up project',
title: initMsg.setup,
task: async () => {
await backgroundWorkPromise;
},
Expand Down Expand Up @@ -249,7 +256,7 @@ export async function setupLocalStarterTemplate(
});

tasks.push({
title: 'Installing dependencies. This could take a few minutes',
title: initMsg.install,
task: async () => {
await installingDepsPromise;
},
Expand All @@ -272,12 +279,17 @@ export async function setupLocalStarterTemplate(
showShortcutBanner();
}

renderSuccess({
headline: [
{userInput: storefrontInfo?.title ?? project.name},
'is ready to build.',
],
});
// If running in --quickstart mode, skip this success banner
if (options.quickstart) {
console.log('\n');
} else {
renderSuccess({
headline: [
{userInput: storefrontInfo?.title ?? project.name},
'is ready to build.',
],
});
}

const continueWithSetup =
(options.i18n ?? options.routes) !== undefined ||
Expand Down

0 comments on commit 5bb4330

Please sign in to comment.