Skip to content

Commit eb82710

Browse files
author
Cam Tullos
committed
Added actinium update command.
Refactored how top level commands work.
1 parent 47975dd commit eb82710

File tree

19 files changed

+641
-259
lines changed

19 files changed

+641
-259
lines changed

arcli.js

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,9 @@ if (fs.existsSync(localConfigFile)) {
3636
props.config = Object.assign(props.config, localConfig);
3737
} else {
3838
// Create the localized config if it doesn't exist
39-
const contents = prettier.format(
40-
JSON.stringify(props.config),
41-
{parser: 'json-stringify'}
42-
);
39+
const contents = prettier.format(JSON.stringify(props.config), {
40+
parser: 'json-stringify',
41+
});
4342

4443
fs.ensureFileSync(localConfigFile);
4544
fs.writeFileSync(localConfigFile, contents);
@@ -55,6 +54,8 @@ if (fs.existsSync(projConfigFile)) {
5554
const lastCheck = op.get(props.config, 'updated', Date.now());
5655

5756
function initialize() {
57+
console.log('');
58+
5859
// Configure prompt
5960
prompt.message = chalk[config.prompt.prefixColor](config.prompt.prefix);
6061
prompt.delimiter = config.prompt.delimiter;
@@ -79,17 +80,36 @@ function initialize() {
7980
* 3. Project : ~/PROJECT/.cli/commands -> overwrites CLI Root & Core.
8081
*/
8182
const commands = {};
83+
const subcommands = {};
84+
8285
globby(globs).forEach(cmd => {
8386
const req = require(cmd);
84-
if (
85-
op.has(req, 'NAME') &&
86-
op.has(req, 'COMMAND') &&
87-
typeof req.COMMAND === 'function'
88-
) {
89-
commands[req.NAME] = req;
87+
if (op.has(req, 'COMMAND') && typeof req.COMMAND === 'function') {
88+
if (op.has(req, 'NAME')) {
89+
commands[req.NAME] = req;
90+
} else {
91+
if (op.has(req, 'ID')) {
92+
let { ID } = req;
93+
ID = String(ID)
94+
.split('<')
95+
.join('')
96+
.split('>')
97+
.join('')
98+
.split(' ').join('.');
99+
100+
op.set(subcommands, ID, req);
101+
}
102+
}
90103
}
91104
});
92105

106+
props.args = process.argv.filter(item => {
107+
return String(item).substr(0, 1) !== '-';
108+
});
109+
110+
props.commands = commands;
111+
props.subcommands = subcommands;
112+
93113
// Apply commands
94114
Object.values(commands).forEach(req => req.COMMAND({ program, props }));
95115

@@ -142,10 +162,9 @@ if (lastUpdateCheck > 1) {
142162
})
143163
.then(() => {
144164
props.config.checked = Date.now();
145-
const contents = prettier.format(
146-
JSON.stringify(props.config),
147-
{parser: 'json-stringify'}
148-
);
165+
const contents = prettier.format(JSON.stringify(props.config), {
166+
parser: 'json-stringify',
167+
});
149168

150169
fs.ensureFileSync(localConfigFile);
151170
fs.writeFileSync(localConfigFile, contents);

commands/actinium/index.js

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
const chalk = require('chalk');
2+
const op = require('object-path');
3+
4+
const NAME = 'actinium';
5+
const DESC = 'Actinium: Command used to install or update Actinium.';
6+
7+
const HELP = props => {
8+
const actions = Object.keys(props.subcommands[NAME]);
9+
actions.sort();
10+
11+
console.log('');
12+
console.log('Actions:');
13+
console.log(' ', actions.map(act => chalk.cyan(act)).join(', '));
14+
console.log('');
15+
console.log('Example:');
16+
actions.forEach(act => console.log(` $ arcl`, chalk.magenta(NAME), chalk.cyan(act), '-h'));
17+
console.log('');
18+
console.log('Beware:');
19+
console.log(` ${chalk.cyan('Install')} will overwrite existing files.`);
20+
console.log(
21+
' ',
22+
chalk.cyan('Update'),
23+
' will overwrite existing',
24+
chalk.magenta('~/.core'),
25+
'files and possibly alter the',
26+
chalk.magenta('~/package.json'),
27+
'file.',
28+
);
29+
console.log('');
30+
};
31+
32+
const COMMAND = ({ program, props }) => {
33+
const ACT = props.args[3];
34+
const { subcommands = {} } = props;
35+
36+
if (NAME === props.args[2] && ACT) {
37+
if (!op.has(subcommands, `${NAME}.${ACT}`)) {
38+
console.log('');
39+
console.log(
40+
chalk.red('Invalid command:'),
41+
NAME,
42+
chalk.cyan(ACT),
43+
);
44+
console.log('');
45+
process.exit();
46+
}
47+
48+
return subcommands[NAME][ACT]['COMMAND']({ program, props });
49+
} else {
50+
return program
51+
.command(`${NAME} <action>`)
52+
.description(DESC)
53+
.action((action, opt) => {})
54+
.on('--help', () => HELP(props));
55+
}
56+
};
57+
58+
module.exports = {
59+
COMMAND,
60+
NAME,
61+
};

commands/actinium/install/actions.js

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
const fs = require('fs-extra');
2-
const path = require('path');
3-
const op = require('object-path');
4-
const request = require('request');
1+
const path = require('path');
2+
const fs = require('fs-extra');
3+
const op = require('object-path');
4+
const request = require('request');
55
const decompress = require('decompress');
66

7-
module.exports = (spinner) => {
8-
const message = (text) => {
7+
module.exports = spinner => {
8+
const message = text => {
99
if (spinner) {
1010
spinner.text = text;
1111
}
@@ -17,15 +17,19 @@ module.exports = (spinner) => {
1717

1818
message('downloading payload, this may take awhile...');
1919

20-
// Create the tmp directory if it doesn't exist.
20+
// Create the tmp directory.
2121
fs.ensureDirSync(path.normalize(`${cwd}/tmp`));
2222

2323
// Download the most recent version of actinium
2424
return new Promise((resolve, reject) => {
2525
request(config.actinium.repo)
26-
.pipe(fs.createWriteStream(path.normalize(`${cwd}/tmp/actinium.zip`)))
27-
.on('error', error => reject(error))
28-
.on('close', () => resolve({ action, status: 200 }));
26+
.pipe(
27+
fs.createWriteStream(
28+
path.normalize(`${cwd}/tmp/actinium.zip`),
29+
),
30+
)
31+
.on('error', error => reject(error))
32+
.on('close', () => resolve({ action, status: 200 }));
2933
});
3034
},
3135

@@ -37,9 +41,9 @@ module.exports = (spinner) => {
3741
const zipFile = path.normalize(`${cwd}/tmp/actinium.zip`);
3842

3943
return new Promise((resolve, reject) => {
40-
decompress(zipFile, cwd, {strip: 1})
41-
.then(() => resolve({ action, status: 200 }))
42-
.catch(error => reject(error));
44+
decompress(zipFile, cwd, { strip: 1 })
45+
.then(() => resolve({ action, status: 200 }))
46+
.catch(error => reject(error));
4347
});
4448
},
4549

commands/actinium/install/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,5 +219,5 @@ module.exports = {
219219
CONFIRM,
220220
CONFORM,
221221
COMMAND,
222-
NAME,
222+
ID: NAME,
223223
};

commands/actinium/update/actions.js

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
const path = require('path');
2+
const fs = require('fs-extra');
3+
const pkg = require('./package');
4+
const semver = require('semver');
5+
const op = require('object-path');
6+
const request = require('request');
7+
const decompress = require('decompress');
8+
9+
module.exports = spinner => {
10+
const message = text => {
11+
if (spinner) {
12+
spinner.text = text;
13+
}
14+
};
15+
16+
return {
17+
download: ({ params, props, action }) => {
18+
message('downloading payload, this may take awhile...');
19+
20+
const { config, cwd } = props;
21+
22+
// Create the tmp directory.
23+
fs.ensureDirSync(path.normalize(`${cwd}/tmp/update`));
24+
25+
// Download the most recent version of actinium
26+
return new Promise((resolve, reject) => {
27+
request(config.actinium.repo)
28+
.pipe(
29+
fs.createWriteStream(
30+
path.normalize(`${cwd}/tmp/update/actinium.zip`),
31+
),
32+
)
33+
.on('error', error => reject(error))
34+
.on('close', () => resolve({ action, status: 200 }));
35+
});
36+
},
37+
38+
unzip: ({ params, props, action }) => {
39+
message('unpacking...');
40+
41+
const { config, cwd } = props;
42+
43+
const zipFile = path.normalize(`${cwd}/tmp/update/actinium.zip`);
44+
const updateDir = path.normalize(`${cwd}/tmp/update`);
45+
46+
// Create the update directory
47+
fs.ensureDirSync(updateDir);
48+
49+
return new Promise((resolve, reject) => {
50+
decompress(zipFile, updateDir, { strip: 1 })
51+
.then(() => resolve({ action, status: 200 }))
52+
.catch(error => reject(error));
53+
});
54+
},
55+
56+
core: ({ params, props, action }) => {
57+
message('updating core...');
58+
59+
const { cwd } = props;
60+
61+
const coreDir = path.normalize(`${cwd}/.core/`);
62+
const updateDir = path.normalize(`${cwd}/tmp/update/.core/`);
63+
64+
fs.ensureDirSync(coreDir);
65+
fs.emptyDirSync(coreDir);
66+
67+
return new Promise((resolve, reject) => {
68+
fs.copy(updateDir, coreDir, error => {
69+
if (error) {
70+
reject(error);
71+
} else {
72+
resolve({ action, status: 200 });
73+
}
74+
});
75+
});
76+
},
77+
78+
files: ({ params, props, action }) => {
79+
// Add/Remove src files
80+
const { cwd } = props;
81+
const actinium = require(path.normalize(
82+
`${cwd}/tmp/update/.core/actinium-config`,
83+
));
84+
const actiniumVersion = op.get(actinium, 'version');
85+
const add = op.get(actinium, 'update.files.add') || [];
86+
const remove = op.get(actinium, 'update.files.remove') || [];
87+
88+
if (add.length > 0 || remove.length > 0) {
89+
message('updating files...');
90+
} else {
91+
return Promise.resolve({ action, status: 200 });
92+
}
93+
94+
// Remove files from src
95+
remove
96+
.filter(({ version }) =>
97+
semver.satisfies(actiniumVersion, version),
98+
)
99+
.forEach(({ source }) => {
100+
source = path.normalize(`${cwd}/${source}`);
101+
if (fs.existsSync(source)) {
102+
fs.removeSync(source);
103+
}
104+
});
105+
106+
// Add files to src
107+
add.filter(({ version }) =>
108+
semver.satisfies(actiniumVersion, version),
109+
).forEach(({ destination, force, source }) => {
110+
destination = path.normalize(`${cwd}/${destination}`);
111+
source = path.normalize(`${cwd}/${source}`);
112+
if (!fs.existsSync(destination) || force === true) {
113+
fs.copySync(source, destination);
114+
}
115+
});
116+
117+
return Promise.resolve({ action, status: 200 });
118+
},
119+
120+
package: ({ params, props, action }) => {
121+
message('updating package.json...');
122+
123+
const { cwd } = props;
124+
const newPackage = pkg(props, path.normalize(`${cwd}/tmp/update/`));
125+
const oldPackage = path.normalize(`${cwd}/package.json`);
126+
127+
fs.writeFileSync(oldPackage, newPackage);
128+
129+
return Promise.resolve({ action, status: 200 });
130+
},
131+
132+
cleanup: ({ params, props, action }) => {
133+
message('removing temp files...');
134+
135+
const { cwd } = props;
136+
137+
return new Promise((resolve, reject) => {
138+
fs.remove(path.normalize(`${cwd}/tmp`), error => {
139+
if (error) {
140+
reject(error);
141+
} else {
142+
resolve({ action, status: 200 });
143+
}
144+
});
145+
});
146+
},
147+
};
148+
};

commands/cli/run/generator.js renamed to commands/actinium/update/generator.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
const ora = require('ora');
22
const ActionSequence = require('action-sequence');
33

4-
module.exports = ({ action, params, props }) => {
4+
module.exports = ({ params, props }) => {
55
const spinner = ora({
66
spinner: 'dots',
77
color: 'cyan',
@@ -21,6 +21,7 @@ module.exports = ({ action, params, props }) => {
2121
})
2222
.catch(error => {
2323
spinner.fail('error!');
24+
console.log(error);
2425
return error;
2526
});
2627
};

0 commit comments

Comments
 (0)