seaneagan / unscripted

Define command-line interfaces using ordinary dart methods and classes.
BSD 3-Clause "New" or "Revised" License
23 stars 10 forks source link

Noticing this issue on Mac. #66

Closed adam-singer closed 10 years ago

adam-singer commented 10 years ago
$ ./daemon_isolate_commands.dart Dart_NewStringFromUTF8 expects argument 'str' to be valid UTF-8.
Dart_NewStringFromUTF8 expects argument 'str' to be valid UTF-8.
Dart_NewStringFromUTF8 expects argument 'str' to be valid UTF-8.
Dart_NewStringFromUTF8 expects argument 'str' to be valid UTF-8.

Known issue or something you want me to dig into?

seaneagan commented 10 years ago

I don't have access to a Mac, so I've only tested unscripted on linux and windows. Were you trying to run daemon_isolate_commands.dart or tab-complete it? If the latter, were you expecting there to be 4 suggested completions? If the former, is something else occurring 4 times?

I found this bug with the same error message. Guessing somewhere the dart vm is trying to run a file which is either a binary, or contains a non-printable character.

Can you post the contents of daemon_isolate_commands.dart, and I'll take a look.

adam-singer commented 10 years ago

@seaneagan its happening when trying to use tab-complete

adam-singer commented 10 years ago

https://github.com/financeCoding/dart-carte-du-jour/blob/master/bin/daemon_isolate_commands.dart

seaneagan commented 10 years ago

@financeCoding Tab completion for daemon_isolate_commands.dart works fine for me in linux and windows (cygwin), so must be Mac-specific.

What is the output of daemon_isolate_commands.dart completion?

daemon_isolate_commands.dart must be on your PATH for completion to work.

Looking at the code, --options (annotated with @Option or @Flag) must be represented as optional named arguments in your dart methods, currently you have some of them as positional arguments.

adam-singer commented 10 years ago

@seaneagan interestingly enough it worked on my other mac. So going to close this out and claim it as user error. Who knows what creeped into that other mac.

adam-singer commented 10 years ago

Thanks for the tips on options. Another question does it make sense to have multiple commands for a single file? So not full blown subcommands.

Another side note. I find it hard to read the description after usage. I really like the ansi colors in the shell. Maybe have the help printout as follows, where "Description:" is white.

–(~/dart/dart-carte-du-jour/bin)–($ daemon_isolate_commands.dart
daemon_isolate_commands.dart: error: Must specify a sub-command.

Description:

Manages a server

Usage:

  daemon_isolate_commands.dart command

Options:

      --config-path    
  -h, --help           Print this usage information.

Available commands:

  catlog
  catconfig
  list
  restart-daemon-isolate
  start-daemon-isolate
  stop-daemon-isolate
  tail-daemon-isolate
  tail-instance
  build-package
  rebuild-package
  buildall-packages
  rebuildall-packages
  build-first-page
  build-index-html
  build-package-version
  health-checks
  remote-health-checks
  local-status
  remote-status
  completion
  help

  Use "daemon_isolate_commands.dart help [command]" for more information about a command.
seaneagan commented 10 years ago

@financeCoding I implemented your idea about 'Description:` for the next release. Thanks! I also spruced up the help output in general to be a lot more complete, and pretty (uses ansi colors to semantically highlight).

Not sure what you meant about "multiple commands in the same file". Could you elaborate?

adam-singer commented 10 years ago

If I wanted to break up the commands via different classes. As of now a collection of subcommons are only available via a single class.

adam-singer commented 10 years ago

Awesome, looking forward to next release

seaneagan commented 10 years ago

@financeCoding

You should be able to use mixins to do that, but I haven't tested it yet:

class Foo with Bar, Baz {
  final bool f;

  @Command()
  Foo({this.f});

  @SubCommand()
  foo({bool x}) => print('foo - x: $x');
}

class Bar {
  @SubCommand()
  bar1(int x) => print('bar1 - x: $x');
  @SubCommand()
  bar2() => print('bar2');
}

class Baz {
  @SubCommand()
  baz(String y) => print('baz - y: $y');
}

unless you are looking for nested sub-commands? That is definitely supported (but not documented too well yet):

class Foo {

  final String x;

  @Command()
  Foo({this.x});

  @SubCommand()
  Bar bar({bool y}) => new Bar(this, y: y);
}

class Bar {

  final Foo foo;
  final String y;

  Bar(this.foo, this.y)

  @SubCommand()
  baz(int x) => print;

  @SubCommand()
  qux() => new Bar(y: y);

}
seaneagan commented 10 years ago

Just tested mixins, and it works as expected.

adam-singer commented 10 years ago

neat! I'll keep this in mind. Thanks for the samples.