Skip to content
This repository has been archived by the owner on May 2, 2024. It is now read-only.
Marcel Kloubert edited this page Jan 30, 2019 · 69 revisions

generator-ego Wiki

This following wiki describes how to use the ego generator for Yeoman.

Table of contents

  1. Additional generators

Additional generators []

Create a yo-ego.js file inside your home directory and use the following skeleton:

// the keys are the display texts, which 
// are shown in the generator's menu
// at the beginning of the execution
exports.generators = {

    'My first generator': async function() {
        // 'this' contains the underlying Generator
        // instance based on: https://github.com/egodigital/generator-ego/blob/master/generators/app/index.js

        this.log(
            'From my 1st generator'
        );
    },

    // path to an external script file
    // 
    // the file must contain a public / exported
    // 'run()' function / method, s. below
    // 
    // relative paths will be mapped to the
    // user's home directory
    'My 2nd generator': 'my-2nd-generator.js',

};

The my-2nd-generator.js can look like that:

exports.run = async function() {
    // 'this' contains the underlying Generator
    // instance based on: https://github.com/egodigital/generator-ego/blob/master/generators/app/index.js
    
    // create a '${HOME}/.generator-ego/my-template' and store all your
    // (template) file there, which should be copied to output
    const TEMPLATES_DIR = this.tools
        .homePath('my-template');

    const NAME_AND_TITLE = await this.tools
        .askForNameAndTitle();
    if (!NAME_AND_TITLE) {
        return;
    }

    const OUT_DIR = NAME_AND_TITLE.mkDestinationDir();

    // copy all files
    this.tools
        .copyAll(TEMPLATES_DIR, OUT_DIR);

    // .gitignore
    /*
        this.tools.createGitIgnore(OUT_DIR, [
            'node_modules/'
        ]);
    */

    // ask for (new) Git repository
    await this.tools
        .askForGitInit(OUT_DIR);

    // ask for open Visual Studio Code
    await this.tools
        .askForOpenVSCode(OUT_DIR);
};

API []

The current sections describes all available namespaces and properties inside a generator's instance:

egoose []

s. @egodigital/egoose

logger []

An instance of a Signale logger.

tools []

The tools namespace contains a look of useful methods, which extends the underlying generator instance. Have a look at tools.js file for more details.

asArray(val, noEmpty) []

Keeps sure a value is an array.

// [ 123 ]
const RES_1 = this.tools.asArray(123);

// [ 11, 33 ]
const RES_2 = this.tools.asArray([11, null, 33]);

// [ 111, null, 333 ]
const RES_3 = this.tools.asArray([111, null, 333], false);

// [ ]
const RES_4 = this.tools.asArray(null);
askForGitInit(dir) []

Asks if a git init should be executed in a specific directory.

await this.tools
          .askForGitInit('/path/where/to/run/git_init');
askForNameAndTitle() []

Asks the user for project name and title.

/**
 * NAME_AND_TITLE:
 *
 * {
 *   "fileName": <'name' property encoded for use as file or folder name>,
 *   "getDestinationDir()": <returns the full path for the projects target directory>,
 *   "mkDestinationDir()": <creates the destination directory for the new project>,
 *   "name": <name in lower case chars>,
 *   "title": <project title>
 * }
 */
const NAME_AND_TITLE =
    await this.tools
              .askForNameAndTitle();
askForOpenVSCode(dir, files) []

Asks the user if Visual Studio Code should be opened for a directory.

const OPTIONAL_FILES_TO_OPEN = [
    '/file_1/to/open',
    '/file_2/to/open'
];

await this.tools
          .askForOpenVSCode('/the/dir/vscode/should/open/after/start',
                            OPTIONAL_FILES_TO_OPEN);
compareValues(x, y) []

Compares two values for sorting.

// -1
const VAL_1 = this.tools.compareValues(5979, 23979);
// 0
const VAL_2 = this.tools.compareValues('5979', '5979');
// 1
const VAL_3 = this.tools.compareValues(23979, 5979);
compareValuesBy(x, y, selector) []

Compares two values for sorting by using a selector.

const OBJ_1 = {
    name: 'TM',
    sortValue: 5979
};
const OBJ_2 = {
    name: 'MK',
    sortValue: 23979
};
const OBJ_3 = {
    name: 'tm',
    sortValue: 5979
};

// -1
const VAL_1 = this.tools.compareValuesBy(
    OBJ_1, OBJ_2,
    obj => obj.sortValue
);
// 0
const VAL_2 = this.tools.compareValuesBy(
    OBJ_1, OBJ_3,
    obj => obj.sortValue
);
// 1
const VAL_3 = this.tools.compareValuesBy(
    OBJ_2, OBJ_1,
    obj => obj.sortValue
);
confirm(message, opts) []

Prompts for a message to confirm.

// Boolean
const IS_SURE = await this.tools.confirm(
    'Are you sure?',
    {
        'default': false
    }
);
copy(from, to, patterns, excludes) []

Copies files from a source to a destination by glob patterns.

const FILES_TO_COPY = [
    '**/*.ts'
];

const FILES_TO_EXCLUDE = [
    '/index.ts'
];

this.tools
    .copy('/source/dir', '/destination/dir',
          FILES_TO_COPY,
          FILES_TO_EXCLUDE);
copyAll() []

Copies all files from a source directory to a destination (with sub elements).

this.tools
    .copyAll('/source/dir', '/destination/dir');
copyREADME(from, to, data) []

Copies an existing README.md file to a destination and renders it as ejs template.

this.tools.copyREADME('/source/dir', '/destination/dir', {
   'var_template_1': 5979,
   'var_template_2': 23979,
});

A template can look like that:

# My README

* `var_template_1`: <%= var_template_1 %>
* `var_template_2`: <%= var_template_2 %>
createEnv(outDir, values) []

Creates an .env file in a specific directory.

this.tools.createEnv('/target/dir', {
    'TM': '1979-09-05',
    'MK': 23091979
});
createGitIgnore(outDir, entries) []

Creates a .gitignore file in a specific directory.

this.tools.createGitIgnore('/target/dir', [
    'node_modules/',
    'dist/**/*'
]);
doesMatch(val, patterns) []

Checks if a string value matches at least one minimatch pattern.

// (true)
const RES_1 = this.tools.doesMatch(
    'index.ts',
    [ '**/*.ts' ]
);

// (false)
const RES_2 = this.tools.doesMatch(
    'index.ts',
    [ '**/*.js' ]
);

// (true)
const RES_3 = this.tools.doesMatch(
    'index.js',
    [ '**/*.ts', '**/*.js' ]
);
download(url) []

Downloads a file from an URL.

const FILE_AS_BUFFER = await this.tools.download(
    'https://e-go-digital.com/site/templates/img/ego_digital_lg_md_sm.svg'
);
downloadGitRepo(repo, dest, opts) []

Downloads a Git repository to a specific directory.

await this.tools.downloadGitRepo(
    'https://github.com/egodigital/generator-ego',
    '/path/to/target',
    {
        'tag': 'some data for the script, can be any kind of JavaScript value'
    }
);

If the repository contains a .yo-ego.js file, the hooks inside there are executed after download.

For that case, you can implement a public downloaded() function

const fs = require('fs');

/**
 * e: {
 *   "dir": <the root directory of the downloaded git repository>
 *   "event": <name of the event that is called: 'downloaded'>
 *   "generator": <the underlying generator instance>
 *   "repository": <the path / url of the downloaded repository>
 *   "tag": <value from 'opts.tag' property of 'downloadGitRepo()' method, if defined>
 * }
 **/
exports.downloaded = async function(e) {
    // 'this' contains the underlying Generator
    // instance based on: https://github.com/egodigital/generator-ego/blob/master/generators/app/index.js

    this.log("Hello from '.yo-ego.js', writing 'test.txt' ...");
    fs.writeFileSync(
        e.dir + '/test.txt',
        `Test from downloaded Git repo: ${ new Date() }`,
        'utf8'
    );
};
encodeHtml(str) []

Encodes a value as string for HTML output.

// "&lt;strong&gt;TM+MK&lt;/strong&gt;"
const ENCODED = this.tools.encodeHtml(
    '<strong>TM+MK</strong>'
);
fromXml(xml, compact) []

Creates a XML object from a string.

s. xml-js for more information.

const XML = this.tools.fromXml(
    '<root>' + 
    '<child_1 />' + 
    '<child_2 tm="5979" mk="23979">' + 
    'TM+MK' + 
    '</child_2>' + 
    '</root>'
);
hasSSHKeys() []

Checks if current user has SSH keys stored inside its home directory.

if (this.tools.hasSSHKeys()) {
    // 'id_rsa' and 'id_rsa.pub'
    // were found in '${HOME}/.ssh'
} else {
    // no keys found
}
homePath(paths) []

Returns a full, joined path relative to the .generator-ego folder, inside the current user's home directory.

// a possible result can be:
// '/home/bgates/.generator-ego/1/Two/3rd'
const FULL_PATH = this.tools.homePath(
    '1', 'Two', '3rd'
);
isDir(path) []

Checks if a path exists and is a directory.

if (this.tools.isDir('/path/to/check')) {
    this.log('Directory');
} else {
    this.log('NO Directory!');
}
isFile(path) []

Checks if a path exists and is a file.

if (this.tools.isFile('/path/to/check')) {
    this.log('File');
} else {
    this.log('NO File!');
}
log() []

Short path to generator's log() function.

this.tools
    .log('Lorem ipsum');
logInteractive(scope, func) []

Invokes a function for log interactivly.

await this.tools.logInteractive('my scope', async (logger) => {
    // 'logger', s. https://www.npmjs.com/package/signale
});
logInteractiveSync(scope, func) []

Invokes a function for log interactivly (synchronously).

this.tools.logInteractiveSync('my scope', (logger) => {
    // 'logger', s. https://www.npmjs.com/package/signale
});
mkDestinationDir(name, throwIfExist) []

Creates a sub folder in the destination directory, especially for use as output directory for the generated project.

const FULL_PATH = this.tools
                      .mkDestinationDir('My sub folder');
prompt() []

Short path to generator's prompt() function.

s. Inquirer.js for more details.

const RESULT = await this.tools.prompt([{
    type: 'input',
    name: 'the_users_name',
    message: 'Whats your name?:',
    validate: (val) => {
        return '' !== String(val).trim();
    }
}]);

const NAME_VALUE = RESULT['the_users_name'];
promptList(message, list, opts) []

Select an item from a list in the console.

const VALUE = await this.tools.promptList(
    'Select a car:',
    [ 'e.GO Life 20', 'e.GO Life 40', 'e.GO Life 60' ],
    {
        default: 'e.GO Life 20'
    }
);
promptMultiSelect(message, items) []

Select one or more items from a list in the console.

const VALUES = await this.tools.promptMultiSelect(
    'Select one or more cars:',
    [{
        name: 'e.GO Life 20',
        checked: true
    }, {
        name: 'e.GO Life 40',
        checked: true
    }, {
        name: 'e.GO Life 60'
    }]
);
promptString(message, opts) []

Ask the user for a string in the console.

const VALUE = await this.tools.promptString(
    "Input your company's name:",
    {
        "default": 'e.GO Digital GmbH',
        "validator": (val) => {
            // shorter:
            // validator = (true)
            return '' !== String(val).trim();
        }
    }
);
require(id) []

Imports any module that can be accessed by that generator.

const moment = this.tools.require('moment');

console.log(
    moment.utc()
          .format('DD.MM.YYYY')
);
runNPMInstall(dir) []

Executes npm install inside a directory.

this.tools.runNPMInstall(
    '/path/where/to/execute'
);
sleep(ms) []

Promise version of setTimeout() function.

await this.tools.sleep(5979);
sortObjectByKey(obj, keySelector) []

Creates a clone of an object and sort its keys.

const OBJ = {
    'TM': 5979,
    'tm': '19790905',
    'MK': 23979
};

// {
//   "MK": 23979,
//   "TM": 5979,
//   'tm': '19790905',
// }
const CLONE_1 = this.tools.sortObjectByKey(
    OBJ
);

// {
//   "MK": 23979,
//   'tm': '19790905',
//   "TM": 5979,
// }
const CLONE_2 = this.tools.sortObjectByKey(
    OBJ,
    objKey => objKey
);
toStringSafe(val, defaultValue) []

Returns a value as a string.

// '111'
const VAL_1 = this.tools.toStringSafe(111);

// ''
const VAL_2 = this.tools.toStringSafe(null);

// 'TM'
const VAL_3 = this.tools.toStringSafe(undefined, 'TM');
toXml(obj, spaces) []

Converts a XML object loaded by fromXml() or xml-js back to a string.

const XML_OBJ = this.tools.fromXml(
    '<root>' + 
    '<child_1 />' + 
    '<child_2 tm="5979" mk="23979">' + 
    'TM+MK' + 
    '</child_2>' + 
    '</root>'
);

XML_OBJ['elements'][0]  // root
       ['elements'][1]  // child_2
       ['elements'][0].text = "XUSZP";

const XML_STR = this.tools.toXml(
    XML_OBJ,
    2
);
unzip(file) []

Unzips a file.

s. node-zip for more information.

const fs = require('fs');

const ZIP = this.tools.unzip(
    fs.readFileSync('/path/to/zip/file')    
);

// you can also submit the file path instead
const ZIP_BY_PATH = this.tools.unzip(
    '/path/to/zip/file'  
);
withSpinner(textOrOptions, func) []

Invokes an action for a spinner (text).

await this.tools.withSpinner('Lorem ipsum', async (spinner) => {
    // spinner => s. https://github.com/sindresorhus/ora
});
withSpinnerSync(textOrOptions, func) []

Invokes an action for a spinner (text) synchronously.

this.tools.withSpinnerSync('Lorem ipsum', (spinner) => {
    // spinner => s. https://github.com/sindresorhus/ora
});