Skip to content

Commit b634b80

Browse files
committed
Initial Commit ✨
0 parents  commit b634b80

12 files changed

Lines changed: 322 additions & 0 deletions

File tree

.editorconfig

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
root = true
2+
3+
[*]
4+
end_of_line = lf
5+
insert_final_newline = true
6+
charset = utf-8
7+
indent_style = space
8+
indent_size = 2

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.DS_Store
2+
node_modules/
3+
npm-debug.log

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2016 Vu Tran <vu@vu-tran.com>
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Dext CLI
2+
3+
> [Dext](https://github.com/vutran/dext) command-line interface tool.
4+
5+
![](screenshot.png?raw=true)
6+
7+
## Install
8+
9+
```bash
10+
$ dpm install -g dext-cli
11+
```
12+
13+
*Requires [Dext](https://github.com/vutran/dext).*
14+
15+
## Usage
16+
17+
```bash
18+
# installs a new plugin/theme
19+
$ dpm install dext-my-plugin
20+
21+
# uninstalls an existing plugin/theme
22+
$ dpm uninstall dext-my-plugin
23+
24+
# sets a new theme
25+
$ dpm theme dext-my-theme
26+
```
27+
28+
## Related
29+
30+
- [dext](https://github.com/vutran/dext) - The Dext smart launcher
31+
32+
## License
33+
34+
MIT © [Vu Tran](https://github.com/vutran/)

api/errors.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
exports.ERR_MODULE_NOT_FOUND = 'ERR_MODULE_NOT_FOUND';
2+
exports.ERR_MODULE_INSTALLED = 'ERR_MODULE_INSTALLED';
3+
exports.ERR_MODULE_NOT_INSTALLED = 'ERR_MODULE_NOT_INSTALLED';
4+
exports.ERR_THEME_ALREADY_ACTIVE = 'ERR_THEME_ALREADY_ACTIVE';

api/index.js

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
const path = require('path');
2+
const { spawn } = require('child_process');
3+
const rimraf = require('rimraf');
4+
const npmName = require('npm-name');
5+
const {
6+
ERR_MODULE_NOT_FOUND,
7+
ERR_MODULE_INSTALLED,
8+
ERR_MODULE_NOT_INSTALLED,
9+
ERR_THEME_ALREADY_ACTIVE,
10+
} = require('./errors');
11+
const Conf = require('../utils/conf');
12+
const { downloadPackage } = require('../utils/download');
13+
const { PLUGIN_PATH } = require('../utils/paths');
14+
15+
const config = new Conf();
16+
17+
/**
18+
* Checks if it exists on npm
19+
*
20+
* @param {String} plugin - The name of the plugin
21+
* @return {Promise}
22+
*/
23+
const checkOnNpm = plugin => new Promise(resolve => {
24+
npmName(plugin).then(available => {
25+
if (available) {
26+
throw new Error(ERR_MODULE_NOT_FOUND);
27+
}
28+
resolve();
29+
});
30+
});
31+
32+
/**
33+
* Installs a plugin
34+
*
35+
* @param {String} plugin - The name of the plugin
36+
* @return {Promise}
37+
*/
38+
const install = plugin => new Promise(resolve => {
39+
const plugins = config.get('plugins') || [];
40+
41+
if (plugins.indexOf(plugin) > -1) {
42+
throw new Error(ERR_MODULE_INSTALLED);
43+
}
44+
45+
checkOnNpm(plugin).then(() => {
46+
// download, install, and update configs
47+
downloadPackage(plugin).then(outputDir => {
48+
const installProcess = spawn('npm', ['install', '--prefix', outputDir]);
49+
installProcess.on('close', (code) => {
50+
if (!code) {
51+
plugins.push(plugin);
52+
config.set('plugins', plugins);
53+
resolve();
54+
}
55+
});
56+
});
57+
});
58+
});
59+
60+
/**
61+
* Uninstalls a plugin
62+
*
63+
* @param {String} plugin - The name of the plugin
64+
* @return {Promise}
65+
*/
66+
const uninstall = plugin => new Promise(resolve => {
67+
const plugins = config.get('plugins') || [];
68+
69+
if (!plugins || !plugins.length) {
70+
throw new Error(ERR_MODULE_NOT_INSTALLED);
71+
}
72+
73+
if (plugins.indexOf(plugin) === -1) {
74+
throw new Error(ERR_MODULE_NOT_INSTALLED);
75+
}
76+
77+
// removes the directory
78+
const pluginDir = path.resolve(PLUGIN_PATH, plugin);
79+
rimraf(pluginDir, err => {
80+
if (err) {
81+
throw new Error(err);
82+
}
83+
plugins.splice(plugins.indexOf(plugin), 1);
84+
config.set('plugins', plugins);
85+
resolve();
86+
});
87+
});
88+
89+
/**
90+
* Switches your current theme
91+
*
92+
* @param {String} theme - The name of the theme
93+
* @return {Promise}
94+
*/
95+
const setTheme = theme => new Promise(resolve => {
96+
const currentTheme = config.get('theme');
97+
const plugins = config.get('plugins') || [];
98+
99+
if (currentTheme === theme) {
100+
throw new Error(ERR_THEME_ALREADY_ACTIVE);
101+
}
102+
103+
if (!plugins || !plugins.length) {
104+
throw new Error(ERR_MODULE_NOT_INSTALLED);
105+
}
106+
107+
if (plugins.indexOf(theme) === -1) {
108+
throw new Error(ERR_MODULE_NOT_INSTALLED);
109+
}
110+
111+
config.set('theme', theme);
112+
113+
resolve();
114+
});
115+
116+
module.exports = {
117+
checkOnNpm,
118+
install,
119+
uninstall,
120+
setTheme,
121+
};

cli.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#!/usr/bin/env node
2+
3+
const args = require('args');
4+
const chalk = require('chalk');
5+
const api = require('./api');
6+
7+
args.command(['install', 'i'], 'Install a new plugin or theme', (name, sub) => {
8+
const plugin = sub[0];
9+
return api.install(plugin)
10+
.then(() => console.log(chalk.green(`${plugin} installed successfully!`)))
11+
.catch(err => console.error(chalk.red(err)));
12+
});
13+
14+
args.command(['uninstall', 'u'], 'Uninstall a plugin or theme', (name, sub) => {
15+
const plugin = sub[0];
16+
return api.uninstall(plugin)
17+
.then(() => console.log(chalk.green(`${plugin} uninstalled successfully!`)))
18+
.catch(err => console.error(chalk.red(err)));
19+
});
20+
21+
args.command(['theme', 't'], 'Sets a theme', (name, sub) => {
22+
const theme = sub[0];
23+
return api.setTheme(theme)
24+
.then(() => console.log(chalk.green(`${theme} has been set successfully!`)))
25+
.catch(err => console.error(chalk.red(err)));
26+
});
27+
28+
const flags = args.parse(process.argv);
29+
30+
if (Object.keys(flags).length !== 0) {
31+
args.showHelp();
32+
}

package.json

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
"name": "dext-cli",
3+
"version": "0.0.0",
4+
"description": "",
5+
"main": "./cli.js",
6+
"scripts": {
7+
"lint": "eslint app"
8+
},
9+
"bin": {
10+
"dpm": "./cli.js"
11+
},
12+
"author": "Vu Tran <vu@vu-tran.com>",
13+
"repository": {
14+
"type": "git",
15+
"url": "https://github.com/vutran/dext"
16+
},
17+
"license": "MIT",
18+
"dependencies": {
19+
"args": "^2.0.0",
20+
"conf": "^0.11.2",
21+
"download": "^5.0.2",
22+
"npm-name": "^3.0.0",
23+
"rimraf": "^2.5.4"
24+
},
25+
"devDependencies": {
26+
"eslint": "^3.4.0",
27+
"eslint-config-airbnb": "^10.0.1",
28+
"eslint-plugin-import": "^1.14.0",
29+
"eslint-plugin-jsx-a11y": "^2.2.0",
30+
"eslint-plugin-react": "^6.2.0"
31+
}
32+
}

screenshot.png

29.7 KB
Loading

utils/conf.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
const Conf = require('conf');
2+
const { DEXT_PATH } = require('./paths');
3+
4+
module.exports = class extends Conf {
5+
constructor(opts) {
6+
const defaultOpts = {
7+
defaults: {
8+
theme: '',
9+
plugins: [],
10+
},
11+
};
12+
const o = Object.assign({}, opts, defaultOpts);
13+
o.cwd = DEXT_PATH;
14+
super(o);
15+
}
16+
};

0 commit comments

Comments
 (0)