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

Merge pre-existing package.json with file generated by Cloverfield #40

Open
wants to merge 13 commits into
base: master
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
3 changes: 2 additions & 1 deletion .babelrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{
"presets": ["es2015"]
"presets": ["es2015"],
"plugins": ["transform-object-rest-spread"]
}
11 changes: 8 additions & 3 deletions lib/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,21 @@ import {parse} from 'nomnom';
import glob from 'glob';
import parseProps from './parseProps';
import generate from './generate';
import setPackageProps from './packageExtras';
import {getPackage, getPackageProps, mergePackages} from './mergePack';
import fs from 'fs';
import mkdirp from 'mkdirp';
import path from 'path';
import {properties, defaults} from './properties';
import {packageProperties, properties, defaults} from './properties';
import {
blackBright as grey,
greenBright as green,
yellowBright as yellow,
redBright as red} from 'cli-color';

const schema = {properties};

let schema = {properties};
const existingPackage = getPackage();
schema = getPackageProps(existingPackage, packageProperties, schema);

Object.assign(prompt, {
message: '>'.green,
Expand Down Expand Up @@ -56,8 +59,10 @@ const scaffold = args => {
prompt.override = args;

getPrompt()
.then(setPackageProps(existingPackage))
.then(parseProps(defaults))
.then(generate(srcContent))
.then(mergePackages(getPackage(), destinations))
.then(saveCompiled)
.then(() => {
console.log(green('OK'), 'Generation completed', '\n');
Expand Down
51 changes: 51 additions & 0 deletions lib/mergePack.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import fs from 'fs';
import path from 'path';
import merge from 'lodash.merge';
import parseAuthor from 'parse-author';
import parseGithub from 'parse-github-url';

export const getPackage = () => {
let origPackage;
try {
origPackage = JSON.parse(fs.readFileSync(path.join(process.cwd(), 'package.json'), 'utf-8'));
} catch (e) {
origPackage = false;
}
return origPackage;
};

export const getPackageProps = (existingPackage, packageProperties, schema) => {
let gitHub, authorInfo;
if (existingPackage) {
console.log(`Existing package.json file has been used to get default variables.`);
schema.properties = {...schema.properties, ...packageProperties};
schema.properties['package.name'].default = existingPackage.name;
schema.properties['package.description'].default = existingPackage.description;
// Try to get Name, Email & GitHub Username
if (existingPackage.repository && existingPackage.repository.url) {
gitHub = parseGithub(existingPackage.repository.url).owner;
schema.properties['user.github'].default = gitHub;
}
if (existingPackage.author) {
authorInfo = parseAuthor(existingPackage.author);
if (authorInfo.name) {
schema.properties['user.name'].default = authorInfo.name;
}
if (authorInfo.email) {
schema.properties['user.email'].default = authorInfo.email;
}
}
}
return schema;
};

export const mergePackages = (origPackage, destinations) => compiledFiles => {
if (origPackage) {
const newPackagePath = path.join(process.cwd(), 'package.json');
const packageIndex = destinations.indexOf(newPackagePath);
const packageContents = JSON.parse(compiledFiles[packageIndex]);
const mergedPack = JSON.stringify(merge(packageContents, origPackage), null, 2);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've tried it several times and tried to fix it too... No luck. With current implmentation no matter what I chose deps/devdeps/scrips are preserved and never updated. If I swap packageContents and origPackage - they always updated instead. Somehow those props from setPackageProps are just totally ignored =(

compiledFiles[packageIndex] = mergedPack;
}
return compiledFiles;
};
16 changes: 16 additions & 0 deletions lib/packageExtras.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import templatePackage from '../template/package.json';

const packageFields = ['dependencies', 'devDependencies', 'scripts'];

const setPackageProps = userPackage => props => {
packageFields.forEach((field) => {
if (props[`package.${field}`]) {
props[`package.${field}`] = {...templatePackage[field], ...userPackage[field]};
} else {
props[`package.${field}`] = {...templatePackage[field]};
}
});
return props;
};

export default setPackageProps;
26 changes: 25 additions & 1 deletion lib/properties.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,31 @@ export const defaults = {
},
package: {
name: '',
description: ''
description: '',
dependencies: {},
devDependencies: {},
scripts: {}
}
};

export const packageProperties = {
'package.dependencies': {
description: 'Keep existing dependencies? (true|false): ',
message: 'Required',
type: 'boolean',
required: true
},
'package.devDependencies': {
description: 'Keep existing devDependencies? (true|false): ',
message: 'Required',
type: 'boolean',
required: true
},
'package.scripts': {
description: 'Keep existing scripts? (true|false): ',
message: 'Required',
type: 'boolean',
required: true
}
};

Expand Down
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,18 +45,22 @@
"cli-color": "^1.0.0",
"glob": "^5.0.14",
"handlebars": "^4.0.0",
"lodash.merge": "^3.3.2",
"mkdirp": "^0.5.1",
"nomnom": "^1.8.1",
"prompt": "^0.2.14"
},
"devDependencies": {
"babel-eslint": "^4.1.1",
"babel-plugin-transform-object-rest-spread": "^6.5.0",
"blue-tape": "^0.1.10",
"eslint": "^1.3.1",
"faucet": "0.0.1",
"husky": "^0.10.1",
"isparta": "^3.0.4",
"nsp": "^2.0.2",
"parse-author": "^0.2.0",
"parse-github-url": "^0.3.0",
"rimraf": "^2.4.3",
"sinon": "^1.16.1",
"tap-xunit": "^1.1.1"
Expand Down
4 changes: 2 additions & 2 deletions template/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@
"precommit": "npm run lint",
"prepush": "npm run validate"
},
"devDependencies": {
"devDependencies": {
"babel-cli": "^6.2.0",
"babel-core": "^6.0.0",
"babel-preset-es2015": "^6.1.18",
"babel-preset-stage-1":"^6.0.0",
"babel-preset-stage-1": "^6.0.0",
"babel-eslint": "^4.0.5",
"babel-loader": "^6.0.0",
"babel-plugin-transform-object-assign": "^6.1.18",
Expand Down
51 changes: 51 additions & 0 deletions test/lib/mergePack-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import {test} from 'blue-tape';
import {mergePackages} from '../../lib/mergePack';
import path from 'path';

test('Merge Packages', t => {

const packPath = path.join(process.cwd(), 'package.json');
const templatedFile = JSON.stringify({
name: 'templatePackage',
description: 'This should not overwrite stuff',
main: 'src/index.js',
scripts: {
start: 'do a lotta new stuff',
test: 'mocha this package'
}
});
const originalFile = {
name: 'originalPackage',
description: 'This should not be overwritten by a template',
scripts: {
start: 'do a lotta old stuff',
lint: 'lint this package'
}
};
const mergedFile = {
name: 'originalPackage',
description: 'This should not be overwritten by a template',
main: 'src/index.js',
scripts: {
start: 'do a lotta old stuff',
lint: 'lint this package',
test: 'mocha this package'
}
};

t.ok(mergePackages instanceof Function, 'should be function');

t.ok(mergePackages() instanceof Function, 'should return function');

t.deepEqual(mergePackages(false, [packPath])([templatedFile]), [templatedFile],
'should return the generated package when there is no pre-existing package.json');

const merger = mergePackages(originalFile, [packPath])([templatedFile])[0];

t.deepEqual(JSON.parse(merger), mergedFile,
'should merge an existing package.json with template and return results');

t.ok(merger.match(/\s\s/), 'merged package should be formatted with spaces');

t.end();
});