Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ build/Release
# Dependency directory
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git

# & Others
node_modules
.idea
test
snippets
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ Apache License
same "printed page" as the copyright notice for easier
identification within third-party archives.

Copyright 2015 S-Core Co, Ltd.
Copyright 2016 S-Core Co, Ltd.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,18 @@ $ npm -g install ./webida-server-tools

*webida-server-tools is not a public node package yet. Do not search this package in your npm repository.*


# webida-package-manager

WPM(Webida Package Manager) is a simple tool to install/remove webida packages. Run webida-package-manager
with -h option to see help, usages.
(under construction)

To install some pacakge from a url https://github.com/webida/webida-core-package

```
$ export WEBIDA_CATALOG_DIR=(where.is.your.plugin-settings.json)
$ export WEBIDA_PACKAGE_DIR=(where.is.your.plugins)
$ webida-package-manager install https://github.com/webida/webida-core-package
```
## common options

most of tools supports following common options

Use options -c and -i not to set environment variables.
- -h (--help) : shows help message.
- -V (--version) : shows program version
- -g (--debug) : run in debug mode
- -D (--dry-run) : shows what will happens with given command

67 changes: 67 additions & 0 deletions lib/common/AbstractProgram.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* Copyright (c) 2016 S-Core Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

'use strict';

var logger = require('./logger');

class AbstractProgram {

constructor(commanderOptions) {
this._options = commanderOptions;
let globalOptions = commanderOptions.parent || commanderOptions;
this._options.configPath = globalOptions.configPath || process.env.WPM_CONFIG_PATH;
this._options.debug = globalOptions.debug || 'false';
this._options.dryRun = globalOptions.dryRun || 'false';
if (this._options.debug) {
logger.level = 'debug';
Promise.config({
warnings:true,
longStackTraces:true
});
}
}

onHelp() {
// do nothing by default. should be overrided if program wants to add help message
}

_handleOptions() {
// do nothing by default
}

// abstract. should implement by each cli programs action
main() {
let args = arguments;
this._handleOptions()
.then( () => this._main.apply(this, args) )
.then( (exitCode) => process.exit(exitCode) )
.catch(err => {
logger.error(this.constructor.name, err);
process.exit(-1);
});
}


// return promise should resolve an exit code
// should handle all error. if something is thrown, then the program has some bugs.
_main() {
logger.error(this.constructor.name + "#_main() is not implemented");
Promise.resolve(-1);
}
}

module.exports = AbstractProgram;
84 changes: 84 additions & 0 deletions lib/common/GlobbingLoader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Copyright (c) 2016 S-Core Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

'use strict';

var fs = Promise.promisifyAll(require('fs-extra'));
var globAsync = Promise.promisify(require('glob'));
var _ = require('lodash');

var logger = require('../common/logger.js');

class GlobbingLoader {

constructor(globPattern, globOptions, filter) {
this.globPattern = globPattern;
this.globOptions = globOptions;
}

loadAll() {
return new Promise((resolve, reject) => {
let allPaths;
globAsync(this.globPattern, this.globOptions)
.then(paths => {
logger.debug('loader found files ', paths);
allPaths = paths;
return Promise.map(paths, this.loadData_.bind(this));
})
.then((objects) => {
// now we have to build a map from paths to objects
let result = this._buildResultMap(allPaths, objects);
_.forOwn(result, (data, path) => {
if(!this.filterResult_(path, data)) {
delete result[path];
logger.info('loader filtered out %s', path, null);
} else {
logger.debug('loader added path %s ', path, null);
}
});
logger.debug('loaded files = %j', Object.keys(result), null);
resolve(result);
})
.catch(err => {
logger.error('loader met error ', err);
reject(err);
})
});
}

_buildResultMap(paths, objects) {
let ret = {};
for (let i=0; i < paths.length; i++) {
const path = paths[i];
const data = objects[i];
ret[path] = data;
}
return ret;
}

// should return boolean
filterResult_(relativePath, data) {
return true;
}

// should return a promise or data
loadData_(relativePath) {
return fs.readJsonAsync(relativePath);
}
}

module.exports = GlobbingLoader;

121 changes: 121 additions & 0 deletions lib/common/ShellCommandRunner.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/*
* Copyright (c) 2016 S-Core Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

'use strict';
var child_process = require('child_process');
var util = require('util');
var logger = require('./logger');

class ShellCommandResult {
constructor() {
this.code = 0;
this.signal = 0;
this.stdout = 'flowed';
this.stderr = 'flowed';
this.error = undefined;
}
}

class ShellCommandRunner {

// options are same to child_process.exec arguments
// see https://nodejs.org/api/child_process.html
// additional options are
constructor(command, args, options) {
this.command = command || null;
this.args = args || [];
this.options = options || {};
this.shellCommand = this._makeShellCommand();
this.pid = 0;
}

spawn(resolveAlways) {
let result = new ShellCommandResult();
return new Promise( (resolve, reject) => {
this.options.stdio = this.options.stdio || 'inherit';
let spawned = child_process.spawn(this.command, this.args, this.options);
this.pid = spawned.pid;
logger.debug("spawnned shell command %s (%d) with args %j, options %j",
this.command, this.pid, this.args, this.options, {});
spawned.on('error', (err) => {
logger.error('spawned child %d got error', spawned.pid, err );
result.error = err;
});
spawned.on('close', (code, signal) => {
logger.debug('spawned child %d completed with exit code %d, signal %d', spawned.pid, code, signal,{} );
this._logFinish(code);
result.code = code;
result.signal = signal;
if(!resolveAlways && (code || result.error)) {
reject(result);
} else {
resolve(result);
}
});
this._logStart();
});
}

exec(resolveAlways) {
let result = new ShellCommandResult();
return new Promise( (resolve, reject) => {
let executed = child_process.exec(this.shellCommand, this.options, (err, stdout, stderr) => {
this._logFinish(err? err.code : 0);
result.stdout = stdout;
result.stderr = stderr;
if (err) {
result.error = err;
result.code = err.code;
result.signal = err.signal;
if (resolveAlways) {
logger.debug("ignoring error %j", err);
resolve(err);
} else {
reject(result);
}
} else {
resolve (result);
}
});
this.pid = executed.pid;
logger.debug('executed shell command [%s] with options %j', this.shellCommand, this.options);
this._logStart();

});
}

_logStart() {
logger.info("start running command %s (pid %d)", this.shellCommand, this.pid, null);
};

_logFinish(exitCode) {
logger.info("finish running command %s (pid %d, exit code %d)", this.command, this.pid, exitCode, null);
}

_makeShellCommand() {
let argv = [this.command];
for(let arg of this.args) {
if (arg.indexOf(' ') >=0) {

arg = '"' + arg + '"';
}
argv.push(arg);
}
return argv.join(' ');
}
}

module.exports = ShellCommandRunner;
29 changes: 29 additions & 0 deletions lib/common/logger.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright (c) 2016 S-Core Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';

var winston = require('winston');

let logger = new winston.Logger({
transports : [
new winston.transports.Console()
]
});

logger.cli();
logger.level = 'info';

module.exports = logger;
Loading