Skip to content

Commit

Permalink
Merge pull request #5 from humanmade/prepare-beta-v1
Browse files Browse the repository at this point in the history
Prepare beta v1
  • Loading branch information
jerico authored Feb 13, 2023
2 parents b1123fd + 7b5d259 commit b7d5108
Show file tree
Hide file tree
Showing 9 changed files with 5,252 additions and 111 deletions.
47 changes: 14 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,63 +1,44 @@
# @humanmade/cli
# @humanmade/altis-cli

CLI for running Human Made utilities and commands.
CLI for running Altis utilities and commands.


## Installing

You need Node v5 or later.
You need Node v18 or later.

```sh
# Install globally:
npm install -g @humanmade/cli
npm install -g @humanmade/altis-cli

# Run it:
hm
```

You may also want to install the autocompletions (Bash only):

```sh
hm completion >> ~/.bashrc
altis-cli
```

## Available Commands

Always use `hm help` for the most up-to-date list of commands.

* `cs` - Coding standards helpers.
* `add` - Add coding standards to an existing repo.
* `run` - Run coding standards on the current repo.
* `completion` - Bash auto-completion script.
* `config` - CLI configuration.
* `reset` - Reset all configuration.
* `setup` - Set or change various configuration.
* `status` - Check what you've configured.
* `issues` - Repo issue helpers.
* `list` - List open issues on the project's repo.
* `open` - Open an issue in your browser.
* `prs` - Pull request helpers.
* `list` - List open pull requests on the project's repo.
* `repo` - Repo helpers.
* `open` - Open the repo in your browser.
* `stack` - HM Stack/hosting helpers.
Always use `altis-cli help` for the most up-to-date list of commands.
* `cli` - Meta CLI commands
* `clear-cache` - Clear the cache file
* `config` - Configuration commands
* `reset` - Reset configuration
* `setup` - Set up configuration
* `status` - Show stored configuration
* `stack` - Stack commands
* `list` - List stacks available in our hosting.
* `backup [stack]` - Create a new backup for the stack.
* `backups [stack]` - List backups for the stack.
* `deploy [stack]` - Deploy a given stack.
* `info [stack]` - Get information for a stack.
* `sequel [stack]` - Connect to stack database via Sequel Pro.
* `scp <src> <dest>` - Copy a file to/from a stack.
* `ssh [stack]` - SSH into a stack.
* `php-logs [stack]` - Show PHP logs for a stack.
* `tests` - Unit testing helpers.
* `add` - Add unit tests to your repo.

## Credits

Created by Ryan McCue to make your day better.

Licensed under the MIT license. Copyright 2017 Human Made.
Licensed under the MIT license. Copyright 2017-2023 Human Made.

```
:+oo/ .hmNh oyy. /dMMm: /syo.
Expand Down
2 changes: 1 addition & 1 deletion bin/altis → bin/altis-cli
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ const main = argv => {
}

const configure = require( '../lib/commands/config/setup' );
return configure( { config } );
return configure.handler( { config } );
}).then(() => {
process.stderr.write( `Run ${chalk.yellow('hm config setup')} at any time to run setup.\n\n` );
return config.set( 'didSetup', true );
Expand Down
90 changes: 65 additions & 25 deletions lib/commands/stack/deploy.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,22 @@ const chalk = require( 'chalk' );
const inquirer = require( 'inquirer' );
const ora = require( 'ora' );

const { getStackRegion, streamLog } = require( './util' );
const { getStack, streamLog } = require( './util' );
const Vantage = require( '../../vantage' );

function deploy( vantage, stack, force ) {
function deploy( vantage, stack, force, buildId ) {

console.log( `Deploying ${stack}...` );

let url = `stack/applications/${stack}/deploys?stream=true`;
if ( force ) {
url += '&force=true';
}

if ( buildId ) {
url += `&build=${ buildId }`;
}

const opts = { method: 'POST' };
return vantage.fetch( url, opts ).then( resp => {
if ( ! resp.ok ) {
Expand All @@ -34,36 +39,71 @@ function deploy( vantage, stack, force ) {
});
}

const handler = function ( argv ) {
const handler = argv => {
const { config, debug, force } = argv;

getStackRegion( argv ).then( ( { region, stack } ) => {
const v = new Vantage( config, region );
if ( argv.resume ) {
streamLog( v, stack, argv.resume, debug );
return;
}
getStack( argv ).then( ( stack ) => {
const v = new Vantage( config );

deploy( v, stack, force )
.then( id => {
console.log( chalk.yellow( `Deploy started, resume later with...` ) );
console.log( chalk.yellow( ` hm stack deploy ${ stack } --resume ${ id }\n` ) );
const status = new ora( `Loading builds for ${ stack }…` );
status.start();

streamLog( v, stack, id, debug );
} )
.catch( err => {
if ( err.code && err.code === 'already-upto-date' ) {
console.log();
ora( `${ chalk.bold( stack ) } is already up to date.` ).fail();
v.fetch( `stack/applications/${ stack }/builds` )
.then( resp => resp.json() )
.then( builds => {
status.succeed();

console.log( chalk.yellow( 'You can force deployment with...' ) );
console.log( chalk.yellow( ` hm stack deploy ${ stack } --force` ) );
const latest = builds.slice();
latest.sort( ( a, b ) => {
const aTime = new Date( a.date );
const bTime = new Date( b.date );

process.exit( 1 );
} else {
throw err;
}
return bTime - aTime;
});

const rows = latest.map( row => {
return {
name: `${ row.source_version.slice(0,8) } ${ chalk.grey( `(${ ( row.date ) })` ) }`,
value: row,
short: row.id,
};
} );

return inquirer.prompt({
type: 'list',
name: 'build',
message: 'Select build to use:',
choices: rows,
});
})
.then( choices => choices.build )
.then( row => {
if ( argv.resume ) {
streamLog( v, stack, argv.resume, debug );
return;
}

deploy( v, stack, force, row.id )
.then( id => {
console.log( chalk.yellow( `Deploy started, resume later with...` ) );
console.log( chalk.yellow( ` altis-cli stack deploy ${ stack } --resume ${ id }\n` ) );

streamLog( v, stack, id, debug );
} )
.catch( err => {
if ( err.code && err.code === 'already-upto-date' ) {
console.log();
ora( `${ chalk.bold( stack ) } is already up to date.` ).fail();

console.log( chalk.yellow( 'You can force deployment with...' ) );
console.log( chalk.yellow( ` altis-cli stack deploy ${ stack } --force` ) );

process.exit( 1 );
} else {
throw err;
}
} )
} );
} );
};
module.exports = {
Expand Down
50 changes: 50 additions & 0 deletions lib/commands/stack/local-setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
const bytes = require( 'bytes' );
const chalk = require( 'chalk' );
const fs = require( 'fs' );
const ora = require( 'ora' );
const process = require( 'process' );
const cmd = require( 'node-cmd' );

const Vantage = require( '../../vantage' );
const { getStack, streamLog } = require( './util' );

const handler = argv => {
getStack( argv ).then( stack => {
const v = new Vantage(argv.config);

const status = new ora(`Loading repository for ${ stack }…`);
status.start();

v.fetch(`stack/applications/${ stack }`)
.then( resp => resp.json() )
.then( repo => {
status.succeed();

const url = repo['git-deployment']['url'];
const branch = repo['git-deployment']['ref'];
const dir = `./${stack}`;

if ( !fs.existsSync( dir ) ){
console.log( chalk.yellow( `Creating directory: ${ chalk.underline( dir ) }` ) );
fs.mkdirSync(dir);
}

process.chdir(dir);

console.log( chalk.yellow( `Cloning: ${ chalk.underline( url ) }` ) );
cmd.runSync(`git clone --branch ${branch} ${url} ./`);

console.log( chalk.yellow( `Installing dependencies…` ) );
cmd.runSync('composer install');

console.log( chalk.yellow( `${ chalk.underline( stack ) } is now available at ${ chalk.underline( dir ) }` ) );
console.log( chalk.yellow( `Run \`composer server start\` to get started` ) );
} );
})
};

module.exports = {
command: 'local-setup [stack]',
description: 'Setup an existing Altis stack locally.',
handler,
};
4 changes: 2 additions & 2 deletions lib/commands/stack/scp.js
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ const handler = function ( argv ) {
if ( parsedSrc.type === 'local' && ! fs.existsSync( parsedSrc.path ) ) {
console.log( `${ parsedSrc.path }: No such file or directory` );
process.exit( 1 );
} else if ( parsedDest.type === 'remote' && ! fs.existsSync( parsedDest.path ) ) {
} else if ( parsedDest.type === 'remote' && ! fs.existsSync( parsedSrc.path ) ) {
console.log( `${ parsedSrc.path }: No such file or directory` );
process.exit( 1 );
}
Expand Down Expand Up @@ -425,7 +425,7 @@ const handler = function ( argv ) {

module.exports = {
command: 'scp <src> <dest>',
description: 'Copy a file to/from a stack.',
description: 'Copy a file to/from a stack. Remote src/dest are determined by a colon in the input, e.g. stack:/usr/src/app.',
builder: subcommand => {
subcommand.option( 'verbose', {
alias: 'v',
Expand Down
45 changes: 0 additions & 45 deletions lib/commands/stack/sequel.js

This file was deleted.

2 changes: 1 addition & 1 deletion lib/vantage.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ class VantageAPI {
}

getLogStream( args ) {
const urlObj = parse( resolve( this.baseUrl, '/stream-log' ), true );
const urlObj = parse( resolve( BASE_URL, '/stream-log' ), true );
urlObj.query = args;
const absUrl = format( urlObj );
return this.authenticate().then( ( { token } ) => {
Expand Down
Loading

0 comments on commit b7d5108

Please sign in to comment.