Skip to content
This repository has been archived by the owner on Aug 5, 2020. It is now read-only.

Project presets support #1009

Open
wants to merge 15 commits into
base: develop
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions packages/gluestick-cli/src/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ commander
.command('new')
.description('generate a new application')
.arguments('<appName>')
.option('-p, --preset <preset>', 'specify preset to create project from')
.option('-d, --dev <path>', 'relative path to development version of gluestick')
.option('-s, --skip-main', 'gluestick will not generate main app')
.option('-n, --npm', 'use npm instead of yarn')
Expand Down
79 changes: 53 additions & 26 deletions packages/gluestick-cli/src/new.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,35 +9,49 @@ const generate = require('gluestick-generators').default;
const fetch = require('node-fetch');
const rimraf = require('rimraf');

const ensureDevelopmentPathIsValid = (pathToGluestickRepo, exitWithError) => {
let gluestickPackage = {};
try {
gluestickPackage = require(path.join(pathToGluestickRepo, 'package.json'));
} catch (error) {
exitWithError(
`Development GlueStick path ${pathToGluestickRepo} is not valid`,
);
}
if (gluestickPackage.name !== 'gluestick-packages') {
exitWithError(
`${pathToGluestickRepo} is not a path to GlueStick`,
);
}
};

const getDevelopmentDependencies = ({ dev }, pathToGluestickPackages) => {
return glob.sync('*', { cwd: pathToGluestickPackages })
.filter(name => name !== 'gluestick-cli')
.reduce((acc, key) => {
return { ...acc, [key]: `file:${path.join('..', dev, 'packages', key)}` };
}, {});
};

module.exports = (appName, options, exitWithError) => {
fetch('http://registry.npmjs.org/gluestick')
.then(res => res.json())
.then(json => {
const packageDeps = {
dependencies: {
gluestick: json['dist-tags'].latest,
},
const preset = options.preset || 'default';
const api = 'http://registry.npmjs.org';
Promise.all([
fetch(`${api}/gluestick`),
fetch(`${api}/gluestick-preset-${preset}`),
]).then(responses => Promise.all(responses.map(res => res.json())))
.then(payloads => {
const latestGluestickVersion = payloads[0]['dist-tags'].latest;
const presetDependencies = payloads[1].versions[latestGluestickVersion].gsProjectDependencies;
let gluestickDependencies = {
gluestick: latestGluestickVersion,
};

if (options.dev) {
const pathToGluestickRepo = path.join(process.cwd(), appName, '..', options.dev);
const pathToGluestickPackages = path.join(pathToGluestickRepo, 'packages');
let gluestickPackage = {};
const packages = glob.sync('*', { cwd: pathToGluestickPackages }).filter((e) => e !== 'gluestick-cli');
try {
gluestickPackage = require(path.join(pathToGluestickRepo, 'package.json'));
} catch (error) {
exitWithError(
`Development GlueStick path ${pathToGluestickRepo} is not valid`,
);
}
if (gluestickPackage.name !== 'gluestick-packages') {
exitWithError(
`${pathToGluestickRepo} is not a path to GlueStick`,
);
}
packages.forEach(e => {
packageDeps.dependencies[e] = `file:${path.join('..', options.dev, 'packages', e)}`;
});
ensureDevelopmentPathIsValid(pathToGluestickRepo, exitWithError);
gluestickDependencies = getDevelopmentDependencies(options, pathToGluestickPackages);
}

const pathToApp = path.join(process.cwd(), appName);
Expand All @@ -50,18 +64,24 @@ module.exports = (appName, options, exitWithError) => {
mkdir.sync(path.join(process.cwd(), appName));

const generatorOptions = {
gluestickDependencies: packageDeps.dependencies,
appName,
preset,
gluestickDependencies,
presetDependencies,
};

process.chdir(appName);
try {
generate(
{
generatorName: 'package',
generatorName: 'packageJson',
entityName: 'package',
options: generatorOptions,
},
undefined,
{
successMessageHandler: () => {},
},
);

const isYarnAvailable = !spawn.sync('yarn', ['-V']).error;
Expand Down Expand Up @@ -100,5 +120,12 @@ module.exports = (appName, options, exitWithError) => {
console.error(error);
process.exit(1);
}
})
.catch(error => {
console.error(chalk.red(error.message));
console.error('This error may occur due to the following reasons:');
console.error(` -> Cannot connect or make request to '${api}'`);
console.error(' -> Specified preset was not found');
process.exit(1);
});
};
58 changes: 58 additions & 0 deletions packages/gluestick-generators/src/generators/packageJson.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/* DO NOT MODIFY */
const createTemplate = module.parent.createTemplate;
/* END OF DO NOT MODIFY */

const dependenciesToJson = dependencies => (acc, key, index, array) => {
return acc.concat(
`"${key}": "${dependencies[key]}"${index === array.length - 1 ? '' : ',\n '}`,
);
};

const templatePackage = createTemplate`
{
"name": "${args => args.appName}",
"version": "1.0.0",
"description": "",
"main": "index.js",
"preset": "${args => args.preset}",
"scripts": {
"start": "gluestick start",
"test": "gluestick test",
"flow": "flow",
"lint": "eslint src"
},
"dependencies": {
${args => Object.keys(args.dependencies).reduce(dependenciesToJson(args.dependencies), '')}
},
"devDependencies": {
${args => Object.keys(args.devDependencies).reduce(dependenciesToJson(args.devDependencies), '')}
},
"author": "",
"license": "ISC"
}
`;

const reverseGluestickDependencies = dependencies => {
return Object.keys(dependencies).reverse().reduce((acc, key) => {
return { ...acc, [key]: dependencies[key] };
}, {});
};

module.exports = ({ appName, preset, gluestickDependencies, presetDependencies }) => ({
entries: [
{
path: '/',
filename: 'package.json',
template: templatePackage,
args: {
appName,
preset,
dependencies: {
...reverseGluestickDependencies(gluestickDependencies),
...presetDependencies.dependencies,
},
devDependencies: presetDependencies.devDependencies,
},
},
],
});
7 changes: 2 additions & 5 deletions packages/gluestick-generators/src/requireGenerator.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@ const { convertToCamelCase, convertToKebabCase } = require('./utils');
// $FlowFixMe
module.createTemplate = createTemplate;

const PATH_TO_GLUESTICK_TEMPLATES: string = '../../build/generator/predefined';
const PATH_TO_GLUESTICK_CLI_TEMPLATES: string = '../templates';
const PATH_TO_GLUESTICK_TEMPLATES: string = '../../build/generators/predefined';
const EXTERNAL: string = 'generators';
const INTERNAL: string = './templates';
const INTERNAL: string = './generators';

const safeResolve = (moduleToResolve: string, ...args: string[]): string => {
try {
Expand All @@ -27,8 +26,6 @@ const getPossiblePaths = (generatorName: string): string[] => {
path.join(process.cwd(), `${EXTERNAL}/${convertToKebabCase(generatorName)}.js`),
safeResolve('gluestick', PATH_TO_GLUESTICK_TEMPLATES, `${convertToCamelCase(generatorName)}.js`),
safeResolve('gluestick', PATH_TO_GLUESTICK_TEMPLATES, `${convertToKebabCase(generatorName)}.js`),
safeResolve('gluestick-cli', PATH_TO_GLUESTICK_CLI_TEMPLATES, `${convertToCamelCase(generatorName)}.js`),
safeResolve('gluestick-cli', PATH_TO_GLUESTICK_CLI_TEMPLATES, `${convertToKebabCase(generatorName)}.js`),
path.join(__dirname, INTERNAL, `${convertToCamelCase(generatorName)}.js`),
path.join(__dirname, INTERNAL, `${convertToKebabCase(generatorName)}.js`),
];
Expand Down
83 changes: 0 additions & 83 deletions packages/gluestick-generators/src/templates/package.js

This file was deleted.

13 changes: 13 additions & 0 deletions packages/gluestick-preset-default/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"presets": [
["env", {
"targets": {
"node": 6.3
}
}],
"stage-0"
],
"plugins": [
"transform-flow-strip-types"
]
}
5 changes: 5 additions & 0 deletions packages/gluestick-preset-default/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
**/__mocks__/**
**/__tests__/**
src/**
coverage/**
.babelrc
Loading