Skip to content

Commit 17a99df

Browse files
committed
docs for libs and utils
1 parent ab4be19 commit 17a99df

File tree

6 files changed

+350
-83
lines changed

6 files changed

+350
-83
lines changed

lib/cli.js

Lines changed: 196 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,80 @@ const EOL = os.EOL;
1111
const formatters = require('./formatters');
1212
const getSysDataPath = require('../utils/get-system-data-dir');
1313

14+
/**
15+
* @typedef {import('chalk').Chalk} Chalk
16+
* @typedef {import('inquirer')} Inquirer
17+
* @typedef {import('yargs')} YargsInstance
18+
* @typedef {import('yargs').Arguments} Arguments
19+
* @typedef {import('yargs').CommandModule} CommandModule
20+
* @typedef {import('yargs').Options} Options
21+
* @typedef {import('yargs').ParserConfigurationOptions} ParserConfigurationOptions
22+
* @typedef {import('yargs').BuilderCallback} BuilderCallback
23+
*/
24+
25+
/**
26+
* @typedef {Object} GlobalOptions
27+
* @property {Object} channel - Channel option configuration
28+
* @property {string} channel.describe - Option description
29+
* @property {string[]} channel.choices - Valid channel choices
30+
* @property {boolean} channel.global - Whether option is global
31+
* @property {string} channel.type - Option type
32+
* @property {Object} clear - Clear option configuration
33+
* @property {string} clear.describe - Option description
34+
* @property {boolean} clear.global - Whether option is global
35+
* @property {string} clear.type - Option type
36+
* @property {Object} debug - Debug option configuration
37+
* @property {string} debug.describe - Option description
38+
* @property {boolean} debug.global - Whether option is global
39+
* @property {string} debug.type - Option type
40+
* @property {Object} experimental - Experimental option configuration
41+
* @property {string} experimental.describe - Option description
42+
* @property {boolean} experimental.global - Whether option is global
43+
* @property {boolean} experimental.hidden - Whether option is hidden
44+
* @property {string} experimental.type - Option type
45+
* @property {Object} help - Help option configuration
46+
* @property {string} help.describe - Option description
47+
* @property {string} help.type - Option type
48+
* @property {Object} lando - Lando option configuration
49+
* @property {boolean} lando.hidden - Whether option is hidden
50+
* @property {string} lando.type - Option type
51+
* @property {Object} verbose - Verbose option configuration
52+
* @property {string} verbose.alias - Option alias
53+
* @property {string} verbose.describe - Option description
54+
* @property {string} verbose.type - Option type
55+
*/
56+
57+
/**
58+
* @typedef {Object} TaskConfig
59+
* @property {string} [command] - Command name
60+
* @property {string} [describe] - Command description
61+
* @property {Array<string|Array>} [examples] - Command examples
62+
* @property {string} [file] - Path to task file
63+
* @property {Options} [options] - Command options
64+
* @property {Object} [positionals] - Command positional arguments
65+
* @property {Function|Object} [run] - Command run function
66+
* @property {string} [level='app'] - Command level
67+
* @property {string} [usage] - Command usage
68+
*/
69+
70+
/**
71+
* @typedef {Object} CliConfig
72+
* @property {string} [prefix='LANDO'] - Environment variable prefix
73+
* @property {string} [logLevel='warn'] - Default log level
74+
* @property {string} [userConfRoot='~/.lando'] - Path to user config directory
75+
* @property {string} [coreBase='../'] - Path to Lando core base directory
76+
* @property {Function} [debug=require('debug')('@lando/cli')] - Debug function
77+
*/
78+
79+
/**
80+
* @typedef {Object} ErrorHandler
81+
* @property {(error: Error & {verbose?: number}, reportErrors?: boolean) => Promise<number>} handle - Handles an error and returns exit code
82+
*/
83+
84+
/**
85+
* @typedef {Error & {verbose?: number}} LandoError
86+
*/
87+
1488
// Global options
1589
const globalOptions = {
1690
channel: {
@@ -50,17 +124,42 @@ const globalOptions = {
50124
},
51125
};
52126

53-
/*
54-
* Construct the CLI
127+
/**
128+
* The CLI class provides command line interface functionality for Lando
129+
*
130+
* This class handles command line argument parsing, task management, and user interaction
131+
* for the Lando CLI. It integrates with the core Lando system to provide a complete
132+
* command line interface.
133+
*
134+
* @since 3.0.0
135+
* @class
136+
* @memberof module:Lando
137+
* @property {string} prefix - Environment variable prefix for CLI
138+
* @property {string} logLevel - Default log level
139+
* @property {string} userConfRoot - Path to user config directory
140+
* @property {string} coreBase - Path to Lando core base directory
141+
* @property {Function} debug - Debug logging function
142+
* @property {Chalk} chalk - Chalk instance for terminal coloring
143+
* @property {Arguments} argv Parsed CLI arguments
144+
* @property {Function} checkPerms Checks if Lando is running with sudo
145+
* @property {Function} clearTaskCaches Clears the Lando task caches
146+
* @property {Function} confirm Creates a confirmation prompt configuration
147+
* @property {Function} defaultConfig Returns default configuration for CLI bootstrap
148+
* @property {Function} formatData Formats data for CLI output
149+
* @property {Function} formatOptions Gets CLI options formatting
55150
*/
56-
module.exports = class Cli {
57-
constructor(
151+
class Cli {
152+
/**
153+
* Creates a new CLI instance
154+
* @param {CliConfig} config - CLI configuration options
155+
*/
156+
constructor({
58157
prefix = 'LANDO',
59158
logLevel = 'warn',
60159
userConfRoot = path.join(os.homedir(), '.lando'),
61160
coreBase = path.resolve(__dirname, '..'),
62161
debug = require('debug')('@lando/cli'),
63-
) {
162+
} = {}) {
64163
this.prefix = prefix;
65164
this.logLevel = logLevel;
66165
this.userConfRoot = userConfRoot;
@@ -74,7 +173,7 @@ module.exports = class Cli {
74173
*
75174
* @since 3.0.0
76175
* @alias lando.cli.argv
77-
* @return {Object} Yarg parsed options
176+
* @return {Arguments} Yargs parsed command line arguments
78177
* @example
79178
* const argv = lando.cli.argv();
80179
* @todo make this static and then fix all call sites
@@ -84,29 +183,35 @@ module.exports = class Cli {
84183
}
85184

86185
/**
87-
* Checks to see if lando is running with sudo. If it is it
88-
* will exit the process with a stern warning
186+
* Checks if Lando is running with sudo and exits if true
89187
*
90188
* @since 3.0.0
91189
* @alias lando.cli.checkPerms
92190
* @example
93191
* lando.cli.checkPerms()
192+
* @throws {Error} If Lando is running with sudo
94193
*/
95194
checkPerms() {
96195
const sudoBlock = require('sudo-block');
97196
sudoBlock(this.makeArt('sudoRun'));
98197
}
99198

100-
/*
101-
* Toggle the secret toggle
199+
/**
200+
* Clears the Lando task caches
201+
* @private
102202
*/
103203
clearTaskCaches() {
104-
if (fs.existsSync(process.landoTaskCacheFile)) fs.unlinkSync(process.landoTaskCacheFile);
105-
if (fs.existsSync(process.landoAppCacheFile)) fs.unlinkSync(process.landoAppCacheFile);
204+
const taskCacheFile = process.env.LANDO_TASK_CACHE_FILE;
205+
const appCacheFile = process.env.LANDO_APP_CACHE_FILE;
206+
if (taskCacheFile && fs.existsSync(taskCacheFile)) fs.unlinkSync(taskCacheFile);
207+
if (appCacheFile && fs.existsSync(appCacheFile)) fs.unlinkSync(appCacheFile);
106208
}
107209

108-
/*
109-
* Confirm question
210+
/**
211+
* Creates a confirmation prompt configuration
212+
*
213+
* @param {string} [message='Are you sure?'] Prompt message
214+
* @return {Object} Inquirer prompt configuration
110215
*/
111216
confirm(message = 'Are you sure?') {
112217
return {
@@ -123,13 +228,12 @@ module.exports = class Cli {
123228
}
124229

125230
/**
126-
* Returns a config object with some good default settings for bootstrapping
127-
* lando as a command line interface
231+
* Returns default configuration for CLI bootstrap
128232
*
129233
* @since 3.5.0
130234
* @alias lando.cli.defaultConfig
131235
* @param {Object} [appConfig={}] Optional raw landofile
132-
* @return {Object} Config that can be used in a Lando CLI bootstrap
236+
* @return {Object} CLI bootstrap configuration
133237
* @example
134238
* const config = lando.cli.defaultConfig();
135239
* // Kick off our bootstrap
@@ -218,44 +322,70 @@ module.exports = class Cli {
218322
return config;
219323
}
220324

221-
/*
222-
* Format data
325+
/**
326+
* Formats data for CLI output
327+
*
328+
* @param {*} data Data to format
329+
* @param {Object} [options] Format options
330+
* @param {string} [options.path=''] Path to data property
331+
* @param {string} [options.format='default'] Output format
332+
* @param {Array} [options.filter=[]] Properties to filter
333+
* @param {Object} [opts={}] Additional formatting options
334+
* @return {string} Formatted output
223335
*/
224336
formatData(data, {path = '', format = 'default', filter = []} = {}, opts = {}) {
225337
return formatters.formatData(data, {path, format, filter}, opts);
226338
}
227339

228-
/*
229-
* FormatOptios
340+
/**
341+
* Gets CLI options formatting
342+
*
343+
* @param {Array} [omit=[]] Options to omit
344+
* @return {Object} Formatted options
230345
*/
231346
formatOptions(omit = []) {
232347
return formatters.formatOptions(omit);
233348
}
234349

350+
/**
351+
* Gets Inquirer instance for prompts
352+
*
353+
* @return {Inquirer} Inquirer instance
354+
*/
235355
getInquirer() {
236356
return require('inquirer');
237357
}
238358

359+
/**
360+
* Gets oclif UX instance
361+
*
362+
* @return {Object} oclif UX instance
363+
*/
239364
getUX() {
240365
return require('@oclif/core').ux;
241366
}
242367

368+
/**
369+
* Checks if debug mode is enabled
370+
*
371+
* @return {number} Debug level
372+
*/
243373
isDebug() {
244374
const {debug, verbose} = this.argv();
245375
return debug ? 1 + verbose : 0 + verbose;
246376
}
247377

248378
/**
249-
* Cli wrapper for error handler
379+
* Handles CLI errors
250380
*
251381
* @since 3.0.0
252382
* @alias lando.cli.handleError
253-
* @param {Error} error The error
254-
* @param {Function} handler The error handler function
255-
* @param {Integer} verbose [verbose=this.argv().verbose] The verbosity level
256-
* @param {Object} lando The Lando object
257-
* @param {Boolean} yes [yes=this.argv().yes] The auto yes value
258-
* @return {Integer} The exit codes
383+
* @param {LandoError} error Error object
384+
* @param {ErrorHandler} handler Error handler
385+
* @param {number} [verbose=this.argv().verbose] Verbosity level
386+
* @param {Object} [lando={}] Lando instance
387+
* @param {boolean} [yes=this.argv().yes] Auto-confirm prompts
388+
* @return {Promise<number>} Exit code
259389
*/
260390
handleError(error, handler, verbose = this.argv().verbose, lando = {}, yes = this.argv().yes) {
261391
// Set the verbosity
@@ -289,8 +419,13 @@ module.exports = class Cli {
289419
.then(() => handler.handle(error, lando.cache.get('report_errors')).then(code => process.exit(code)));
290420
}
291421

292-
/*
293-
* Init
422+
/**
423+
* Initializes the CLI with tasks and configuration
424+
*
425+
* @param {YargsInstance} yargs Yargs instance
426+
* @param {Array<CommandModule>} tasks CLI tasks
427+
* @param {Object} config Lando configuration
428+
* @param {Object} [userConfig={}] User configuration
294429
*/
295430
init(yargs, tasks, config, userConfig = {}) {
296431
// if we have LANDO_ENTRYPOINT_NAME
@@ -351,15 +486,14 @@ module.exports = class Cli {
351486
yargs.argv;
352487
}
353488

354-
355489
/**
356-
* Returns some cli "art"
490+
* Generates CLI art
357491
*
358492
* @since 3.0.0
359493
* @alias lando.cli.makeArt
360-
* @param {String} [func='start'] The art func you want to call
361-
* @param {Object} [opts] Func options
362-
* @return {String} Usually a printable string
494+
* @param {string} func Art function to call
495+
* @param {Object} [opts] Function options
496+
* @return {string} Generated art
363497
* @example
364498
* console.log(lando.cli.makeArt('secretToggle', true);
365499
*/
@@ -368,18 +502,18 @@ module.exports = class Cli {
368502
}
369503

370504
/**
371-
* Parses a lando task object into something that can be used by the [yargs](http://yargs.js.org/docs/) CLI.
505+
* Parses a Lando task into Yargs command format
372506
*
373507
* A lando task object is an abstraction on top of yargs that also contains some
374508
* metadata about how to interactively ask questions on both a CLI and GUI.
375509
*
376510
* @since 3.5.0
377511
* @alias lando.cli.parseToYargs
378-
* @see [yargs docs](http://yargs.js.org/docs/)
379-
* @see [inquirer docs](https://github.com/sboudrias/Inquirer.js)
380-
* @param {Object} task A Lando task object (@see add for definition)
381-
* @param {Object} [config={}] The landofile
382-
* @return {Object} A yargs command object
512+
* @param {TaskConfig} task - Lando task configuration
513+
* @param {Object} [config={}] - Lando configuration
514+
* @return {CommandModule} Yargs command object
515+
* @see {@link http://yargs.js.org/docs/|Yargs}
516+
* @see {@link https://github.com/sboudrias/Inquirer.js|Inquirer.js}
383517
* @example
384518
* // Add a task to the yargs CLI
385519
* yargs.command(lando.tasks.parseToYargs(task));
@@ -502,12 +636,23 @@ module.exports = class Cli {
502636
}};
503637
}
504638

639+
/**
640+
* Prettifies data for CLI output
641+
*
642+
* @param {*} data Data to prettify
643+
* @param {Object} [options] Prettify options
644+
* @param {string} [options.arraySeparator=', '] Separator for arrays
645+
* @return {string} Prettified output
646+
*/
505647
prettify(data, {arraySeparator = ', '} = {}) {
506648
return require('../utils/prettify')(data, {arraySeparator});
507649
}
508650

509-
/*
510-
* Run the CLI
651+
/**
652+
* Runs the CLI
653+
*
654+
* @param {Array<CommandModule>} [tasks=[]] CLI tasks
655+
* @param {Object} [config={}] Lando configuration
511656
*/
512657
run(tasks = [], config = {}) {
513658
const yargonaut = require('yargonaut');
@@ -551,8 +696,11 @@ module.exports = class Cli {
551696
this.init(yargs, tasks, config, userConfig);
552697
}
553698

554-
/*
555-
* Toggle a toggle
699+
/**
700+
* Updates user configuration
701+
*
702+
* @param {Object} [data={}] Configuration updates
703+
* @return {Object} Updated configuration
556704
*/
557705
updateUserConfig(data = {}) {
558706
const Yaml = require(`../lib/yaml`);
@@ -562,4 +710,6 @@ module.exports = class Cli {
562710
const file = yaml.dump(configFile, _.assign({}, config, data));
563711
return yaml.load(file);
564712
}
565-
};
713+
}
714+
715+
module.exports = Cli;

0 commit comments

Comments
 (0)