Skip to content

Commit

Permalink
feat(clap): setup infrastructure
Browse files Browse the repository at this point in the history
This allows us to setup clap and see if it compiles, which is the prime
goal of the current workflow step.

Related to #81
  • Loading branch information
Byron committed Apr 28, 2015
1 parent 57808cf commit 988d37f
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 38 deletions.
3 changes: 1 addition & 2 deletions etc/api/type-cli.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ cargo:
keywords: [cli]
is_executable: YES
dependencies:
- docopt = "*"
- docopt_macros = "*"
- clap = "*"
- rustc-serialize = "*"
- yup-hyper-mock = "*"
- serde = ">= 0.3.0"
Expand Down
4 changes: 2 additions & 2 deletions src/mako/cli/README.md.mako
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
c = new_context(schemas, resources, context.get('methods'))
%>\
<%namespace name="util" file="../lib/util.mako"/>\
<%namespace name="docopt" file="lib/docopt.mako"/>\
<%namespace name="argparse" file="lib/argparse.mako"/>\
<%block filter="markdown_comment">\
<%util:gen_info source="${self.uri}" />\
</%block>
Expand All @@ -26,7 +26,7 @@ Everything else about the *${util.canonical_name()}* API can be found at the
This documentation was generated from the *${util.canonical_name()}* API at revision *${revision is UNDEFINED and '00000000' or revision}*. The CLI is at version *${cargo.build_version}*.

```bash
${docopt.new(c, usage_only=True)}
${argparse.grammar(c)}
```

# Configuration
Expand Down
85 changes: 76 additions & 9 deletions src/mako/cli/lib/docopt.mako → src/mako/cli/lib/argparse.mako
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
<%namespace name="util" file="../../lib/util.mako"/>\
<%!
from util import (put_and, supports_scopes, api_index)
from util import (put_and, supports_scopes, api_index, indent_by)
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)
%>\
<%def name="new(c, usage_only=False)">\
<%def name="grammar(c)">\
<%
param_used = False
struct_used = False
upload_protocols_used = set()
output_used = False
%>\
% if not usage_only:
docopt!(Options derive Debug, "
Usage:
% endif
% for resource in sorted(c.rta_map.keys()):
% for method in sorted(c.rta_map[resource]):
<%
Expand Down Expand Up @@ -75,7 +71,78 @@ Configuration:
--${DEBUG_AUTH_FLAG}
Output all communication related to authentication to standard error. `tx`
and `rx` are placed into the same stream.
% if not usage_only:
");
% endif
</%def>



<%def name="new(c)" buffered="True">\
<%
param_used = False
struct_used = False
upload_protocols_used = set()
output_used = False
%>\
App::new("${util.program_name()}")
<%block filter="indent_by(4)">
% for resource in sorted(c.rta_map.keys()):
% for method in sorted(c.rta_map[resource]):
<%
mc = new_method_context(resource, method, c)
args = list()
for p in mc.required_props:
if is_request_value_property(mc, p):
continue
args.append(to_docopt_arg(p))
# end for each required property
if mc.request_value:
args.append('-%s %s...' % (STRUCT_FLAG, '<%s>' % KEY_VALUE_ARG))
struct_used = True
# 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))
upload_protocols_used = upload_protocols_used|set(upload_protocols)
# end upload handling
if mc.optional_props or parameters is not UNDEFINED:
args.append('[-%s %s...]' % (PARAM_FLAG, '<%s>' % VALUE_ARG))
param_used = True
# end paramters
if mc.response_schema or mc.m.get('supportsMediaDownload', False):
args.append('[-%s %s]' % (OUTPUT_FLAG, OUT_ARG))
output_used = True
# handle output
%>\
${util.program_name()} [options] ${mangle_subcommand(resource)} ${mangle_subcommand(method)} ${' '.join(args)}
% endfor # each method
% endfor # end for each resource
${util.program_name()} --help
All documentation details can be found at
${cargo.doc_base_url + '/' + api_index(cargo.doc_base_url, name, version, make, check_exists=False)}
Configuration:
% if supports_scopes(auth):
--${SCOPE_FLAG} <url>
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.
% endif scopes
--${CONFIG_DIR_FLAG} <folder>
A directory into which we will store our persistent data. Defaults to
a user-writable directory that we will create during the first invocation.
[default: ${CONFIG_DIR}]
--${DEBUG_FLAG}
Output all server communication to standard error. `tx` and `rx` are placed
into the same stream.
--${DEBUG_AUTH_FLAG}
Output all communication related to authentication to standard error. `tx`
and `rx` are placed into the same stream.
.get_matches();
</%block>
</%def>
52 changes: 27 additions & 25 deletions src/mako/cli/main.rs.mako
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
<%namespace name="docopt" file="lib/docopt.mako"/>\
<%namespace name="argparse" file="lib/argparse.mako"/>\
<%namespace name="engine" file="lib/engine.mako"/>\
<%namespace name="util" file="../lib/util.mako"/>\
<%
from util import (new_context, rust_comment, to_extern_crate_name, library_to_crate_name, library_name)
from util import (new_context, rust_comment, to_extern_crate_name, library_to_crate_name, library_name,
indent_all_but_first_by)
c = new_context(schemas, resources, context.get('methods'))
default_user_agent = "google-cli-rust-client/" + cargo.build_version
Expand All @@ -11,10 +12,9 @@
<%util:gen_info source="${self.uri}" />\
</%block>
#![feature(plugin, exit_status)]
#![plugin(docopt_macros)]
#![allow(unused_variables, unused_imports, dead_code, unused_mut)]

extern crate docopt;
extern crate clap;
extern crate yup_oauth2 as oauth2;
extern crate yup_hyper_mock as mock;
extern crate rustc_serialize;
Expand All @@ -25,28 +25,30 @@ extern crate ${to_extern_crate_name(library_to_crate_name(library_name(name, ver

use std::env;
use std::io::{self, Write};
use clap::{App, SubCommand};

${docopt.new(c)}\

${engine.new(c)}\
## ${engine.new(c)}\

fn main() {
let opts: Options = Options::docopt().decode().unwrap_or_else(|e| e.exit());
let debug = opts.flag_debug;
match Engine::new(opts) {
Err(err) => {
writeln!(io::stderr(), "{}", err).ok();
env::set_exit_status(err.exit_code);
},
Ok(engine) => {
if let Some(err) = engine.doit() {
if debug {
writeln!(io::stderr(), "{:?}", err).ok();
} else {
writeln!(io::stderr(), "{}", err).ok();
}
env::set_exit_status(1);
}
}
}
let matches =
${argparse.new(c) | indent_all_but_first_by(1)}\

## let opts: Options = Options::docopt().decode().unwrap_or_else(|e| e.exit());
## let debug = opts.flag_debug;
## match Engine::new(opts) {
## Err(err) => {
## writeln!(io::stderr(), "{}", err).ok();
## env::set_exit_status(err.exit_code);
## },
## Ok(engine) => {
## if let Some(err) = engine.doit() {
## if debug {
## writeln!(io::stderr(), "{:?}", err).ok();
## } else {
## writeln!(io::stderr(), "{}", err).ok();
## }
## env::set_exit_status(1);
## }
## }
## }
}

0 comments on commit 988d37f

Please sign in to comment.