Skip to content

Commit

Permalink
Address author prompt from object
Browse files Browse the repository at this point in the history
This resolves the situation where an existing package.json has an
author field, but it is an object instead of a string. In this case,
the prompt is skipped.

Also includes some code cleanup that doesn't change behavior in any way.
  • Loading branch information
misteroneill committed Jan 11, 2016
1 parent 15f2823 commit 55b4fdf
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 90 deletions.
10 changes: 10 additions & 0 deletions fixtures/author/package.json
@@ -0,0 +1,10 @@
{
"name": "videojs-author-fixture",
"description": "This is a fixture to test the handling of an author object.",
"author": {
"name": "John Doe",
"email": "john@doe.com"
},
"license": "MIT",
"version": "1.0.0"
}
3 changes: 2 additions & 1 deletion package.json
Expand Up @@ -48,13 +48,14 @@
"npm-run-all": "~1.2.0",
"tap": "^2.3.1",
"tap-parser": "^1.2.2",
"tsml": "^1.0.1",
"tsmlj": "^1.0.0",
"yeoman-generator": "^0.20.0",
"yosay": "^1.0.2"
},
"devDependencies": {
"babel": "^5.8.34",
"doctoc": "^0.15.0",
"fs-extra": "^0.26.4",
"mocha": "^2.3.4",
"videojs-standard": "^4.0.0"
}
Expand Down
170 changes: 82 additions & 88 deletions src/app/index.js
@@ -1,24 +1,22 @@
import _ from 'lodash';
import chalk from 'chalk';
import path from 'path';
import {spawn} from 'child_process';
import tsml from 'tsml';
import tsmlj from 'tsmlj';
import yeoman from 'yeoman-generator';
import yosay from 'yosay';

import packageJSON from './package-json';

const validateName = (input) => {
if (!(/^[a-z][a-z0-9-]+$/).test(input)) {
return tsml`
Names must start with a lower-case letter and cont
ain only lower-case letters (a-z), digits (0-9), a
nd hyphens (-).
return tsmlj`
Names must start with a lower-case letter and contain
only lower-case letters (a-z), digits (0-9), and hyphens (-).
`;
} else if (_.startsWith(input, 'videojs-')) {
return tsml`
Plugins cannot start with "videojs-"; it will auto
matically be prepended!
return tsmlj`
Plugins cannot start with "videojs-"; it will automatically
be prepended!
`;
}
return true;
Expand Down Expand Up @@ -66,9 +64,9 @@ export default yeoman.generators.Base.extend({
*
* @method _getPromptDefaults
* @private
* @param {Function} callback Callback called with author string.
* @return {Object}
*/
_getPromptDefaults(callback) {
_getPromptDefaults() {
let configs = this.config.getAll();
let pkg = this._currentPkgJSON || {};
let licenseNames = this._licenseNames;
Expand All @@ -81,8 +79,6 @@ export default yeoman.generators.Base.extend({
sass: configs.hasOwnProperty('sass') ? configs.sass : false
};

let git;

['author', 'license', 'name', 'description'].forEach(key => {
if (pkg.hasOwnProperty(key)) {
defaults[key] = pkg[key];
Expand All @@ -105,85 +101,81 @@ export default yeoman.generators.Base.extend({
});
}

// If we don't have an author yet, make one last-ditch effort to find
// the author's name with `git config`.
if (!defaults.author) {

// Make sure it's a string, so we can concat without worrying!
defaults.author = '';
let name = this.user.git.name();

git = spawn('git', ['config', 'user.name']);
// Build up an author string from git if possible as a last-ditch effort.
if (!defaults.author && name) {
let email = this.user.git.email();

git.stdout.on('data', chunk => defaults.author += chunk);
defaults.author = name;

git.on('close', () => {
defaults.author = defaults.author.trim();
callback(defaults);
});
} else {
callback(defaults);
if (email) {
defaults.author += ` <${email}>`;
}
}

return defaults;
},

/**
* Gets prompts for the user.
*
* @method _createPrompts
* @private
* @param {Function} callback Callback when prompts array is ready.
* @return {Array}
*/
_createPrompts(callback) {
this._getPromptDefaults(defaults => {
callback([{
name: 'name',
message: tsml`
Enter the name of this plugin (a-z/0-9/- only
; will be prefixed with "videojs-"):
`,
default: defaults.name,
validate: validateName
}, {
name: 'description',
message: 'Enter a description for your plugin:',
default: defaults.description
}, {
name: 'author',
message: 'Enter the author of this plugin:',
default: defaults.author
}, {
type: 'list',
name: 'license',
message: 'Choose a license for your project',
default: defaults.license,
choices: _.map(this._licenseNames, (v, k) => {
return {name: v, value: k};
})
}, {
type: 'confirm',
name: 'sass',
message: 'Do you want to include Sass styling?',
default: defaults.sass
}, {
type: 'confirm',
name: 'docs',
message: 'Do you want to include documentation tooling?',
default: defaults.docs
}, {
type: 'confirm',
name: 'lang',
message: tsml`
Do you need video.js language file infrastructure for internat
ionalized strings?
`,
default: defaults.lang
}, {
type: 'confirm',
name: 'bower',
message: 'Do you want to support Bower (adds special versioning handling)?',
default: defaults.bower
}].filter(prompt => !_.contains(this._promptsToFilter, prompt.name)));
});
_getPrompts() {
let defaults = this._getPromptDefaults(defaults);
let prompts = [{
name: 'name',
message: tsmlj`
Enter the name of this plugin (a-z/0-9/- only; will be
prefixed with "videojs-"):
`,
default: defaults.name,
validate: validateName
}, {
name: 'description',
message: 'Enter a description for your plugin:',
default: defaults.description
}, {
name: 'author',
message: 'Enter the author of this plugin:',
default: defaults.author
}, {
type: 'list',
name: 'license',
message: 'Choose a license for your project',
default: defaults.license,
choices: _.map(this._licenseNames, (v, k) => {
return {name: v, value: k};
})
}, {
type: 'confirm',
name: 'sass',
message: 'Do you want to include Sass styling?',
default: defaults.sass
}, {
type: 'confirm',
name: 'docs',
message: 'Do you want to include documentation tooling?',
default: defaults.docs
}, {
type: 'confirm',
name: 'lang',
message: tsmlj`
Do you need video.js language file infrastructure for
internationalized strings?
`,
default: defaults.lang
}, {
type: 'confirm',
name: 'bower',
message: 'Do you want to support Bower (adds special versioning handling)?',
default: defaults.bower
}];

return prompts.filter(p => !_.contains(this._promptsToFilter, p.name));
},

/**
Expand Down Expand Up @@ -268,6 +260,12 @@ export default yeoman.generators.Base.extend({
// Brightcove plugins are either Apache-2.0 or private/closed-source.
this._licenseNames = _.pick(this._licenseNames, 'apache2', 'private');
this._licenseDefault = 'apache2';

// Make sure we filter out the author prompt if there is a current
// package.json file with an object for the author field.
} else if (this._currentPkgJSON && _.isPlainObject(this._currentPkgJSON.author)) {
this._promptsToFilter.push('author');
this._configsTemp.author = this._currentPkgJSON.author;
}
},

Expand All @@ -281,17 +279,13 @@ export default yeoman.generators.Base.extend({
return;
}

this.log(yosay(tsml`
Welcome to the ${chalk.red('videojs-plugin')} generator!
`));
this.log(yosay(`Welcome to the ${chalk.red('videojs-plugin')} generator!`));

let done = this.async();

this._createPrompts(prompts => {
this.prompt(prompts, responses => {
_.assign(this._configsTemp, responses);
done();
});
this.prompt(this._getPrompts(), responses => {
_.assign(this._configsTemp, responses);
done();
});
},

Expand Down Expand Up @@ -427,7 +421,7 @@ export default yeoman.generators.Base.extend({
if (this.options.hurry) {
return;
}
this.log(yosay(tsml`
this.log(yosay(tsmlj`
All done; ${chalk.red(this.context.nameOf.package)} is ready to go!
`));
}
Expand Down
38 changes: 37 additions & 1 deletion src/test/app.test.js
@@ -1,6 +1,8 @@
/* global before, describe, it */

import _ from 'lodash';
import fs from 'fs-extra';
import path from 'path';
import {assert, test as helpers} from 'yeoman-generator';

import * as libs from './libs';
Expand Down Expand Up @@ -142,6 +144,41 @@ describe('videojs-plugin:app', function() {
});
});

describe('existing package.json with author object', function() {

before(function(done) {
helpers.run(libs.GENERATOR_PATH)
.inTmpDir(function(dir) {
fs.copySync(path.join(__dirname, '../fixtures/author'), dir);
})
.withOptions(libs.options({force: true}))
.withPrompts({
name: 'nomen',
author: 'ignore me',
description: 'it is a plugin'
})
.on('end', libs.onEnd.bind(this, done));
});

it('does not change the value of the author field', function() {
let author = this.pkg.author;

assert.ok(_.isPlainObject(author), 'the author is still an object');

assert.strictEqual(
author.name,
'John Doe',
'the author\'s name is correct'
);

assert.strictEqual(
author.email,
'john@doe.com',
'the author\'s email is correct'
);
});
});

describe('package.json merging', function() {
let result = packageJSON({
a: 1,
Expand Down Expand Up @@ -196,4 +233,3 @@ describe('videojs-plugin:app', function() {
});
});
});

0 comments on commit 55b4fdf

Please sign in to comment.