CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-yeoman-generator

Rails-inspired generator system that provides scaffolding for your apps

Overview
Eval results
Files

command-line.mddocs/

Command Line Interface

Options and arguments definition system with parsing, validation, and help generation for creating command-line tools with Yeoman generators.

Capabilities

Option Definition

Define command line options with type validation, defaults, and help text.

/**
 * Adds an option to the set of generator expected options
 * By default, generators get all the CLI options parsed by nopt as this.options hash
 * @param name - Option name or option specification object
 * @param config - Option configuration
 * @returns This generator for chaining
 */
option(name: string | CliOptionSpec | CliOptionSpec[], config?: Partial<Omit<CliOptionSpec, 'name'>>): this;

Usage Examples:

export default class MyGenerator extends Generator {
  constructor(args, opts) {
    super(args, opts);
    
    // Basic boolean option
    this.option('skip-install', {
      type: Boolean,
      description: 'Skip npm install',
      default: false
    });
    
    // String option with alias
    this.option('project-name', {
      type: String,
      alias: 'n',
      description: 'Name of the project',
      default: 'my-project'
    });
    
    // Number option
    this.option('port', {
      type: Number,
      description: 'Server port number',
      default: 3000
    });
    
    // Hidden option (not shown in help)
    this.option('internal-flag', {
      type: Boolean,
      hide: true,
      description: 'Internal use only'
    });
    
    // Option with storage
    this.option('author', {
      type: String,
      description: 'Author name',
      storage: this.config // Store in generator config
    });
  }
  
  initializing() {
    // Access options
    if (this.options.skipInstall) {
      this.log('Skipping npm install...');
    }
    
    this.log(`Project name: ${this.options.projectName}`);
    this.log(`Port: ${this.options.port}`);
  }
}

Argument Definition

Define positional command line arguments with type validation and requirements.

/**
 * Adds an argument to the class and creates an attribute getter for it
 * Arguments are different from options - they are retrieved based on their position
 * @param name - Argument name  
 * @param config - Argument configuration
 * @returns This generator for chaining
 */
argument(name: string, config?: Partial<ArgumentSpec>): this;

Usage Examples:

export default class MyGenerator extends Generator {
  constructor(args, opts) {
    super(args, opts);
    
    // Required string argument
    this.argument('appname', {
      type: String,
      description: 'Name of the application',
      required: true
    });
    
    // Optional argument with default
    this.argument('template', {
      type: String,
      description: 'Template to use',
      required: false,
      default: 'basic'
    });
    
    // Array argument (captures remaining arguments)
    this.argument('features', {
      type: Array,
      description: 'Features to include',
      required: false,
      default: []
    });
  }
  
  initializing() {
    // Access arguments
    this.log(`App name: ${this.options.appname}`);
    this.log(`Template: ${this.options.template}`);
    this.log(`Features: ${this.options.features.join(', ')}`);
    
    // Also available as this.args array
    this.log(`Raw arguments: ${this.args.join(' ')}`);
  }
}

Help Generation

Automatic help text generation with usage information and option/argument documentation.

/**
 * Generate help message for the generator
 * @returns Complete help message with usage, options, and arguments
 */
help(): string;

/**
 * Generate usage information for this generator
 * @returns Usage line showing proper command syntax
 */
usage(): string;

/**
 * Set custom description to append on help output
 * @param description - Description text
 * @returns This generator for chaining
 */
desc(description: string): this;

/**
 * Get help text for arguments
 * @returns Formatted table of arguments with descriptions
 */
argumentsHelp(): string;

/**
 * Get help text for options  
 * @returns Formatted table of options with descriptions
 */
optionsHelp(): string;

Usage Examples:

export default class MyGenerator extends Generator {
  constructor(args, opts) {
    super(args, opts);
    
    // Set generator description
    this.desc('Generate a new Node.js project with customizable features');
    
    // Define options and arguments
    this.argument('name', {
      type: String,
      description: 'Project name',
      required: true
    });
    
    this.option('typescript', {
      type: Boolean,
      alias: 't',
      description: 'Use TypeScript',
      default: false
    });
    
    this.option('package-manager', {
      type: String,
      alias: 'pm',
      description: 'Package manager to use',
      default: 'npm'
    });
  }
  
  // Users can run: yo myapp --help
  // This will automatically generate help text like:
  // 
  // Usage:
  //   yo myapp <name> [options]
  // 
  // Generate a new Node.js project with customizable features
  // 
  // Options:
  //   -t, --typescript     Use TypeScript             Default: false
  //   --pm, --package-manager  Package manager to use   Default: npm
  //   -h, --help          Print the generator's options and usage
  // 
  // Arguments:
  //   name    Project name    Type: String    Required: true
}

Option Parsing

Automatic parsing and validation of command line options and arguments.

/**
 * Parse command line options and arguments
 * Usually called automatically, but can be called manually
 */
parseOptions(): void;

/**
 * Check that all required arguments are present
 * Throws error if required arguments are missing
 */
checkRequiredArgs(): void;

Usage Example:

export default class MyGenerator extends Generator {
  constructor(args, opts) {
    super(args, opts);
    
    this.argument('name', { type: String, required: true });
    this.option('force', { type: Boolean, default: false });
    
    // Parsing is automatic, but you can force it
    if (this.features.skipParseOptions) {
      this.parseOptions();
    }
  }
  
  initializing() {
    // Arguments and options are parsed and available
    this.log(`Creating project: ${this.options.name}`);
    
    if (this.options.force) {
      this.log('Force mode enabled');
    }
  }
}

Built-in Options

Standard options available in all generators.

// Built-in options (automatically available)
interface BuiltInOptions {
  help: boolean;           // -h, --help: Print generator help
  skipCache: boolean;      // --skip-cache: Do not remember prompt answers  
  skipInstall: boolean;    // --skip-install: Do not automatically install dependencies
  forceInstall: boolean;   // --force-install: Fail on install dependencies error
  askAnswered: boolean;    // --ask-answered: Show prompts for already configured options
}

Usage Example:

export default class MyGenerator extends Generator {
  constructor(args, opts) {
    super(args, opts);
    
    // Built-in options are always available
    if (this.options.help) {
      // Help will be shown automatically, this won't run
      return;
    }
  }
  
  async prompting() {
    // skipCache affects prompt behavior
    if (!this.options.skipCache) {
      this.log('Using cached answers...');
    }
    
    this.answers = await this.prompt([...]);
  }
  
  install() {
    // skipInstall affects install behavior
    if (!this.options.skipInstall) {
      this.spawnCommand('npm', ['install']);
    }
  }
}

Advanced Option Configuration

Complex option configurations with custom types and validation.

Usage Examples:

export default class MyGenerator extends Generator {
  constructor(args, opts) {
    super(args, opts);
    
    // Custom type converter
    this.option('features', {
      type: (val) => val.split(','),
      description: 'Comma-separated list of features',
      default: []
    });
    
    // Multiple option objects at once
    this.option([
      {
        name: 'verbose',
        type: Boolean,
        alias: 'v',
        description: 'Verbose output',
        default: false
      },
      {
        name: 'config-file',
        type: String,
        description: 'Path to config file',
        storage: this.config
      }
    ]);
    
    // Required option
    this.option('api-key', {
      type: String,
      required: true,
      description: 'API key for service'
    });
  }
  
  initializing() {
    // Validate custom requirements
    if (this.options.features.includes('database') && !this.options.dbUrl) {
      throw new Error('Database feature requires --db-url option');
    }
  }
}

Option Storage Integration

Automatic persistence of option values to configuration storage.

Usage Example:

export default class MyGenerator extends Generator {
  constructor(args, opts) {
    super(args, opts);
    
    // Options with storage are automatically persisted
    this.option('author-name', {
      type: String,
      description: 'Author name',
      storage: this.config, // Store in .yo-rc.json
      default: 'Anonymous'
    });
    
    this.option('git-email', {
      type: String,
      description: 'Git email',
      storage: 'config', // Store in this.config by name
      default: async () => await this.git.email()
    });
  }
  
  configuring() {
    // Stored options are automatically available in config
    const authorName = this.config.get('authorName');
    const gitEmail = this.config.get('gitEmail');
    
    this.log(`Config author: ${authorName}`);
    this.log(`Config email: ${gitEmail}`);
  }
}

Types

interface CliOptionSpec {
  name: string;
  type: typeof Boolean | typeof String | typeof Number | ((opt: string) => any);
  required?: boolean;
  alias?: string;
  default?: any;
  description?: string;
  hide?: boolean;
  storage?: string | Storage;
}

interface ArgumentSpec {
  name: string;
  description?: string;
  required?: boolean;
  optional?: boolean;
  type: typeof String | typeof Number | typeof Array | typeof Object;
  default?: any;
}

Install with Tessl CLI

npx tessl i tessl/npm-yeoman-generator

docs

command-execution.md

command-line.md

configuration.md

core-generator.md

file-system.md

git-integration.md

index.md

package-management.md

task-lifecycle.md

user-interaction.md

tile.json