Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

frint-cli: Introduce "new" command #325

Merged
merged 17 commits into from Nov 6, 2017
@@ -8,6 +8,7 @@ const app = new App();

app.registerApp(require('../commands/version'));
app.registerApp(require('../commands/init'));
app.registerApp(require('../commands/new'));
app.registerApp(require('../commands/help'));

const command = app.get('command');
@@ -0,0 +1,99 @@
const mkdirp = require('mkdirp');
const request = require('request');
const tar = require('tar');

const createApp = require('frint').createApp;

const descriptionText = `
Usage:
$ frint new
$ frint new <name>
$ frint new <name> --example=<example>
$ frint new <name> --path=<path> --example=<example>
Example:
$ frint new myapp --path=frint-vue/tree/master/examples --example=basic
You can find a list of all available official examples here:
https://github.com/Travix-International/frint/tree/master/examples
`.trim();

const invalidPathArgText = `
Invalid <path> value. Must be in the format:
"<organization>/<repository>/tree/<branch>/**/*"
`.trim();

module.exports = createApp({
name: 'new',
providers: [
{
name: 'summary',
useValue: 'Scaffolds a new Frint app in specified directory',
},
{
name: 'description',
useValue: descriptionText,
},
{
name: 'execute',
useFactory: function useFactory(deps) {
return function execute() {
const path = deps.params.path || 'Travix-International/frint/tree/master/examples';
// Split by '/' and filter out empty results.
// <path> arg might start or end with the separator.
const pathComponents = path.split('/').filter(str => str !== '');
// Must contain at least 4 components: <organization>/<repository>/tree/<branch>.
if (pathComponents.length < 4) {
deps.console.error(invalidPathArgText);
return;
}
const organization = pathComponents[0];
const repository = pathComponents[1];
const branch = pathComponents[3];
let rest = pathComponents.slice(4).join('/');
if (rest !== '') rest += '/';

const example = deps.params.example || 'counter';

// Normally, the application name goes to the first slot of params if defined.
// Note that flags such as <path> and <example> are not part of the _ array.

// If app name is specified, it is taken as the 1st param.
// Note that params does not include flags <path> and <example>.
const dir = deps.params._.length >= 1
? deps.params._[0]
: deps.pwd;

function streamFrintExampleToDir() {
request(`https://codeload.github.com/${organization}/${repository}/tar.gz/${branch}`)
.on('error', deps.console.error)
.pipe(tar.x({
filter: p => p.indexOf(`${repository}-${branch}/${rest}${example}/`) === 0,
strip: 3,
C: dir,
}))
.on('error', deps.console.error)
.on('finish', () => deps.console.log('Done!'));
}

deps.console.log('Initializing...');

mkdirp(dir, function mkdirpCallback(error) {
if (error) {
deps.console.error(error);
return;
}
streamFrintExampleToDir();
});

This comment has been minimized.

Copy link
@markvincze

markvincze Oct 2, 2017

Contributor

From line 69 to here it's duplicated also in the init command, maybe we can extract this code?

This comment has been minimized.

Copy link
@discosultan

discosultan Oct 2, 2017

Author Contributor

I currently opted not to extract any code, because AFAIK, frint init command will be deprecated in the future and its code removed. @fahad19 may correct me, if I'm wrong.

This comment has been minimized.

Copy link
@fahad19

fahad19 Oct 3, 2017

Member

yeah, init will be deprecated. in fact the deprecation message can be included in this PR too.

This comment has been minimized.

Copy link
@markvincze

markvincze Oct 3, 2017

Contributor

👍

};
},
deps: [
'console',
'params',
'pwd',
],
}
],
});
@@ -0,0 +1,18 @@
/* eslint-disable import/no-extraneous-dependencies, func-names */
/* global describe, it */
const expect = require('chai').expect;
const App = require('frint').App;

const createRootApp = require('../root/index.mock');
const CommandApp = require('./new');

describe('frint-cli › commands › new', function () {
it('is a Frint App', function () {
const RootApp = createRootApp();
const rootApp = new RootApp();
rootApp.registerApp(CommandApp);
const commandApp = rootApp.getAppInstance('new');

expect(commandApp).to.be.an.instanceOf(App);
});
});
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.