Skip to content

Commit

Permalink
fix(clap): update docs and fix calltype handling
Browse files Browse the repository at this point in the history
* mkdoc docs grammar is now hierarchical, making the command structure
  more obvious and easier to understand. It's a nice addition to the
  auto-generated, hierachical usage of clap.
* UploadProtocol enum is now CallType, to ease handling the different
  ways the Call has to be executed. It looks quite clean, even though
  combining upload protocols and the calltype is a bit hacky.
  • Loading branch information
Byron committed Apr 30, 2015
1 parent 7a38f7e commit b039b38
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 30 deletions.
32 changes: 18 additions & 14 deletions src/mako/cli/lib/argparse.mako
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from cli import (mangle_subcommand, new_method_context, PARAM_FLAG, STRUCT_FLAG, UPLOAD_FLAG, OUTPUT_FLAG, VALUE_ARG,
CONFIG_DIR, SCOPE_FLAG, is_request_value_property, FIELD_SEP, docopt_mode, FILE_ARG, MIME_ARG, OUT_ARG,
CONFIG_DIR_FLAG, KEY_VALUE_ARG, to_docopt_arg, DEBUG_FLAG, DEBUG_AUTH_FLAG, MODE_ARG, SCOPE_ARG,
CONFIG_DIR_ARG)
CONFIG_DIR_ARG, FILE_FLAG, MIME_FLAG)
def rust_boolean(v):
return v and 'true' or 'false'
Expand All @@ -19,11 +19,13 @@
elif isinstance(v, basestring):
v = '"%s"' % v
elif isinstance(v, list):
v = 'vec![%s]' % ','.join('UploadProtocol::%s' % p.capitalize() for p in v)
v = 'vec![%s]' % ','.join('CallType::Upload%s' % p.capitalize() for p in v)
return 'Some(%s)' % v
%>\
<%def name="grammar(c)">\
${util.program_name()} [options]
% for resource in sorted(c.rta_map.keys()):
${mangle_subcommand(resource)}
% for method in sorted(c.rta_map[resource]):
<%
mc = new_method_context(resource, method, c)
Expand All @@ -36,24 +38,24 @@
# end for each required property
if mc.request_value:
args.append('-%s %s...' % (STRUCT_FLAG, '<%s>' % KEY_VALUE_ARG))
args.append('(-%s %s)...' % (STRUCT_FLAG, '<%s>' % KEY_VALUE_ARG))
# end request_value
if mc.media_params:
upload_protocols = [mp.protocol for mp in mc.media_params]
mode = docopt_mode(upload_protocols)
args.append('-%s %s <%s> <%s>' % (UPLOAD_FLAG, mode, FILE_ARG, MIME_ARG))
args.append('(-%s %s -%s <%s> -%s <%s>)' % (UPLOAD_FLAG, mode, FILE_FLAG, FILE_ARG, MIME_FLAG, MIME_ARG))
# end upload handling
if mc.optional_props or parameters is not UNDEFINED:
args.append('[-%s %s...]' % (PARAM_FLAG, '<%s>' % VALUE_ARG))
args.append('[-%s %s]...' % (PARAM_FLAG, '<%s>' % VALUE_ARG))
# end paramters
if mc.response_schema or mc.m.get('supportsMediaDownload', False):
args.append('[-%s <%s>]' % (OUTPUT_FLAG, OUT_ARG))
# handle output
%>\
${util.program_name()} [options] ${mangle_subcommand(resource)} ${mangle_subcommand(method)} ${' '.join(args)}
${mangle_subcommand(method)} ${' '.join(args)}
% endfor # each method
% endfor # end for each resource
${util.program_name()} --help
Expand All @@ -63,7 +65,7 @@ ${cargo.doc_base_url + '/' + os.path.dirname(api_index(cargo.doc_base_url, name,
Configuration:
% if supports_scopes(auth):
--${SCOPE_FLAG} <${SCOPE_ARG}>...
[--${SCOPE_FLAG} <${SCOPE_ARG}>]...
Specify the authentication a method should be executed in. Each scope
requires the user to grant this application permission to use it.
If unset, it defaults to the shortest scope url for a particular method.
Expand Down Expand Up @@ -212,7 +214,7 @@ let arg_data = [
% if not mc.media_params:
## Make sure the type is set, even though we don't have any protocol information
% if loop.first:
None::${'<Vec<&str>>'}\
None::${'<Vec<CallType>>'}\
% else:
None\
% endif
Expand Down Expand Up @@ -284,16 +286,18 @@ for &(main_command_name, ref subcommands) in arg_data.iter() {
}
if let &Some(ref protocols) = protocols {
arg = arg.possible_values(protocols);
arg = arg.requires("file");
arg = arg.requires("mime");
arg = arg.requires("${FILE_ARG}");
arg = arg.requires("${MIME_ARG}");
scmd = scmd.arg(Arg::with_name("file")
.short("f")
scmd = scmd.arg(Arg::with_name("${FILE_ARG}")
.short("${FILE_FLAG}")
.required(true)
.requires("${MODE_ARG}")
.help("The file to upload")
.takes_value(true));
scmd = scmd.arg(Arg::with_name("mime")
.short("m")
scmd = scmd.arg(Arg::with_name("${MIME_ARG}")
.short("${MIME_FLAG}")
.requires("${MODE_ARG}")
.required(true)
.help("The file's mime time, like 'application/octet-stream'")
.takes_value(true));
Expand Down
2 changes: 2 additions & 0 deletions src/mako/cli/lib/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@

MODE_ARG = 'mode'
FILE_ARG = 'file'
FILE_FLAG = 'f'
MIME_ARG = 'mime'
MIME_FLAG = 'm'
OUT_ARG = 'out'

SCOPE_ARG = 'url'
Expand Down
14 changes: 8 additions & 6 deletions src/mako/cli/lib/engine.mako
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
hub_type_name = 'api::' + hub_type(c.schemas, util.canonical_name())
%>\
use cmn::{InvalidOptionsError, CLIError, JsonTokenStorage, arg_from_str, writer_from_opts, parse_kv_arg,
input_file_from_opts, input_mime_from_opts, FieldCursor, FieldError, UploadProtocol};
input_file_from_opts, input_mime_from_opts, FieldCursor, FieldError, CallType};
use std::default::Default;
use std::str::FromStr;
Expand Down Expand Up @@ -256,11 +256,11 @@ ${value_unwrap}\
}
% endif # handle call parameters
% if mc.media_params:
let protocol = ${req_value(MODE_ARG)};
let protocol = CallType::from(${req_value(MODE_ARG)});
let mut input_file = input_file_from_opts(${req_value(FILE_ARG)}, err);
let mime_type = input_mime_from_opts(${req_value(MIME_ARG)}, err);
% else:
let protocol = "${STANDARD}";
let protocol = CallType::Standard;
% endif # support upload
if dry_run {
None
Expand All @@ -276,13 +276,15 @@ if dry_run {
% if handle_output:
let mut ostream = writer_from_opts(opt.value_of("${(OUT_ARG)}"));
% endif # handle output
match match UploadProtocol::from(protocol) {
match match protocol {
% if mc.media_params:
% for p in mc.media_params:
UploadProtocol::${p.protocol.capitalize()} => call.${upload_action_fn(api.terms.upload_action, p.type.suffix)}(input_file.unwrap(), mime_type.unwrap()),
CallType::Upload${p.protocol.capitalize()} => call.${upload_action_fn(api.terms.upload_action, p.type.suffix)}(input_file.unwrap(), mime_type.unwrap()),
% endfor
CallType::Standard => unreachable!()
% else:
"${STANDARD}" => call.${api.terms.action}(),
CallType::Standard => call.${api.terms.action}(),
_ => unreachable!()
% endif
} {
Err(api_err) => Some(api_err),
Expand Down
22 changes: 12 additions & 10 deletions src/rust/cli/cmn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,27 @@ use std::default::Default;

const FIELD_SEP: char = '.';

pub enum UploadProtocol {
Simple,
Resumable,
pub enum CallType {
UploadSimple,
UploadResumable,
Standard,
}

impl AsRef<str> for UploadProtocol {
impl AsRef<str> for CallType {
fn as_ref(&self) -> &str {
match *self {
UploadProtocol::Simple => "simple",
UploadProtocol::Resumable => "resumable",
CallType::UploadSimple => "simple",
CallType::UploadResumable => "resumable",
CallType::Standard => "standard-request"
}
}
}

impl<'a> From<&'a str> for UploadProtocol {
fn from(this: &'a str) -> UploadProtocol {
impl<'a> From<&'a str> for CallType {
fn from(this: &'a str) -> CallType {
match this {
"simple" => UploadProtocol::Simple,
"resumable" => UploadProtocol::Resumable,
"simple" => CallType::UploadSimple,
"resumable" => CallType::UploadResumable,
_ => unreachable!(),
}
}
Expand Down

0 comments on commit b039b38

Please sign in to comment.