Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

working parser

  • Loading branch information...
commit 9295ded8d7a4c7d5b619962175f277642849177b 1 parent b017121
@contra contra authored
View
16 README.md
@@ -1,14 +1,14 @@
-![status](https://secure.travis-ci.org/wearefractal/APPNAME.png?branch=master)
+![status](https://secure.travis-ci.org/wearefractal/argus.png?branch=master)
## Information
<table>
<tr>
-<td>Package</td><td>APPNAME</td>
+<td>Package</td><td>argus</td>
</tr>
<tr>
<td>Description</td>
-<td>NOTHING HERE YET</td>
+<td>Complex CLI argument parser</td>
</tr>
<tr>
<td>Node Version</td>
@@ -16,15 +16,19 @@
</tr>
</table>
+## Details
+
+Argus allows you to pass an array of complex data to your application through a CLI. This can be an array of objects, strings, numbers, you name it. Anything that is a valid JSON array can be used. Ideally when you get this array of objects you would pass it into whatever function was being called.
+
## Usage
```coffee-script
-NOTHING HERE YET
+mycli dostuff["johnny boy",true,-1]
```
-## Examples
+## Quirks
-You can view more examples in the [example folder.](https://github.com/wearefractal/APPNAME/tree/master/examples)
+Bash doesn't agree with a lot of characters so some escaping may be required. Still looking for a solution to this.
## LICENSE
View
0  examples/empty
No changes.
View
14 lib/main.coffee
@@ -1 +1,13 @@
-module.exports = {}
+{readFileSync} = require 'fs'
+{join} = require 'path'
+{buildParser} = require 'pegjs'
+
+safe = buildParser String readFileSync join __dirname, 'safe.pegjs'
+#unsafe = buildParser String readFileSync join __dirname, 'unsafe.pegjs'
+
+module.exports =
+ #unsafe: (command) ->
+ # unsafe.parse command
+
+ parse: (command) ->
+ safe.parse command
View
141 lib/safe.pegjs
@@ -0,0 +1,141 @@
+start
+ = _ command:command { return command; }
+
+command
+ = head:task tail:(":" _ task)* {
+ var result = {};
+ result[head[0]] = head[1];
+ for (var i = 0; i < tail.length; i++) {
+ result[tail[i][2][0]] = tail[i][2][1];
+ }
+ return result;
+ }
+
+task
+ = name:alphanumeric+ arg:array { return [name.join(""), arg]; }
+ / name:alphanumeric+ { return [name.join(""), []]; }
+
+alphanumeric
+ = [a-z0-9_]i
+
+/* Everything below is dervived from the PEGJS JSON parser example */
+/*
+ Modifications made:
+ - null actually returns null (kind of a hack around PEG)
+ - undefined added
+ - Strings use ' instead of "
+*/
+
+object
+ = "{" _ "}" _ { return {}; }
+ / "{" _ members:members "}" _ { return members; }
+
+members
+ = head:pair tail:("," _ pair)* {
+ var result = {};
+ result[head[0]] = (head[1] === "_$null$_" ? null : head[1]);
+ for (var i = 0; i < tail.length; i++) {
+ result[tail[i][2][0]] = (tail[i][2][1] === "_$null$_" ? null : tail[i][2][1]);
+ }
+ return result;
+ }
+
+pair
+ = name:string ":" _ value:value { return [name, value]; }
+
+array
+ = "[" _ "]" _ { return []; }
+ / "[" _ elements:elements "]" _ { return elements; }
+
+elements
+ = head:value tail:("," _ value)* {
+ var result = [head === "_$null$_" ? null : head];
+ for (var i = 0; i < tail.length; i++) {
+ result.push(tail[i][2] === "_$null$_" ? null : tail[i][2]);
+ }
+ return result;
+ }
+
+value
+ = string
+ / number
+ / object
+ / array
+ / "true" _ { return true; }
+ / "false" _ { return false; }
+ / "null" _ { return "_$null$_"; }
+ / "undefined" _ { return undefined; }
+
+/* ===== Lexical Elements ===== */
+
+string "string"
+ = '"' '"' _ { return ""; }
+ / '"' chars:chars '"' _ { return chars; }
+
+chars
+ = chars:char+ { return chars.join(""); }
+
+char
+ // In the original JSON grammar: "any-Unicode-character-except-"-or-\-or-control-character"
+ = [^"\\\0-\x1F\x7f]
+ / '\\"' { return '"'; }
+ / "\\\\" { return "\\"; }
+ / "\\/" { return "/"; }
+ / "\\b" { return "\b"; }
+ / "\\f" { return "\f"; }
+ / "\\n" { return "\n"; }
+ / "\\r" { return "\r"; }
+ / "\\t" { return "\t"; }
+ / "\\u" h1:hexDigit h2:hexDigit h3:hexDigit h4:hexDigit {
+ return String.fromCharCode(parseInt("0x" + h1 + h2 + h3 + h4));
+ }
+
+number "number"
+ = int_:int frac:frac exp:exp _ { return parseFloat(int_ + frac + exp); }
+ / int_:int frac:frac _ { return parseFloat(int_ + frac); }
+ / int_:int exp:exp _ { return parseFloat(int_ + exp); }
+ / int_:int _ { return parseFloat(int_); }
+
+int
+ = digit19:digit19 digits:digits { return digit19 + digits; }
+ / digit:digit
+ / "-" digit19:digit19 digits:digits { return "-" + digit19 + digits; }
+ / "-" digit:digit { return "-" + digit; }
+
+frac
+ = "." digits:digits { return "." + digits; }
+
+exp
+ = e:e digits:digits { return e + digits; }
+
+digits
+ = digits:digit+ { return digits.join(""); }
+
+e
+ = e:[eE] sign:[+-]? { return e + sign; }
+
+/*
+ * The following rules are not present in the original JSON gramar, but they are
+ * assumed to exist implicitly.
+ *
+ * FIXME: Define them according to ECMA-262, 5th ed.
+ */
+
+digit
+ = [0-9]
+
+digit19
+ = [1-9]
+
+hexDigit
+ = [0-9a-fA-F]
+
+/* ===== Whitespace ===== */
+
+_ "whitespace"
+ = whitespace*
+
+// Whitespace is undefined in the original JSON grammar, so I assume a simple
+// conventional definition consistent with ECMA-262, 5th ed.
+whitespace
+ = [ \t\n\r]
View
26 lib/unsafe.pegjs
@@ -0,0 +1,26 @@
+start
+ = command:command { return command; }
+
+command
+ = head:task tail:(":" task)* {
+ var result = {};
+ result[head[0]] = head[1];
+ for (var i = 0; i < tail.length; i++) {
+ result[tail[i][1][0]] = tail[i][1][1];
+ }
+ return result;
+ }
+
+task
+ = name:name arg:arguments { return [name.join(""), arg]; }
+ / name:name { return [name.join(""), []]; }
+
+arguments
+ = "[" "]" { return []; }
+ / "[" chars:[^\]]+ "]" { return chars.join(""); }
+
+name
+ = alphanumeric+
+
+alphanumeric
+ = [a-z0-9_]i
View
13 package.json
@@ -1,14 +1,15 @@
{
- "name":"APPNAME",
- "description":"Nothing here yet",
+ "name":"argus",
+ "description":"Complex CLI argument parser",
"version":"0.0.1",
- "homepage":"http://github.com/wearefractal/APPNAME",
- "repository":"git://github.com/wearefractal/APPNAME.git",
+ "homepage":"http://github.com/wearefractal/argus",
+ "repository":"git://github.com/wearefractal/argus.git",
"author":"Fractal <contact@wearefractal.com> (http://wearefractal.com/)",
"main":"./index.js",
"dependencies":{
- "coffee-script":"*"
+ "coffee-script":"*",
+ "pegjs":"*"
},
"devDependencies":{
"mocha":"*",
@@ -23,7 +24,7 @@
"licenses":[
{
"type":"MIT",
- "url":"http://github.com/wearefractal/APPNAME/raw/master/LICENSE"
+ "url":"http://github.com/wearefractal/argus/raw/master/LICENSE"
}
]
}
View
61 test/main.coffee
@@ -1,10 +1,59 @@
-APPNAME = require '../'
+argus = require '../'
should = require 'should'
require 'mocha'
-describe 'FUNCTIONTYPE', ->
- describe 'FUNCTIONNAME()', ->
- it 'should TASKNAME', (done) ->
- should.exist true
- true.should.equal.true
+testargs = [
+ "string", 'string'
+ true, false
+ 2, -2, 0
+ 2.2, -2.2
+ null,#undefined
+ [{"test":"test"}],["arr1","arr2"]
+ {"test":"~~~test~~"}, {}
+]
+testcli = JSON.stringify testargs
+
+describe 'parse()', ->
+ describe 'standard behaviour', ->
+ it 'task(none)', (done) ->
+ res = argus.parse "task"
+ should.exist res
+ should.exist res.task
+ res.task.should.eql []
+ done()
+ it 'task(all)', (done) ->
+ res = argus.parse "task#{testcli}"
+ should.exist res
+ should.exist res.task
+ res.task.should.eql testargs
+ done()
+ it 'task(none):task2(all)', (done) ->
+ res = argus.parse "task:task2#{testcli}"
+ should.exist res
+ should.exist res.task
+ res.task.should.eql []
+ should.exist res.task2
+ res.task2.should.eql testargs
+ done()
+ it 'task(all):task2(none)', (done) ->
+ res = argus.parse "task#{testcli}:task2"
+ should.exist res
+ should.exist res.task
+ res.task.should.eql testargs
+ should.exist res.task2
+ res.task2.should.eql []
+ done()
+
+ describe 'overloading', ->
+ it 'task(none):task(all)', (done) ->
+ res = argus.parse "task:task#{testcli}"
+ should.exist res
+ should.exist res.task
+ res.task.should.eql testargs
+ done()
+ it 'task(all):task(none)', (done) ->
+ res = argus.parse "task#{testcli}:task"
+ should.exist res
+ should.exist res.task
+ res.task.should.eql []
done()
View
1  test/mocha.opts
@@ -0,0 +1 @@
+--reporter spec
Please sign in to comment.
Something went wrong with that request. Please try again.