Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
node_modules
yarn.lock
.nyc_output
coverage
.project
71 changes: 32 additions & 39 deletions lib/cli.js
Original file line number Diff line number Diff line change
@@ -1,39 +1,28 @@
#!/usr/bin/env node
'use strict';
const fs = require('fs');
const path = require('path');
const chalk = require('chalk');
const updateNotifier = require('update-notifier');
const yosay = require('yosay');
const stringLength = require('string-length');
const rootCheck = require('root-check');
const meow = require('meow');
const list = require('cli-list');
const Tabtab = require('tabtab');
const pkg = require('../package.json');
const Router = require('./router');

import fs from 'node:fs';
import path from 'node:path';
import chalk from 'chalk';
import updateNotifier from 'update-notifier';
import yosay from 'yosay';
import stringLength from 'string-length';
import rootCheck from 'root-check';
import meow from 'meow';
import list from 'cli-list';
import tabtab from './completion/tabtab.cjs';
import pkg from './utils/project-package.js';
import Router from './router.js';
import {bootstrap} from 'global-agent';
import * as routes from './routes/index.js';
import {getDirname} from './utils/node-shims.js';

const __dirname = getDirname(import.meta.url);
const gens = list(process.argv.slice(2));

// Override http networking to go through a proxy ifone is configured
const MAJOR_NODEJS_VERSION = Number.parseInt(process.version.slice(1).split('.')[0], 10);

if (MAJOR_NODEJS_VERSION >= 10) {
// `global-agent` works with Node.js v10 and above.
require('global-agent').bootstrap();
} else {
// `global-tunnel-ng` works only with Node.js v10 and below.
require('global-tunnel-ng').initialize();
}

/* eslint new-cap: 0, no-extra-parens: 0 */
const tabtab = new Tabtab.Commands.default({
name: 'yo',
completer: 'yo-complete'
});
bootstrap();

const cli = gens.map(gen => {
const minicli = meow({autoHelp: false, autoVersion: true, pkg, argv: gen});
const minicli = meow({autoHelp: false, autoVersion: true, pkg, argv: gen, importMeta: import.meta});
const options = minicli.flags;
const args = minicli.input;

Expand Down Expand Up @@ -66,7 +55,9 @@ function updateCheck() {
async function pre() {
// Debugging helper
if (cmd === 'doctor') {
require('yeoman-doctor')();
// eslint-disable-next-line node/no-unsupported-features/es-syntax
const yeomanDoctor = (await import('yeoman-doctor')).default;
yeomanDoctor();
return;
}

Expand All @@ -76,7 +67,9 @@ async function pre() {

// Easteregg
if (cmd === 'yeoman' || cmd === 'yo') {
console.log(require('yeoman-character'));
// eslint-disable-next-line node/no-unsupported-features/es-syntax
const yeomanCharacter = (await import('yeoman-character')).default;
console.log(yeomanCharacter);
return;
}

Expand Down Expand Up @@ -171,13 +164,13 @@ async function init() {

function runYo(env) {
const router = new Router(env);
router.registerRoute('help', require('./routes/help'));
router.registerRoute('update', require('./routes/update'));
router.registerRoute('run', require('./routes/run'));
router.registerRoute('install', require('./routes/install'));
router.registerRoute('exit', require('./routes/exit'));
router.registerRoute('clearConfig', require('./routes/clear-config'));
router.registerRoute('home', require('./routes/home'));
router.registerRoute('help', routes.help);
router.registerRoute('update', routes.update);
router.registerRoute('run', routes.run);
router.registerRoute('install', routes.install);
router.registerRoute('exit', routes.exit);
router.registerRoute('clearConfig', routes.clearConfig);
router.registerRoute('home', routes.home);

process.once('exit', router.navigate.bind(router, 'exit'));

Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion lib/completion/index.js → lib/completion/index.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const tabtab = require('tabtab')({
name: 'yo',
cache: !process.env.YO_TEST
});
const Completer = require('./completer');
const Completer = require('./completer.cjs');

(async () => {
// eslint-disable-next-line node/no-unsupported-features/es-syntax
Expand Down
10 changes: 10 additions & 0 deletions lib/completion/tabtab.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const Tabtab = require('tabtab');

// eslint-disable-next-line new-cap
const tabtab = new Tabtab.Commands.default({
name: 'yo',
completer: 'yo-complete',
cache: false
});

module.exports = tabtab;
20 changes: 9 additions & 11 deletions lib/router.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
'use strict';
const path = require('path');
const titleize = require('titleize');
const humanizeString = require('humanize-string');
const readPkgUp = require('read-pkg-up');
const updateNotifier = require('update-notifier');
const Configstore = require('configstore');
const {namespaceToName} = require('./utils/namespace');
import path from 'path';
import titleize from 'titleize';
import humanizeString from 'humanize-string';
import readPkgUp from 'read-pkg-up';
import updateNotifier from 'update-notifier';
import Configstore from 'configstore';
import {namespaceToName} from './utils/namespace.js';
import pkg from './utils/project-package.js';

/**
* The router is in charge of handling `yo` different screens.
* @constructor
* @param {Environment} env A yeoman environment instance
* @param {Configstore} [conf] An optional config store instance
*/
class Router {
export default class Router {
constructor(env, conf) {
const pkg = require('../package.json');
this.routes = {};
this.env = env;
this.conf = conf || new Configstore(pkg.name, {
Expand Down Expand Up @@ -83,5 +83,3 @@ class Router {
}
}
}

module.exports = Router;
12 changes: 6 additions & 6 deletions lib/routes/clear-config.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
'use strict';
const _ = require('lodash');
const chalk = require('chalk');
const inquirer = require('inquirer');
const globalConfig = require('../utils/global-config');
const {namespaceToName} = require('../utils/namespace');
import _ from 'lodash';
import chalk from 'chalk';
import inquirer from 'inquirer';
import globalConfig from '../utils/global-config.js';
import {namespaceToName} from '../utils/namespace.js';

module.exports = async app => {
export const clearConfig = async app => {
const defaultChoices = [
{
name: 'Take me back home, Yo!',
Expand Down
4 changes: 2 additions & 2 deletions lib/routes/exit.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict';
const yosay = require('yosay');
import yosay from 'yosay';

module.exports = async () => {
export const exit = async () => {
const PADDING = 5;
const url = 'http://yeoman.io';
const maxLength = url.length + PADDING;
Expand Down
6 changes: 3 additions & 3 deletions lib/routes/help.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
'use strict';
const inquirer = require('inquirer');
const open = require('open');
import inquirer from 'inquirer';
import open from 'open';

module.exports = async app => {
export const help = async app => {
return inquirer.prompt([{
name: 'whereTo',
type: 'list',
Expand Down
19 changes: 9 additions & 10 deletions lib/routes/home.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
'use strict';
const _ = require('lodash');
const chalk = require('chalk');
const fullname = require('fullname');
const inquirer = require('inquirer');
const {isString} = require('lodash');
const {namespaceToName} = require('../utils/namespace');
const globalConfigHasContent = require('../utils/global-config').hasContent;
import _ from 'lodash';
import chalk from 'chalk';
import fullname from 'fullname';
import inquirer from 'inquirer';
import {namespaceToName} from '../utils/namespace.js';
import globalConfig from '../utils/global-config.js';

module.exports = async app => {
export const home = async app => {
const defaultChoices = [{
name: 'Install a generator',
value: 'install'
Expand All @@ -19,7 +18,7 @@ module.exports = async app => {
value: 'exit'
}];

if (globalConfigHasContent()) {
if (globalConfig.hasContent()) {
defaultChoices.splice(-1, 0, {
name: 'Clear global config',
value: 'clearConfig'
Expand Down Expand Up @@ -53,7 +52,7 @@ module.exports = async app => {
}

return fullname().then(name => {
const allo = (name && isString(name)) ? `'Allo ${name.split(' ')[0]}! ` : '\'Allo! ';
const allo = (name && _.isString(name)) ? `'Allo ${name.split(' ')[0]}! ` : '\'Allo! ';

return inquirer.prompt([{
name: 'whatNext',
Expand Down
7 changes: 7 additions & 0 deletions lib/routes/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export {clearConfig} from './clear-config.js';
export {exit} from './exit.js';
export {help} from './help.js';
export {home} from './home.js';
export {install} from './install.js';
export {run} from './run.js';
export {update} from './update.js';
23 changes: 12 additions & 11 deletions lib/routes/install.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
'use strict';
const _ = require('lodash');
const async = require('async');
const chalk = require('chalk');
const inquirer = require('inquirer');
const spawn = require('cross-spawn');
const sortOn = require('sort-on');
const figures = require('figures');
const npmKeyword = require('npm-keyword');
const packageJson = require('package-json');
const got = require('got');

import _ from 'lodash';
import async from 'async';
import chalk from 'chalk';
import inquirer from 'inquirer';
import spawn from 'cross-spawn';
import sortOn from 'sort-on';
import figures from 'figures';
import npmKeyword from 'npm-keyword';
import packageJson from 'package-json';
import got from 'got';

const OFFICIAL_GENERATORS = new Set([
'generator-angular',
Expand All @@ -30,7 +31,7 @@ const OFFICIAL_GENERATORS = new Set([
'generator-webapp'
]);

module.exports = app => {
export const install = app => {
return inquirer.prompt([{
name: 'searchTerm',
message: 'Search npm for generators:'
Expand Down
6 changes: 3 additions & 3 deletions lib/routes/run.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
'use strict';
const chalk = require('chalk');
const {namespaceToName} = require('../utils/namespace');
import chalk from 'chalk';
import {namespaceToName} from '../utils/namespace.js';

module.exports = async (app, name) => {
export const run = async (app, name) => {
const baseName = namespaceToName(name);

console.log(
Expand Down
8 changes: 4 additions & 4 deletions lib/routes/update.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict';
const chalk = require('chalk');
const inquirer = require('inquirer');
const spawn = require('cross-spawn');
import chalk from 'chalk';
import inquirer from 'inquirer';
import spawn from 'cross-spawn';

const successMessage = 'I\'ve just updated your generators. Remember, you can update\na specific generator with npm by running:\n' +
chalk.magenta('\n npm install -g generator-_______');
Expand All @@ -18,7 +18,7 @@ function updateGenerators(app, pkgs) {
.on('close', updateSuccess.bind(null, app));
}

module.exports = app => {
export const update = app => {
return inquirer.prompt([{
name: 'generators',
message: 'Generators to update',
Expand Down
10 changes: 6 additions & 4 deletions lib/utils/global-config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict';
const fs = require('fs');
const path = require('path');
const os = require('os');
import fs from 'node:fs';
import path from 'node:path';
import os from 'node:os';

// Path to the config file
const globalConfigPath = path.join(os.homedir(), '.yo-rc-global.json');
Expand Down Expand Up @@ -52,10 +52,12 @@ function hasContent() {
return Object.keys(getAll()).length > 0;
}

module.exports = {
const globalConfig = {
getAll,
remove,
removeAll,
hasContent,
path: globalConfigPath
};

export default globalConfig;
6 changes: 1 addition & 5 deletions lib/utils/namespace.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
function namespaceToName(namespace) {
export function namespaceToName(namespace) {
return namespace.split(':')[0];
}

module.exports = {
namespaceToName
};
14 changes: 14 additions & 0 deletions lib/utils/node-shims.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import {fileURLToPath} from 'url';
import path from 'path';

/**
* Returns the __dirname when provided import.meta.url.
*
* __dirname is not available in ESM, and import.meta.dirname is only available in Node 20.11.0+.
*
* @param fileUrl (typically import.meta.url)
* @returns __dirname
*/
export const getDirname = fileUrl => {
return path.dirname(fileURLToPath(fileUrl));
};
6 changes: 6 additions & 0 deletions lib/utils/project-package.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Directly requiring package.json is not supported in ESM
// and JSON imports are still experimental in Node.
// This is the workaround.
import {createRequire} from 'module';
const require = createRequire(import.meta.url);
export default require('../../package.json');
Loading
Loading