Skip to content

Commit

Permalink
Cleaned up CommandHelp by using buffered.Writer. Fixed indentation.
Browse files Browse the repository at this point in the history
  • Loading branch information
cquinn committed Jun 20, 2017
1 parent 5cea1ec commit 0324149
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 104 deletions.
2 changes: 1 addition & 1 deletion examples/commandline/main.pony
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ actor Main
match CommandParser(cli_spec()).parse(env.args, env.vars())
| let c: Command => c
| let ch: CommandHelp =>
ch.print_help(OutWriter(env.out))
ch.print_help(env.out)
env.exitcode(0)
return
| let se: SyntaxError =>
Expand Down
12 changes: 6 additions & 6 deletions examples/gups_basic/main.pony
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ class val Config
match CommandParser(cs).parse(env.args, env.vars())
| let c: Command => c
| let ch: CommandHelp =>
ch.print_help(OutWriter(env.out))
env.exitcode(0)
error
ch.print_help(env.out)
env.exitcode(0)
error
| let se: SyntaxError =>
env.out.print(se.string())
env.exitcode(1)
error
env.out.print(se.string())
env.exitcode(1)
error
end
logtable = cmd.option("table").i64().usize()
iterate = cmd.option("iterate").i64().usize()
Expand Down
12 changes: 6 additions & 6 deletions examples/gups_opt/main.pony
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ class val Config
match CommandParser(cs).parse(env.args, env.vars())
| let c: Command => c
| let ch: CommandHelp =>
ch.print_help(OutWriter(env.out))
env.exitcode(0)
error
ch.print_help(env.out)
env.exitcode(0)
error
| let se: SyntaxError =>
env.out.print(se.string())
env.exitcode(1)
error
env.out.print(se.string())
env.exitcode(1)
error
end
logtable = cmd.option("table").i64().usize()
iterate = cmd.option("iterate").i64().usize()
Expand Down
12 changes: 6 additions & 6 deletions examples/httpget/httpget.pony
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ class val Config
match CommandParser(cs).parse(env.args, env.vars())
| let c: Command => c
| let ch: CommandHelp =>
ch.print_help(OutWriter(env.out))
env.exitcode(0)
error
ch.print_help(env.out)
env.exitcode(0)
error
| let se: SyntaxError =>
env.out.print(se.string())
env.exitcode(1)
error
env.out.print(se.string())
env.exitcode(1)
error
end
user = cmd.option("user").string()
pass = cmd.option("pass").string()
Expand Down
12 changes: 6 additions & 6 deletions examples/mandelbrot/mandelbrot.pony
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,13 @@ class val Config
match CommandParser(cs).parse(env.args, env.vars())
| let c: Command => c
| let ch: CommandHelp =>
ch.print_help(OutWriter(env.out))
env.exitcode(0)
error
ch.print_help(env.out)
env.exitcode(0)
error
| let se: SyntaxError =>
env.out.print(se.string())
env.exitcode(1)
error
env.out.print(se.string())
env.exitcode(1)
error
end
iterations = cmd.option("iterations").i64().usize()
limit = cmd.option("limit").f64().f32()
Expand Down
20 changes: 10 additions & 10 deletions examples/yield/main.pony
Original file line number Diff line number Diff line change
Expand Up @@ -212,16 +212,16 @@ actor Main

let cmd =
match CommandParser(cs).parse(_env.args, _env.vars())
| let c: Command => c
| let ch: CommandHelp =>
ch.print_help(OutWriter(_env.out))
_env.exitcode(0)
return
| let se: SyntaxError =>
_env.out.print(se.string())
_env.exitcode(1)
return
end
| let c: Command => c
| let ch: CommandHelp =>
ch.print_help(_env.out)
_env.exitcode(0)
return
| let se: SyntaxError =>
_env.out.print(se.string())
_env.exitcode(1)
return
end

var punk: Bool = cmd.option("punk").bool()
var perf: U64 = cmd.option("bench").i64().u64()
Expand Down
120 changes: 52 additions & 68 deletions packages/cli/command_help.pony
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use "buffered"

primitive Help

Expand Down Expand Up @@ -46,41 +47,48 @@ class box CommandHelp
match _parent
| let p: CommandHelp => p.fullname() + " " + _spec.name()
else
_spec.name()
_spec.name()
end

fun box string(): String => fullname()

fun box help_string(): String =>
let w: StringWriter ref = StringWriter
print_help(w)
w.string()

fun box print_help(w: Writer) =>
print_usage(w)
let w: Writer = Writer
_write_help(w)
let str = recover trn String(w.size()) end
for bytes in w.done().values() do str.append(bytes) end
consume str

fun box print_help(os: OutStream) =>
let w: Writer = Writer
_write_help(w)
os.writev(w.done())

fun box _write_help(w: Writer) =>
_write_usage(w)
if _spec.descr().size() > 0 then
w.write("\n")
w.write(_spec.descr() + "\n")
end

let options = all_options()
let options = _all_options()
if options.size() > 0 then
w.write("\nOptions:\n")
print_options(w, options)
_write_options(w, options)
end
if _spec.commands().size() > 0 then
w.write("\nCommands:\n")
print_commands(w)
_write_commands(w)
end
let args = _spec.args()
if args.size() > 0 then
w.write("\nArgs:\n")
print_args(w, args)
_write_args(w, args)
end

fun box print_usage(w: Writer) =>
fun box _write_usage(w: Writer) =>
w.write("usage: " + fullname())
if any_options() then
if _any_options() then
w.write(" [<options>]")
end
if _spec.commands().size() > 0 then
Expand All @@ -95,104 +103,80 @@ class box CommandHelp
end
w.write("\n")

fun box print_options(w: Writer, options: Array[OptionSpec box] box) =>
let cols = Array[(String,String)]()
fun box _write_options(w: Writer, options: Array[OptionSpec box] box) =>
let cols = Array[(USize,String,String)]()
for o in options.values() do
cols.push((" " + o.help_string(), o.descr()))
cols.push((2, o.help_string(), o.descr()))
end
_Columns.print(w, cols)
_Columns.write(w, cols)

fun box print_commands(w: Writer) =>
let cols = Array[(String,String)]()
fun box _write_commands(w: Writer) =>
let cols = Array[(USize,String,String)]()
_list_commands(_spec, cols, 1)
_Columns.print(w, cols)
_Columns.write(w, cols)

fun box _list_commands(
cs: CommandSpec box,
cols: Array[(String,String)],
cols: Array[(USize,String,String)],
level: USize)
=>
for c in cs.commands().values() do
cols.push((_Columns.indent(level*2) + c.help_string(), c.descr()))
cols.push((level*2, c.help_string(), c.descr()))
_list_commands(c, cols, level + 1)
end

fun box print_args(w: Writer, args: Array[ArgSpec] box) =>
let cols = Array[(String,String)]()
fun box _write_args(w: Writer, args: Array[ArgSpec] box) =>
let cols = Array[(USize,String,String)]()
for a in args.values() do
cols.push((" " + a.help_string(), a.descr()))
cols.push((2, a.help_string(), a.descr()))
end
_Columns.print(w, cols)
_Columns.write(w, cols)

fun box any_options(): Bool =>
fun box _any_options(): Bool =>
if _spec.options().size() > 0 then
true
else
match _parent
| let p: CommandHelp => p.any_options()
| let p: CommandHelp => p._any_options()
else
false
end
end

fun box all_options(): Array[OptionSpec box] =>
fun box _all_options(): Array[OptionSpec box] =>
let options = Array[OptionSpec box]()
_all_options(options)
_all_options_fill(options)
options

fun box _all_options(options: Array[OptionSpec box]) =>
fun box _all_options_fill(options: Array[OptionSpec box]) =>
match _parent
| let p: CommandHelp => p._all_options(options)
| let p: CommandHelp => p._all_options_fill(options)
end
for o in _spec.options().values() do
options.push(o)
end

interface Writer
"""
This interface and two classes allow the help output to go to a general
Writer that can be implemented for string creation or to an OutStream. Or
other targets. This could be polished up and moved into a more central
package.
"""
fun ref write(data: ByteSeq)

class StringWriter
let _s: String ref = String

fun ref write(data: ByteSeq) =>
_s.append(data)

fun string(): String iso^ =>
_s.clone()

class OutWriter
let _os: OutStream tag

new create(os: OutStream tag) =>
_os = os

fun ref write(data: ByteSeq) =>
_os.write(data)

primitive _Columns
fun indent(n: USize): String =>
let spaces = " "
spaces.substring(0, n.isize())
fun indent(w: Writer, n: USize) =>
var i = n
while i > 0 do
w.write(" ")
i = i - 1
end

fun print(w: Writer, cols: Array[(String,String)]) =>
fun write(w: Writer, cols: Array[(USize,String,String)]) =>
var widest: USize = 0
for c in cols.values() do
(let c1, _) = c
let c1s = c1.size()
(let c0, let c1, _) = c
let c1s = c0 + c1.size()
if c1s > widest then
widest = c1s
end
end
for c in cols.values() do
(let c1, let c2) = c
w.write(indent(1))
(let c0, let c1, let c2) = c
indent(w, 1 + c0)
w.write(c1)
w.write(indent((widest - c1.size()) + 2))
indent(w, (widest - c1.size()) + 2)
w.write(c2 + "\n")
end
3 changes: 2 additions & 1 deletion packages/cli/command_parser.pony
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ class CommandParser
end
else
match _parse_arg(token, arg_pos)
| let a: Arg => args.update(a.spec().name(), a); arg_pos = arg_pos + 1
| let a: Arg => args.update(a.spec().name(), a)
arg_pos = arg_pos + 1
| let se: SyntaxError => return se
end
end
Expand Down

0 comments on commit 0324149

Please sign in to comment.