Browse Source

AmberCli: not existing commands now print the help message

Manfred Kroehnert 11 years ago
parent
commit
491bfb150d
4 changed files with 77 additions and 58 deletions
  1. 18 9
      cli/js/AmberCli.deploy.js
  2. 21 12
      cli/js/AmberCli.js
  3. 23 28
      cli/js/amber-cli.js
  4. 15 9
      cli/st/AmberCli.st

+ 18 - 9
cli/js/AmberCli.deploy.js

@@ -32,13 +32,13 @@ smalltalk.method({
 selector: "handleArguments:",
 fn: function (args){
 var self=this;
-var command;
+var selector;
 function $Array(){return smalltalk.Array||(typeof Array=="undefined"?nil:Array)}
 return smalltalk.withContext(function($ctx1) { 
-command=_st(self)._selectorForCommandLineSwitch_(_st(args)._first());
+selector=_st(self)._selectorForCommandLineSwitch_(_st(args)._first());
 _st(args)._remove_(_st(args)._first());
-_st(self)._perform_withArguments_(command,_st($Array())._with_(args));
-return self}, function($ctx1) {$ctx1.fill(self,"handleArguments:",{args:args,command:command},smalltalk.AmberCli.klass)})},
+_st(self)._perform_withArguments_(selector,_st($Array())._with_(args));
+return self}, function($ctx1) {$ctx1.fill(self,"handleArguments:",{args:args,selector:selector},smalltalk.AmberCli.klass)})},
 messageSends: ["selectorForCommandLineSwitch:", "first", "remove:", "perform:withArguments:", "with:"]}),
 smalltalk.AmberCli.klass);
 
@@ -97,15 +97,24 @@ smalltalk.method({
 selector: "selectorForCommandLineSwitch:",
 fn: function (aSwitch){
 var self=this;
+var command,selector;
 return smalltalk.withContext(function($ctx1) { 
-var $1;
-$1=_st(_st(aSwitch)._replace_with_("-[a-z]",(function(each){
+var $1,$2;
+$1=_st(_st(self)._commandLineSwitches())._includes_(aSwitch);
+if(smalltalk.assert($1)){
+selector=_st(_st(aSwitch)._replace_with_("-[a-z]",(function(each){
 return smalltalk.withContext(function($ctx2) {
 return _st(_st(each)._second())._asUppercase();
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}))).__comma(":");
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"selectorForCommandLineSwitch:",{aSwitch:aSwitch},smalltalk.AmberCli.klass)})},
-messageSends: [",", "replace:with:", "asUppercase", "second"]}),
+selector;
+} else {
+selector="help:";
+selector;
+};
+$2=selector;
+return $2;
+}, function($ctx1) {$ctx1.fill(self,"selectorForCommandLineSwitch:",{aSwitch:aSwitch,command:command,selector:selector},smalltalk.AmberCli.klass)})},
+messageSends: ["ifTrue:ifFalse:", ",", "replace:with:", "asUppercase", "second", "includes:", "commandLineSwitches"]}),
 smalltalk.AmberCli.klass);
 
 smalltalk.addMethod(

+ 21 - 12
cli/js/AmberCli.js

@@ -1,6 +1,6 @@
 smalltalk.addPackage('AmberCli');
 smalltalk.addClass('AmberCli', smalltalk.Object, [], 'AmberCli');
-smalltalk.AmberCli.comment="I am the Amber CLI (CommandLine Interface) tool which runs on Node.js.\x0a\x0aMy responsibility is to start different Amber programs like the FileServer or the Repl.\x0aWhich program to start is determined by the first commandline parameters passed to the AmberCli executable.\x0aUse `help` to get a list of all available options.\x0aAny further commandline parameters are passed to the specific program.\x0a\x0a## Commands\x0a\x0aNew commands can be added by creating a unary class side method in the `commands` protocol.\x0aAny `camelCaseCommand` is transformed into a commandline parameter of the form `camel-case-command` and vice versa."
+smalltalk.AmberCli.comment="I am the Amber CLI (CommandLine Interface) tool which runs on Node.js.\x0a\x0aMy responsibility is to start different Amber programs like the FileServer or the Repl.\x0aWhich program to start is determined by the first commandline parameters passed to the AmberCli executable.\x0aUse `help` to get a list of all available options.\x0aAny further commandline parameters are passed to the specific program.\x0a\x0a## Commands\x0a\x0aNew commands can be added by creating a class side method in the `commands` protocol which takes one parameter.\x0aThis parameter is an array of all commandline options + values passed on to the program.\x0aAny `camelCaseCommand` is transformed into a commandline parameter of the form `camel-case-command` and vice versa."
 
 smalltalk.addMethod(
 smalltalk.method({
@@ -39,15 +39,15 @@ selector: "handleArguments:",
 category: 'commandline',
 fn: function (args){
 var self=this;
-var command;
+var selector;
 function $Array(){return smalltalk.Array||(typeof Array=="undefined"?nil:Array)}
 return smalltalk.withContext(function($ctx1) { 
-command=_st(self)._selectorForCommandLineSwitch_(_st(args)._first());
+selector=_st(self)._selectorForCommandLineSwitch_(_st(args)._first());
 _st(args)._remove_(_st(args)._first());
-_st(self)._perform_withArguments_(command,_st($Array())._with_(args));
-return self}, function($ctx1) {$ctx1.fill(self,"handleArguments:",{args:args,command:command},smalltalk.AmberCli.klass)})},
+_st(self)._perform_withArguments_(selector,_st($Array())._with_(args));
+return self}, function($ctx1) {$ctx1.fill(self,"handleArguments:",{args:args,selector:selector},smalltalk.AmberCli.klass)})},
 args: ["args"],
-source: "handleArguments: args\x0a\x09| command |\x0a\x09command := self selectorForCommandLineSwitch: (args first).\x0a\x09args remove: args first.\x0a\x09self perform: command  withArguments: (Array with: args).",
+source: "handleArguments: args\x0a\x09| selector |\x0a\x0a\x09selector := self selectorForCommandLineSwitch: (args first).\x0a\x09args remove: args first.\x0a\x09self perform: selector  withArguments: (Array with: args)",
 messageSends: ["selectorForCommandLineSwitch:", "first", "remove:", "perform:withArguments:", "with:"],
 referencedClasses: ["Array"]
 }),
@@ -124,17 +124,26 @@ selector: "selectorForCommandLineSwitch:",
 category: 'commandline',
 fn: function (aSwitch){
 var self=this;
+var command,selector;
 return smalltalk.withContext(function($ctx1) { 
-var $1;
-$1=_st(_st(aSwitch)._replace_with_("-[a-z]",(function(each){
+var $1,$2;
+$1=_st(_st(self)._commandLineSwitches())._includes_(aSwitch);
+if(smalltalk.assert($1)){
+selector=_st(_st(aSwitch)._replace_with_("-[a-z]",(function(each){
 return smalltalk.withContext(function($ctx2) {
 return _st(_st(each)._second())._asUppercase();
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}))).__comma(":");
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"selectorForCommandLineSwitch:",{aSwitch:aSwitch},smalltalk.AmberCli.klass)})},
+selector;
+} else {
+selector="help:";
+selector;
+};
+$2=selector;
+return $2;
+}, function($ctx1) {$ctx1.fill(self,"selectorForCommandLineSwitch:",{aSwitch:aSwitch,command:command,selector:selector},smalltalk.AmberCli.klass)})},
 args: ["aSwitch"],
-source: "selectorForCommandLineSwitch: aSwitch\x0a\x09\x22Add ':' at the end\x0a\x09 and replace all occurences of a lowercase letter preceded by a '-' with\x0a\x09 the Uppercase letter.\x0a\x09 Example: fallback-page becomes fallbackPage:\x22\x0a\x09^(aSwitch replace: '-[a-z]' with: [ :each | each second asUppercase ]), ':'",
-messageSends: [",", "replace:with:", "asUppercase", "second"],
+source: "selectorForCommandLineSwitch: aSwitch\x0a\x09\x22Add ':' at the end and replace all occurences of a lowercase letter preceded by a '-' with the Uppercase letter.\x0a\x09 Example: fallback-page becomes fallbackPage:.\x0a\x09 If no correct selector is found return 'help:'\x22\x0a\x09 | command selector |\x0a\x0a\x09 (self commandLineSwitches includes: aSwitch)\x0a\x09 ifTrue: [ selector := (aSwitch replace: '-[a-z]' with: [ :each | each second asUppercase ]), ':']\x0a\x09 ifFalse: [ selector := 'help:' ].\x0a\x09^selector",
+messageSends: ["ifTrue:ifFalse:", ",", "replace:with:", "asUppercase", "second", "includes:", "commandLineSwitches"],
 referencedClasses: []
 }),
 smalltalk.AmberCli.klass);

+ 23 - 28
cli/js/amber-cli.js

@@ -16782,6 +16782,7 @@ smalltalk.addClass('ProtocolRemoved', smalltalk.ProtocolAnnouncement, [], 'Kerne
 
 smalltalk.addPackage('AmberCli');
 smalltalk.addClass('AmberCli', smalltalk.Object, [], 'AmberCli');
+smalltalk.AmberCli.comment="I am the Amber CLI (CommandLine Interface) tool which runs on Node.js.\x0a\x0aMy responsibility is to start different Amber programs like the FileServer or the Repl.\x0aWhich program to start is determined by the first commandline parameters passed to the AmberCli executable.\x0aUse `help` to get a list of all available options.\x0aAny further commandline parameters are passed to the specific program.\x0a\x0a## Commands\x0a\x0aNew commands can be added by creating a class side method in the `commands` protocol which takes one parameter.\x0aThis parameter is an array of all commandline options + values passed on to the program.\x0aAny `camelCaseCommand` is transformed into a commandline parameter of the form `camel-case-command` and vice versa."
 
 smalltalk.addMethod(
 smalltalk.method({
@@ -16820,15 +16821,15 @@ selector: "handleArguments:",
 category: 'commandline',
 fn: function (args){
 var self=this;
-var command;
+var selector;
 function $Array(){return smalltalk.Array||(typeof Array=="undefined"?nil:Array)}
 return smalltalk.withContext(function($ctx1) { 
-command=_st(self)._selectorForCommandLineSwitch_(_st(args)._first());
+selector=_st(self)._selectorForCommandLineSwitch_(_st(args)._first());
 _st(args)._remove_(_st(args)._first());
-_st(self)._perform_withArguments_(command,_st($Array())._with_(args));
-return self}, function($ctx1) {$ctx1.fill(self,"handleArguments:",{args:args,command:command},smalltalk.AmberCli.klass)})},
+_st(self)._perform_withArguments_(selector,_st($Array())._with_(args));
+return self}, function($ctx1) {$ctx1.fill(self,"handleArguments:",{args:args,selector:selector},smalltalk.AmberCli.klass)})},
 args: ["args"],
-source: "handleArguments: args\x0a\x09| command |\x0a\x09command := self selectorForCommandLineSwitch: (args first).\x0a\x09args remove: args first.\x0a\x09self perform: command  withArguments: (Array with: args).",
+source: "handleArguments: args\x0a\x09| selector |\x0a\x0a\x09selector := self selectorForCommandLineSwitch: (args first).\x0a\x09args remove: args first.\x0a\x09self perform: selector  withArguments: (Array with: args)",
 messageSends: ["selectorForCommandLineSwitch:", "first", "remove:", "perform:withArguments:", "with:"],
 referencedClasses: ["Array"]
 }),
@@ -16905,17 +16906,26 @@ selector: "selectorForCommandLineSwitch:",
 category: 'commandline',
 fn: function (aSwitch){
 var self=this;
+var command,selector;
 return smalltalk.withContext(function($ctx1) { 
-var $1;
-$1=_st(_st(aSwitch)._replace_with_("-[a-z]",(function(each){
+var $1,$2;
+$1=_st(_st(self)._commandLineSwitches())._includes_(aSwitch);
+if(smalltalk.assert($1)){
+selector=_st(_st(aSwitch)._replace_with_("-[a-z]",(function(each){
 return smalltalk.withContext(function($ctx2) {
 return _st(_st(each)._second())._asUppercase();
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}))).__comma(":");
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"selectorForCommandLineSwitch:",{aSwitch:aSwitch},smalltalk.AmberCli.klass)})},
+selector;
+} else {
+selector="help:";
+selector;
+};
+$2=selector;
+return $2;
+}, function($ctx1) {$ctx1.fill(self,"selectorForCommandLineSwitch:",{aSwitch:aSwitch,command:command,selector:selector},smalltalk.AmberCli.klass)})},
 args: ["aSwitch"],
-source: "selectorForCommandLineSwitch: aSwitch\x0a\x09\x22Add ':' at the end\x0a\x09 and replace all occurences of a lowercase letter preceded by a '-' with\x0a\x09 the Uppercase letter.\x0a\x09 Example: fallback-page becomes fallbackPage:\x22\x0a\x09^(aSwitch replace: '-[a-z]' with: [ :each | each second asUppercase ]), ':'",
-messageSends: [",", "replace:with:", "asUppercase", "second"],
+source: "selectorForCommandLineSwitch: aSwitch\x0a\x09\x22Add ':' at the end and replace all occurences of a lowercase letter preceded by a '-' with the Uppercase letter.\x0a\x09 Example: fallback-page becomes fallbackPage:.\x0a\x09 If no correct selector is found return 'help:'\x22\x0a\x09 | command selector |\x0a\x0a\x09 (self commandLineSwitches includes: aSwitch)\x0a\x09 ifTrue: [ selector := (aSwitch replace: '-[a-z]' with: [ :each | each second asUppercase ]), ':']\x0a\x09 ifFalse: [ selector := 'help:' ].\x0a\x09^selector",
+messageSends: ["ifTrue:ifFalse:", ",", "replace:with:", "asUppercase", "second", "includes:", "commandLineSwitches"],
 referencedClasses: []
 }),
 smalltalk.AmberCli.klass);
@@ -16941,6 +16951,7 @@ smalltalk.AmberCli.klass);
 
 
 smalltalk.addClass('FileServer', smalltalk.Object, ['path', 'http', 'fs', 'url', 'host', 'port', 'basePath', 'util', 'username', 'password', 'fallbackPage'], 'AmberCli');
+smalltalk.FileServer.comment="I am the Amber Smalltalk FileServer.\x0aMy runtime requirement is a functional Node.js executable.\x0a\x0aTo start a FileServer instance on port `4000` use the following code:\x0a\x0a    FileServer new start\x0a\x0aA parameterized instance can be created with the following code:\x0a\x0a    FileServer createServerWithArguments: options\x0a\x0aHere, `options` is an array of commandline style strings each followed by a value e.g. `#('--port', '6000', '--host', '0.0.0.0')`.\x0aA list of all available parameters can be printed to the commandline by passing `--help` as parameter.\x0aSee the `Options` section for further details on how options are mapped to instance methods.\x0a\x0aAfter startup FileServer checks if the directory layout required by Amber is present and logs a warning on absence.\x0a\x0a\x0a## Options\x0a\x0aEach option is of the form `--some-option-string` which is transformed into a selector of the format `someOptionString:`.\x0aThe trailing `--` gets removed, each `-[a-z]` gets transformed into the according uppercase letter, and a `:` is appended to create a selector which takes a single argument.\x0aAfterwards, the selector gets executed on the `FileServer` instance with the value following in the options array as parameter.\x0a\x0a## Adding new commandline parameters\x0a\x0aAdding new commandline parameters to `FileServer` is as easy as adding a new single parameter method to the `accessing` protocol."
 smalltalk.addMethod(
 smalltalk.method({
 selector: "base64Decode:",
@@ -17591,23 +17602,6 @@ referencedClasses: []
 }),
 smalltalk.FileServer);
 
-smalltalk.addMethod(
-smalltalk.method({
-selector: "username:password:",
-category: 'accessing',
-fn: function (aUsername,aPassword){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
-self["@username"]=aUsername;
-self["@password"]=aPassword;
-return self}, function($ctx1) {$ctx1.fill(self,"username:password:",{aUsername:aUsername,aPassword:aPassword},smalltalk.FileServer)})},
-args: ["aUsername", "aPassword"],
-source: "username: aUsername password: aPassword\x0a\x09username := aUsername.\x0a\x09password := aPassword.",
-messageSends: [],
-referencedClasses: []
-}),
-smalltalk.FileServer);
-
 smalltalk.addMethod(
 smalltalk.method({
 selector: "writeData:toFileNamed:",
@@ -17900,6 +17894,7 @@ smalltalk.FileServer.klass);
 
 
 smalltalk.addClass('Repl', smalltalk.Object, ['readline', 'interface', 'util'], 'AmberCli');
+smalltalk.Repl.comment="I am a class representing a REPL (Read Evaluate Print Loop) and provide a command line interface to Amber Smalltalk.\x0aOn the prompt you can type Amber statements which will be evaluated after pressing <Enter>.\x0aThe evaluation is comparable with executing a 'DoIt' in a workspace.\x0a\x0aMy runtime requirement is a functional Node.js executable with working Readline support."
 smalltalk.addMethod(
 smalltalk.method({
 selector: "close",

+ 15 - 9
cli/st/AmberCli.st

@@ -12,7 +12,8 @@ Any further commandline parameters are passed to the specific program.
 
 ## Commands
 
-New commands can be added by creating a unary class side method in the `commands` protocol.
+New commands can be added by creating a class side method in the `commands` protocol which takes one parameter.
+This parameter is an array of all commandline options + values passed on to the program.
 Any `camelCaseCommand` is transformed into a commandline parameter of the form `camel-case-command` and vice versa.!
 
 !AmberCli class methodsFor: 'commandline'!
@@ -33,18 +34,23 @@ commandLineSwitches
 !
 
 handleArguments: args
-	| command |
-	command := self selectorForCommandLineSwitch: (args first).
+	| selector |
+
+	selector := self selectorForCommandLineSwitch: (args first).
 	args remove: args first.
-	self perform: command  withArguments: (Array with: args).
+	self perform: selector  withArguments: (Array with: args)
 !
 
 selectorForCommandLineSwitch: aSwitch
-	"Add ':' at the end
-	 and replace all occurences of a lowercase letter preceded by a '-' with
-	 the Uppercase letter.
-	 Example: fallback-page becomes fallbackPage:"
-	^(aSwitch replace: '-[a-z]' with: [ :each | each second asUppercase ]), ':'
+	"Add ':' at the end and replace all occurences of a lowercase letter preceded by a '-' with the Uppercase letter.
+	 Example: fallback-page becomes fallbackPage:.
+	 If no correct selector is found return 'help:'"
+	 | command selector |
+
+	 (self commandLineSwitches includes: aSwitch)
+	 ifTrue: [ selector := (aSwitch replace: '-[a-z]' with: [ :each | each second asUppercase ]), ':']
+	 ifFalse: [ selector := 'help:' ].
+	^selector
 ! !
 
 !AmberCli class methodsFor: 'commands'!