@river-agency/cli
v1.4.0
Published
The river CLI tool provides a central service for creating, managing and configuring projects at RIVER.
Downloads
7
Readme
RIVER CLI
The river CLI tool provides a central service for creating, managing and configuring projects at RIVER.
Usage
Available Commands
new
: Create a new Laravel project using the default branch of the river-laravel-template repositoryversion
: Display the CLI version
Laravel
env:init
: Generate Laravel's.env
file
Terraform
terraform:init
: Generate the terraform configurationterraform:apply
: Apply the terraform configurationterraform:download
: Download the AWS configuration fileterraform:install
: Run all terraform commands
Bitbucket Pipelines
pipelines:init
: Generate thebitbucket-pipelines.yml
configurationpipelines:add
: Add a new deployment to thebitbucket-pipelines.yml
configurationpipelines:remove
: Remove a deployment from thebitbucket-pipelines.yml
configuration
Lando
lando:init
: Generate the.lando.yml
configuration
Development
To develop on the CLI locally, follow these steps:
Install dependencies
npm install
npm install -g ts-node # typescript version of `node`
*Note: Node 16 or later is required.*
Run Commands
# Invoke the CLI application
ts-node src/index.ts
# Show the help menu explicitly
ts-node src/index.ts --help
# Run a command
ts-node src/index.ts new
A note on performance
If you are using an IDE with Typescript support, you can skip the compile time type-checking and get native JS speeds when running commands. Simply pass the transpileOnly
flag when running the command.
ts-node -T src/index.ts
Adding new Commands
Commands are automatically loaded from the src/commands
directory. This is not recursive.
All commands must extend the Command
class exported from src/command.ts
Working with the CLI during development
Create a new project locally, using example
as the production domain (this is ignored via .gitignore
)
ts-node src/index.ts new
Change into the project directory and call the CLI using relative paths, not the global install.
cd example
ts-node ../src/index.ts env:init
Deployment
To publish the package, ensure you are logged into the RIVER agency NPM account.
Steps
# Start from a clean working directory
git add .
git commit -m "your message"
git push
# Tag a new version
# major: Major release / Breaking changes (e.g. 2.0.0)
# minor: Feature release / Non breaking changes
# patch: Bug fix releasee / Non breaking changes
npm version minor
# Publish the package
npm publish
Note: The prepublishOnly
and postpublish
NPM scripts have been configured to automate the discrete build steps
Documentation
Command API
name
: The name of the command (required)description
: An optional description for the commandoptions
: An object representing any flag that can be passed to the command. The key will be used as the flag and the value the description.
protected options = {
'--force': "Force the command"
// Optionally, define a shortcut
'--force': ["-f", "Force the command"]
}
Flags can be accessed from the handle
method (described below).
const isForced = this.flag("force", true /* optional default */);
handle
: The async function to run when the command is invoked.
public async handle() {
return 0;
}
Note, if invoking the command from another command, returning a value will not exit the process. To exit manually, you can call the exit
method.
public async handle() {
//...
this.exit(); // Same as this.exit(0);
}
Return values
0
(integer) = Exit without errors1
(integer) = Exit with errors- any other value = Exit without errors
Invoking commands programatically
You may call any registered command by "dispatching" it via the application container.
public async handle() {
const result = this.app.dispatch("other-command")
// You may also provide flags
const result = this.app.dispatch("other-command", {
'--force': true, // By flag
'-f': true, // By flag shortcut,
'force': true, // By flag name,
})
}
Writing Console Output
public async handle()
{
this.info("Hello world") // Prints green tex
this.warn("Hello world") // Prints yellow textt
this.error("Hello world") // Prints red text
this.line("Hello world") // Prints gray text
this.jsonLine("Hello world") // Prints formmated json (gray)
this.newLine() // Prints 1 new line
this.newLine(3) // Prints 3 new lines
this.loading("Hello world") // Display a loading spinner with a message
this.loading(false) // Stop the last loading spinner
}
Accepting input
public async handle()
{
// Accept text input
const name = await this.ask("Question", "default value");
// Accept true/false input
const runInProd = await this.confirm("Run in production?", false);
// Pick from a list of options
const mode = await this.prompt(
"Which mode to run?",
["Long", "Short"],
"Short"
);
}