Skip to content

Commit

Permalink
feature/issue 1253 add initial directory option for init scaffolding (#…
Browse files Browse the repository at this point in the history
…1280)

* add optional project name flag to init scaffolding

* update init documentation to promote my-app option

* produce a .npmrc file for npm projects

* improve next step console logs

* clean up errant characters

* add npm run dev script to init package.json

* fix linting
  • Loading branch information
thescientist13 committed Nov 2, 2024
1 parent 1205b86 commit 29a117d
Show file tree
Hide file tree
Showing 14 changed files with 143 additions and 37 deletions.
4 changes: 3 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
**/node_modules/**
!.eslintrc.cjs
!.mocharc.js
packages/init/src/template/src/**/*.js
packages/init/src/template/**
packages/init/test/cases/**/output/**
packages/init/test/cases/**/my-app/**
packages/plugin-babel/test/cases/**/*main.js
TODO.md
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
coverage/
node_modules/
packages/init/test/**/my-app
packages/init/test/**/output
packages/**/test/**/yarn.lock
packages/**/test/**/package-lock.json
packages/**/test/**/netlify
Expand Down
26 changes: 19 additions & 7 deletions packages/init/README.md
Original file line number Diff line number Diff line change
@@ -1,29 +1,41 @@
# @greenwood/init

## Overview

Init package for scaffolding out a new Greenwood project. For more information and complete docs, please visit the [Greenwood website](https://www.greenwoodjs.io/docs).

## Usage

Create a directory and then run the `init` command to scaffold a minimal Greenwood project.
Run the `init` command to scaffold a minimal Greenwood project into a directory of your choosing.

```bash
mkdir my-app && cd my-app
npx @greenwood/init@latest
# providing an output directory of my-app
npx @greenwood/init@latest my-app
```

This will then output the following
This will then output your project files into a directory called _my-app_
```bash
├── greenwood.config.js
my-app
├── .gitignore
├── greenwood.config.js
├── package.json
└── src/
└─ pages/
└─ index.md
└─ ...
```

## API

### Project Name

By providing a name as the first argument, the `init` command will output the project files into a directory of the same name and configure the `name` property _package.json_.

```bash
# example
npx @greenwood/init@latest my-app
```

> _Omitting my-app will install project files into the current directory._
### Template

To scaffold your new project based on one of [Greenwood's starter templates](https://github.com/orgs/ProjectEvergreen/repositories?q=greenwood-template-&type=all&language=&sort=), pass the `--template` flag and then follow the prompts to complete the scaffolding.
Expand Down
38 changes: 32 additions & 6 deletions packages/init/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ const templateStandardName = 'greenwood-template-';
let selectedTemplate = null;
const scriptPkg = JSON.parse(fs.readFileSync(fileURLToPath(new URL('../package.json', import.meta.url)), 'utf-8'));
let templateDir = fileURLToPath(new URL('./template', import.meta.url));
const TARGET_DIR = process.cwd();
let TARGET_DIR = process.cwd();
const clonedTemplateDir = path.join(TARGET_DIR, '.greenwood', '.template');

console.log(`${chalk.rgb(175, 207, 71)('-------------------------------------------------------')}`);
console.log(`${chalk.rgb(175, 207, 71)('Initialize Greenwood Template ♻️')}`);
console.log(`${chalk.rgb(175, 207, 71)('Initialize a Greenwood Project ♻️')}`);
console.log(`${chalk.rgb(175, 207, 71)('-------------------------------------------------------')}`);

const program = new commander.Command(scriptPkg.name)
Expand All @@ -53,7 +53,7 @@ const npmInit = async () => {
const appPkg = JSON.parse(await fs.promises.readFile(path.join(templateDir, '/package.json'), 'utf-8'));

// use installation path's folder name for packages
appPkg.name = path.basename(process.cwd());
appPkg.name = path.basename(TARGET_DIR);

// make sure users get latest and greatest version of Greenwood
// https://github.com/ProjectEvergreen/greenwood/issues/781
Expand All @@ -68,14 +68,20 @@ const npmInit = async () => {

// Copy root and src files to target directory
const srcInit = async () => {
const templateFiles = [];
let templateFiles = [];

await createGitIgnore();

fs.readdirSync(templateDir).forEach(file => {
templateFiles.push(file);
});

if (program.yarn) {
// we only need .npmrc if we're using npm
// because npm struggles with peer dependencies :/
templateFiles = templateFiles.filter(file => file !== '.npmrc');
}

await Promise.all(
templateFiles.map(async file => {
const resolvedPath = path.join(templateDir, file);
Expand Down Expand Up @@ -217,7 +223,7 @@ const listAndSelectTemplate = async () => {
});

if (selectedTemplate) {
console.log('\Installing Selected Template:', selectedTemplate.name);
console.log('Installing Selected Template:', selectedTemplate.name);
}
});
}
Expand Down Expand Up @@ -247,6 +253,20 @@ const cleanUp = async () => {

const run = async () => {
try {
const firstArg = process.argv[process.argv.length - 1].split(' ')[0];
const taskRunner = program.yarn ? 'yarn' : 'npm run';
const shouldChangeDirectory = !firstArg.startsWith('--') && firstArg !== '';

if (!firstArg.startsWith('--') && firstArg !== '') {
TARGET_DIR = path.join(TARGET_DIR, `./${firstArg}`);

if (!fs.existsSync(TARGET_DIR)) {
fs.mkdirSync(TARGET_DIR);
}
}

console.log(`Initializing into project directory... ${TARGET_DIR}`);

if (program.template) {
await listAndSelectTemplate();

Expand All @@ -260,7 +280,7 @@ const run = async () => {
console.log('Initializing project with files...');
await srcInit();

console.log('Creating manifest (package.json)...');
console.log('Creating package.json...');
await npmInit();

if (program.install || program.yarn) {
Expand All @@ -271,6 +291,12 @@ const run = async () => {
await cleanUp();

console.log(`${chalk.rgb(175, 207, 71)('Initializing new project complete!')}`);

if (shouldChangeDirectory) {
console.log(`Change directories by running => cd ${firstArg}`);
}

console.log(`To start developing run => ${taskRunner} dev`);
} catch (err) {
console.error(err);
}
Expand Down
1 change: 1 addition & 0 deletions packages/init/src/template/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
legacy-peer-deps=true
1 change: 1 addition & 0 deletions packages/init/src/template/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"description": "",
"type": "module",
"scripts": {
"dev": "greenwood develop",
"start": "greenwood develop",
"build": "greenwood build",
"serve": "greenwood serve"
Expand Down
5 changes: 0 additions & 5 deletions packages/init/src/template/src/pages/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,6 @@
<html lang="en" prefix="og:http://ogp.me/ns#">
<head>
<title>Greenwood</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<meta name="mobile-web-app-capable" content="yes"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta name="apple-mobile-web-app-status-bar-style" content="black"/>
<link rel="shortcut icon" href="/favicon.ico">
<link rel="icon" href="/favicon.ico">

Expand Down
4 changes: 2 additions & 2 deletions packages/init/test/cases/build.default/build.default.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
* Scaffold from minimal template and run Greenwood build command.
*
* User Result
* Should scaffold from template and run the buildå.
* Should scaffold from template and run the build.
*
* User Command
* @greenwood/init --install && greenwood buildå
* @greenwood/init --install && greenwood build
*
* User Workspace
* N / A
Expand Down
12 changes: 2 additions & 10 deletions packages/init/test/cases/develop.default/develop.default.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,18 +108,10 @@ xdescribe('Scaffold Greenwood and Run Develop command: ', function() {
done();
});

it('should display My Project heading', function(done) {
const heading = dom.window.document.querySelector('body > h2');

expect(heading.textContent).to.equal('My Project');

done();
});

it('should display My Project title', function(done) {
it('should display default project title', function(done) {
const title = dom.window.document.querySelector('head > title');

expect(title.textContent).to.equal('My App');
expect(title.textContent).to.equal('Greenwood');

done();
});
Expand Down
7 changes: 6 additions & 1 deletion packages/init/test/cases/init.default/init.default.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ describe('Scaffold Greenwood With Default Template: ', function() {
expect(fs.existsSync(path.join(outputPath, 'package-lock.json'))).to.be.false;
});

it('should generate a .npmrc file', function() {
expect(fs.existsSync(path.join(outputPath, '.npmrc'))).to.be.true;
});

it('should not generate a yarn.lock file', function() {
expect(fs.existsSync(path.join(outputPath, 'yarn.lock'))).to.be.false;
});
Expand All @@ -77,7 +81,8 @@ describe('Scaffold Greenwood With Default Template: ', function() {
it('the should have the correct Greenwood scripts', function() {
const scripts = pkgJson.scripts;

expect(scripts.start).to.equal('greenwood develop');
expect(scripts.dev).to.equal('greenwood develop');
expect(scripts.start).to.equal(scripts.dev);
expect(scripts.build).to.equal('greenwood build');
expect(scripts.serve).to.equal('greenwood serve');
});
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Use Case
* Scaffold into a custom project directory
*
* User Result
* Should scaffold out the new project into a my-app directory.
*
* User Command
* npx @greenwood/init my-app
*
* User Workspace
* N / A
*/
import chai from 'chai';
import fs from 'fs';
import path from 'path';
import { Runner } from 'gallinago';
import { fileURLToPath, URL } from 'url';

const expect = chai.expect;

describe('Scaffold Greenwood into a custom directory: ', function() {
const initPath = path.join(process.cwd(), 'packages/init/src/index.js');
const outputPath = fileURLToPath(new URL('./output', import.meta.url));
const projectName = 'my-app';
let runner;

before(function() {
this.context = {
publicDir: path.join(outputPath, 'public')
};
runner = new Runner();
});

describe(`Default output to a custom ${projectName} directory`, function () {

before(function() {
runner.setup(outputPath);
runner.runCommand(initPath, `${projectName} --foo=bar`);
});

describe('expected scaffolding output', function () {

it('should create a src/pages directory', function() {
expect(fs.existsSync(path.join(outputPath, projectName, 'src', 'pages'))).to.be.true;
});

it('should generate a .gitignore file', function() {
expect(fs.existsSync(path.join(outputPath, projectName, '.gitignore'))).to.be.true;
});

it('should generate a package.json file', function() {
expect(fs.existsSync(path.join(outputPath, projectName, 'package.json'))).to.be.true;
});

it('should have the name in package.json match the project name argument', function() {
const packageJson = JSON.parse(fs.readFileSync(path.join(outputPath, projectName, 'package.json'), 'utf-8'));

expect(packageJson.name).to.equal(projectName);
});
});

});

after(function() {
runner.teardown([outputPath]);
});

});
4 changes: 4 additions & 0 deletions packages/init/test/cases/init.yarn/init.yarn.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ xdescribe('Scaffold Greenwood With Yarn: ', function() {
expect(fs.existsSync(path.join(outputPath, 'package-lock.json'))).to.be.false;
});

it('should not generate a .npmrc file', function() {
expect(fs.existsSync(path.join(outputPath, '.npmrc'))).to.be.false;
});

it('should generate a public directory', function() {
expect(fs.existsSync(path.join(outputPath, 'public'))).to.be.true;
});
Expand Down
2 changes: 1 addition & 1 deletion www/pages/docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ This is the documentation space for **Greenwood** that we hope will help you get


### Installation
Greenwood can be installed with any of the common package managers available today.
Greenwood can be installed manually with any of the common package managers available today or you scaffold a new project through our [`init` package](/getting-started/quick-start/#init-package).

```bash
# npm
Expand Down
6 changes: 2 additions & 4 deletions www/pages/getting-started/quick-start.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,10 @@ If you want to get right into the code, we have a few options to get you started

### Init Package

You can use Greenwood's [`init` package](https://github.com/ProjectEvergreen/greenwood/blob/master/packages/init/README.md) to scaffold out a new empty Greenwood project, or from a layout.
You can use Greenwood's [`init` package](https://github.com/ProjectEvergreen/greenwood/blob/master/packages/init/README.md) to scaffold out a new empty Greenwood project or use one our template starter kits.

```bash
mkdir my-app && cd my-app

npx @greenwood/init@latest
$ npx @greenwood/init@latest my-app
```

### Command Line
Expand Down

0 comments on commit 29a117d

Please sign in to comment.