Skip to content
Merged
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
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