finally moved the CLI to argv.js... still not done

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2020-12-08 18:35:50 +03:00
parent 2a5e490117
commit d19b678b37
5 changed files with 113 additions and 235 deletions

View File

@ -32,6 +32,7 @@ var requirejs_cfg = {
//'lib/keyboard': './node_modules/ig-keyboard/keyboard', //'lib/keyboard': './node_modules/ig-keyboard/keyboard',
'object-run': 'node_modules/object-run/run', 'object-run': 'node_modules/object-run/run',
'lib/argv': 'node_modules/ig-argv/argv',
'lib/walk': 'node_modules/generic-walk/walk', 'lib/walk': 'node_modules/generic-walk/walk',
}, },
map: { map: {
@ -46,6 +47,7 @@ var requirejs_cfg = {
//'ig-keyboard': 'lib/keyboard', //'ig-keyboard': 'lib/keyboard',
'ig-argv': 'lib/argv',
'generic-walk': 'lib/walk', 'generic-walk': 'lib/walk',
}, },
}, },

View File

@ -20,6 +20,7 @@ var base = require('features/base')
if(typeof(process) != 'undefined'){ if(typeof(process) != 'undefined'){
var pathlib = requirejs('path') var pathlib = requirejs('path')
var argv = requirejs('lib/argv')
} }
@ -53,12 +54,11 @@ if(typeof(process) != 'undefined'){
var CLIActions = actions.Actions({ var CLIActions = actions.Actions({
get cli_commands(){ get cliActions(){
return this.actions return this.actions
.filter(function(action){ .filter(function(action){
return this.getActionAttr(action, 'cli') }.bind(this)) }, return this.getActionAttr(action, 'cli') }.bind(this)) },
// XXX should this be here??? // XXX should this be here???
// ...move this to progress... // ...move this to progress...
__progress: null, __progress: null,
@ -96,37 +96,71 @@ var CLIActions = actions.Actions({
state.msg = msg state.msg = msg
}], }],
startREPL: ['- System/Start CLI interpreter',
{cli: '@repl'},
function(){
var repl = nodeRequire('repl')
makeIndex: ['- System/', this._keep_running = true
{cli: true},
// setup the global ns...
global.ig =
global.ImageGrid =
this
require('features/all')
global.ImageGridFeatures = core.ImageGridFeatures
//var ig = core.ImageGridFeatures
repl
.start({
prompt: 'ig> ',
useGlobal: true,
input: process.stdin,
output: process.stdout,
//ignoreUndefined: true,
})
.on('exit', function(){
//ig.stop()
process.exit() }) }],
startGUI: ['- System/Start viewer GUI',
{cli: '@gui'},
function(){
// XXX
}],
// XXX this is reletively generic, might be useful globally...
makeIndex: ['- System/Make index',
{cli: {
name: '@make',
arg: 'PATH',
valueRequired: true,
}},
function(path){ function(path){
var that = this var that = this
// XXX is this correct???
path = path || this.location.path
path = util.normalizePath(path) path = util.normalizePath(path)
return this.loadImages(path) // XXX is cloning index here the correct way to go???
//var index = this.clone()
var index = this
return index.loadImages(path)
// save base index... // save base index...
.then(function(){ .then(function(){
return that.saveIndex(path) return index.saveIndex() })
}) // sharp stuff...
// make the previews...
.then(function(){ .then(function(){
if(that.makePreviews){ if(index.makePreviews){
return that.makePreviews('all') return Promise.all([
} index.cacheMetadata('all'),
}) index.makePreviews('all') ])} })
.then(function(){ .then(function(){
//that.readAllMetadata() return index
return that
.sortImages() .sortImages()
// XXX for some reason this is not running from cli .saveIndex() }) }],
.saveIndex(path)
})
}],
}) })
@ -150,222 +184,63 @@ module.CLI = core.ImageGridFeatures.Feature({
actions: CLIActions, actions: CLIActions,
handlers: [ handlers: [
// XXX should some of the flag handlers be actions???
['ready', ['ready',
function(){ function(){
var that = this var that = this
// get the arguments... var pkg = nodeRequire('./package.json')
if(this.runtime.nw){
var argv = nw.App.argv
// XXX appears to have a stray '--help' lodged in argv.Parser({
// all the time... // XXX argv.js is not picking these up because
// ...need to test this with a packed exec... // of the require(..) mixup...
console.log('>>>>', argv) author: pkg.author,
version: pkg.version,
license: pkg.license,
} else if(this.runtime.node){ // XXX setup presets...
var argv = process.argv // ...load sets of features and allow user
// to block/add specific features...
// XXX feature config...
// ...get/set persistent config values...
// build the action command list...
...this.cliActions
.reduce(function(res, action){
var cmd = that.getActionAttr(action, 'cli')
if(typeof(cmd) == typeof('str') || cmd === true){
var name = cmd
var cmd = {name} }
var name = name === true ?
action
: cmd.name
res[name] = {
doc: (that.getActionAttr(action, 'doc') || '')
.split(/[\\\/]/g).pop(),
// XXX revise argument passing...
// ...this must be as flexible as possible...
handler: function(rest, key, value){
return that[action](value) },
...cmd,
} }
return res }, {}),
var keep_running = false
// XXX this is not portable...
//var package = requirejs('fs-extra').readJSONSync('./package.json')
// XXX DEPRECATED...
var cli = requirejs('commander')
cli
// XXX get the version from package.json...
.version(that.version)
//.usage('[command] [options] ..')
.option('-v, --verbose', 'verbose mode', function(){
// XXX use a standard logger...
that.logger = {
root: true,
push: function(){
var o = Object.create(this)
o.root = false
o.__prefix = (this.__prefix || []).concat([...arguments])
return o
},
pop: function(){
return this.root ? this : this.__proto__
},
emit: function(){
console.log.apply(console,
(this.__prefix || []).concat([...arguments]))
},
}
}) })
.onNoArgs(function(args){
console.log('No args.')
.option('l, --list-commands', 'list commands', function(){ // XXX we should either start the GUI here or print help...
console.log('Commands:\n ', that.cli_commands.join('\n\t')) args.push('--help')
//args.push('gui')
}) })
.then(function(){
// list features...
// XXX make this a core action... (???)
.option('lf, --list-features', 'list loaded features', function(){
// excluded...
that.features.excluded.length > 0
&& console.warn('Features excluded (%d):\n ',
that.features.excluded.length,
that.features.excluded.join('\n '))
// not applicable...
that.features.unapplicable.length > 0
&& console.log('Features not applicable (%d):\n ',
that.features.unapplicable.length,
that.features.unapplicable.join('\n '))
// loaded...
console.log('Features loaded (%d):\n ',
that.features.features.length,
that.features.features.join('\n '))
})
// XXX make this applicable features...
.option('laf, --list-available-features', 'list available features', function(){
// XXX bug, this hangs....
//console.log(core.ImageGridFeatures.buildFeatureList())
var f = core.ImageGridFeatures.features
console.log('Features available (%d):\n ',
f.length,
f.join('\n '))
})
// list actions...
// XXX this is a bit pointless as single actions are
// meaningless when no state is stored...
.option('la, --list-actions', 'list loaded actions', function(){
console.log('Actions loaded (%d):\n ',
that.length,
Object.keys(that.getDoc()).join('\n '))
})
// XXX experimental....
// to see this in action use:
// ig lf sm lf
// ...this will print the list of features before
// and after setup...
.option('sm, --setup-minimal', 'setup minimal features', function(){
// load features we might need...
var all = require('features/all')
// extend the current instance to a minimal non-ui
// state...
core.ImageGridFeatures
.setup(that, ['imagegrid-minimal'])
})
.option('repl, --repl', 'start an ImageGrid REPL', function(){
var repl = nodeRequire('repl')
keep_running = true
// setup the global ns...
global.ig =
global.ImageGrid =
that
require('features/all')
global.ImageGridFeatures = core.ImageGridFeatures
//var ig = core.ImageGridFeatures
repl
.start({
prompt: 'ig> ',
useGlobal: true,
input: process.stdin,
output: process.stdout,
//ignoreUndefined: true,
})
.on('exit', function(){
ig.stop()
})
})
// XXX this needs both a local/linked nwjs installed and an
// appropriate nw version under it...
// npm install -g nwjs
// npm link nwjs
// nw install 0.14.5-sdk
.option('nw, --nw', 'start ImageGrid.Viewer (nw)', function(){
throw new Error('ig: GUI startup not implemented.')
var path = requirejs('path')
requirejs('child_process')
.spawn(requirejs('nwjs'), [
path.dirname(process.argv[1]).replace(/\\/g, '/') + '/'])
keep_running = true
})
.option('electron, --electron', 'start ImageGrid.Viewer (electron)', function(){
var path = requirejs('path')
requirejs('child_process')
.spawn(requirejs('electron'), [
path.join(
path.dirname(nodeRequire.main.filename),
'e.js')])
// XXX need to stop the process iff nothing
// else is running, like repl...
// XXX feels hackish...
.on('exit', function(){
(!global.ig
|| global.ig.isStopped())
&& process.exit()
})
keep_running = true
})
/* // XXX the problem with this is that it still tires
// to find and run 'ig-index'...
.command('index [path]', 'build an index of path')
.action(function(path){
console.log('!!!!!! INDEX', path)
//this.makeIndex(path)
})
//*/
// XXX might be a good idea to make the action call
// syntax like this:
// --<action-name> [args]
.arguments('<action> [args]')
.action(function(action, args){
// XXX // XXX
//console.log('>>>>', action, args, !!that[action]) })()
if(!that[action]){
console.error('No such action:', action)
return
}
var res = that[action](args)
if(res instanceof Promise){
keep_running = true
res.then(function(){
process.exit()
})
}
})
.parse(argv)
// XXX is this the right way to trigger state change // XXX is this the right way to trigger state change
// from within a state action... // from within a state action...
!keep_running !this._keep_running
&& this.afterAction(function(){ process.exit() }) && this.afterAction(function(){ process.exit() })
}], }],
], ],

View File

@ -676,7 +676,8 @@ var LifeCycleActions = actions.Actions({
`, `,
function(){ function(){
var that = this var that = this
this.logger && this.logger.emit('start') this.logger
&& this.logger.push('System').emit('start')
// NOTE: jQuery currently provides no way to check if an event // NOTE: jQuery currently provides no way to check if an event
// is bound so we'll need to keep track manually... // is bound so we'll need to keep track manually...
@ -819,8 +820,8 @@ var LifeCycleActions = actions.Actions({
// System ready event... // System ready event...
// //
// Not intended for direct use, use .declareReady() to initiate. // Not intended for direct use, use .declareReady() to initiate.
this.logger && this.logger.emit('ready') this.logger
})], && this.logger.push('System').emit('ready') })],
// NOTE: this calls .ready() once per session. // NOTE: this calls .ready() once per session.
declareReady: ['- System/Declare system ready', declareReady: ['- System/Declare system ready',
doc`Declare ready state doc`Declare ready state
@ -913,7 +914,8 @@ var LifeCycleActions = actions.Actions({
delete this.__ready delete this.__ready
delete this.__stop_handler delete this.__stop_handler
this.logger && this.logger.emit('stop') this.logger
&& this.logger.push('System').emit('stop')
// trigger the stopped event... // trigger the stopped event...
this.stopped() this.stopped()

View File

@ -1081,9 +1081,9 @@
} }
}, },
"ig-argv": { "ig-argv": {
"version": "2.15.0", "version": "2.15.1",
"resolved": "https://registry.npmjs.org/ig-argv/-/ig-argv-2.15.0.tgz", "resolved": "https://registry.npmjs.org/ig-argv/-/ig-argv-2.15.1.tgz",
"integrity": "sha512-Y9x7B96bq0T6yXIIMYJ6f3V9j7wOJjwpXytA8QpZn1LTM2D4C+YG2Ljl/rj+fhw29q42GNbZyVPsHsISPYVpsw==", "integrity": "sha512-BJ0j6aoIkWVjXEVZ/A+U4FTn4DYqthZ5W0XwOQYkeuR85FXVZuAFo1Ugdz6DJp3J7WrdpVRXQpIFDRobB84eZw==",
"requires": { "requires": {
"ig-object": "^5.2.6" "ig-object": "^5.2.6"
} }
@ -1110,9 +1110,9 @@
"integrity": "sha512-9kZM80Js9/eTwXN9VXwLDC1wDJ7gIAdYU9GIzb5KJmNcLAMaW+zhgFrwFFMrcSfggUuadgnqSrS41E4XLe8JZw==" "integrity": "sha512-9kZM80Js9/eTwXN9VXwLDC1wDJ7gIAdYU9GIzb5KJmNcLAMaW+zhgFrwFFMrcSfggUuadgnqSrS41E4XLe8JZw=="
}, },
"ig-types": { "ig-types": {
"version": "5.0.39", "version": "5.0.40",
"resolved": "https://registry.npmjs.org/ig-types/-/ig-types-5.0.39.tgz", "resolved": "https://registry.npmjs.org/ig-types/-/ig-types-5.0.40.tgz",
"integrity": "sha512-Tqha0RCPFm2rlcmsBSb9RyhUBK4qNAhtCIqmWeq/k0StiotC9EddqlFOXuJvKtFBSKFYorRYAv+rewXP3Y3YYQ==", "integrity": "sha512-L2tUujoojQ8rQB+grMN5BafvCRxZ94tm1GrJaxTjfGOzkDeSfFdoOXfmk1BIkrJb62DLxO6SmA1lKdf7S/4WWQ==",
"requires": { "requires": {
"ig-object": "^5.4.12", "ig-object": "^5.4.12",
"object-run": "^1.0.1" "object-run": "^1.0.1"

View File

@ -29,10 +29,10 @@
"glob": "^7.1.6", "glob": "^7.1.6",
"guarantee-events": "^1.0.0", "guarantee-events": "^1.0.0",
"ig-actions": "^3.24.21", "ig-actions": "^3.24.21",
"ig-argv": "^2.15.0", "ig-argv": "^2.15.1",
"ig-features": "^3.4.2", "ig-features": "^3.4.2",
"ig-object": "^5.4.12", "ig-object": "^5.4.12",
"ig-types": "^5.0.39", "ig-types": "^5.0.40",
"moment": "^2.29.1", "moment": "^2.29.1",
"object-run": "^1.0.1", "object-run": "^1.0.1",
"requirejs": "^2.3.6", "requirejs": "^2.3.6",
@ -44,7 +44,6 @@
}, },
"dependencies-disabled": { "dependencies-disabled": {
"openseadragon": "^2.4.1", "openseadragon": "^2.4.1",
"commander": "^2.20.3",
"flickrapi": "^0.3.28" "flickrapi": "^0.3.28"
}, },
"optionalDependencies": { "optionalDependencies": {