Skip to content

Commit 988d37f

Browse files
committed
feat(clap): setup infrastructure
This allows us to setup clap and see if it compiles, which is the prime goal of the current workflow step. Related to #81
1 parent 57808cf commit 988d37f

4 files changed

Lines changed: 106 additions & 38 deletions

File tree

etc/api/type-cli.yaml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ cargo:
2626
keywords: [cli]
2727
is_executable: YES
2828
dependencies:
29-
- docopt = "*"
30-
- docopt_macros = "*"
29+
- clap = "*"
3130
- rustc-serialize = "*"
3231
- yup-hyper-mock = "*"
3332
- serde = ">= 0.3.0"

src/mako/cli/README.md.mako

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
c = new_context(schemas, resources, context.get('methods'))
66
%>\
77
<%namespace name="util" file="../lib/util.mako"/>\
8-
<%namespace name="docopt" file="lib/docopt.mako"/>\
8+
<%namespace name="argparse" file="lib/argparse.mako"/>\
99
<%block filter="markdown_comment">\
1010
<%util:gen_info source="${self.uri}" />\
1111
</%block>
@@ -26,7 +26,7 @@ Everything else about the *${util.canonical_name()}* API can be found at the
2626
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}*.
2727

2828
```bash
29-
${docopt.new(c, usage_only=True)}
29+
${argparse.grammar(c)}
3030
```
3131

3232
# Configuration
Lines changed: 76 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,17 @@
11
<%namespace name="util" file="../../lib/util.mako"/>\
22
<%!
3-
from util import (put_and, supports_scopes, api_index)
3+
from util import (put_and, supports_scopes, api_index, indent_by)
44
from cli import (mangle_subcommand, new_method_context, PARAM_FLAG, STRUCT_FLAG, UPLOAD_FLAG, OUTPUT_FLAG, VALUE_ARG,
55
CONFIG_DIR, SCOPE_FLAG, is_request_value_property, FIELD_SEP, docopt_mode, FILE_ARG, MIME_ARG, OUT_ARG,
66
CONFIG_DIR_FLAG, KEY_VALUE_ARG, to_docopt_arg, DEBUG_FLAG, DEBUG_AUTH_FLAG)
77
%>\
8-
<%def name="new(c, usage_only=False)">\
8+
<%def name="grammar(c)">\
99
<%
1010
param_used = False
1111
struct_used = False
1212
upload_protocols_used = set()
1313
output_used = False
1414
%>\
15-
% if not usage_only:
16-
docopt!(Options derive Debug, "
17-
Usage:
18-
% endif
1915
% for resource in sorted(c.rta_map.keys()):
2016
% for method in sorted(c.rta_map[resource]):
2117
<%
@@ -75,7 +71,78 @@ Configuration:
7571
--${DEBUG_AUTH_FLAG}
7672
Output all communication related to authentication to standard error. `tx`
7773
and `rx` are placed into the same stream.
78-
% if not usage_only:
79-
");
80-
% endif
74+
</%def>
75+
76+
77+
78+
<%def name="new(c)" buffered="True">\
79+
<%
80+
param_used = False
81+
struct_used = False
82+
upload_protocols_used = set()
83+
output_used = False
84+
%>\
85+
App::new("${util.program_name()}")
86+
<%block filter="indent_by(4)">
87+
% for resource in sorted(c.rta_map.keys()):
88+
% for method in sorted(c.rta_map[resource]):
89+
<%
90+
mc = new_method_context(resource, method, c)
91+
92+
args = list()
93+
for p in mc.required_props:
94+
if is_request_value_property(mc, p):
95+
continue
96+
args.append(to_docopt_arg(p))
97+
# end for each required property
98+
99+
if mc.request_value:
100+
args.append('-%s %s...' % (STRUCT_FLAG, '<%s>' % KEY_VALUE_ARG))
101+
struct_used = True
102+
# end request_value
103+
104+
if mc.media_params:
105+
upload_protocols = [mp.protocol for mp in mc.media_params]
106+
mode = docopt_mode(upload_protocols)
107+
args.append('-%s %s %s %s' % (UPLOAD_FLAG, mode, FILE_ARG, MIME_ARG))
108+
upload_protocols_used = upload_protocols_used|set(upload_protocols)
109+
# end upload handling
110+
111+
if mc.optional_props or parameters is not UNDEFINED:
112+
args.append('[-%s %s...]' % (PARAM_FLAG, '<%s>' % VALUE_ARG))
113+
param_used = True
114+
# end paramters
115+
116+
if mc.response_schema or mc.m.get('supportsMediaDownload', False):
117+
args.append('[-%s %s]' % (OUTPUT_FLAG, OUT_ARG))
118+
output_used = True
119+
# handle output
120+
%>\
121+
${util.program_name()} [options] ${mangle_subcommand(resource)} ${mangle_subcommand(method)} ${' '.join(args)}
122+
% endfor # each method
123+
% endfor # end for each resource
124+
${util.program_name()} --help
125+
126+
All documentation details can be found at
127+
${cargo.doc_base_url + '/' + api_index(cargo.doc_base_url, name, version, make, check_exists=False)}
128+
129+
Configuration:
130+
% if supports_scopes(auth):
131+
--${SCOPE_FLAG} <url>
132+
Specify the authentication a method should be executed in. Each scope
133+
requires the user to grant this application permission to use it.
134+
If unset, it defaults to the shortest scope url for a particular method.
135+
% endif scopes
136+
--${CONFIG_DIR_FLAG} <folder>
137+
A directory into which we will store our persistent data. Defaults to
138+
a user-writable directory that we will create during the first invocation.
139+
[default: ${CONFIG_DIR}]
140+
--${DEBUG_FLAG}
141+
Output all server communication to standard error. `tx` and `rx` are placed
142+
into the same stream.
143+
--${DEBUG_AUTH_FLAG}
144+
Output all communication related to authentication to standard error. `tx`
145+
and `rx` are placed into the same stream.
146+
.get_matches();
147+
</%block>
81148
</%def>

src/mako/cli/main.rs.mako

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
<%namespace name="docopt" file="lib/docopt.mako"/>\
1+
<%namespace name="argparse" file="lib/argparse.mako"/>\
22
<%namespace name="engine" file="lib/engine.mako"/>\
33
<%namespace name="util" file="../lib/util.mako"/>\
44
<%
5-
from util import (new_context, rust_comment, to_extern_crate_name, library_to_crate_name, library_name)
5+
from util import (new_context, rust_comment, to_extern_crate_name, library_to_crate_name, library_name,
6+
indent_all_but_first_by)
67
78
c = new_context(schemas, resources, context.get('methods'))
89
default_user_agent = "google-cli-rust-client/" + cargo.build_version
@@ -11,10 +12,9 @@
1112
<%util:gen_info source="${self.uri}" />\
1213
</%block>
1314
#![feature(plugin, exit_status)]
14-
#![plugin(docopt_macros)]
1515
#![allow(unused_variables, unused_imports, dead_code, unused_mut)]
1616

17-
extern crate docopt;
17+
extern crate clap;
1818
extern crate yup_oauth2 as oauth2;
1919
extern crate yup_hyper_mock as mock;
2020
extern crate rustc_serialize;
@@ -25,28 +25,30 @@ extern crate ${to_extern_crate_name(library_to_crate_name(library_name(name, ver
2525

2626
use std::env;
2727
use std::io::{self, Write};
28+
use clap::{App, SubCommand};
2829

29-
${docopt.new(c)}\
30-
31-
${engine.new(c)}\
30+
## ${engine.new(c)}\
3231

3332
fn main() {
34-
let opts: Options = Options::docopt().decode().unwrap_or_else(|e| e.exit());
35-
let debug = opts.flag_debug;
36-
match Engine::new(opts) {
37-
Err(err) => {
38-
writeln!(io::stderr(), "{}", err).ok();
39-
env::set_exit_status(err.exit_code);
40-
},
41-
Ok(engine) => {
42-
if let Some(err) = engine.doit() {
43-
if debug {
44-
writeln!(io::stderr(), "{:?}", err).ok();
45-
} else {
46-
writeln!(io::stderr(), "{}", err).ok();
47-
}
48-
env::set_exit_status(1);
49-
}
50-
}
51-
}
33+
let matches =
34+
${argparse.new(c) | indent_all_but_first_by(1)}\
35+
36+
## let opts: Options = Options::docopt().decode().unwrap_or_else(|e| e.exit());
37+
## let debug = opts.flag_debug;
38+
## match Engine::new(opts) {
39+
## Err(err) => {
40+
## writeln!(io::stderr(), "{}", err).ok();
41+
## env::set_exit_status(err.exit_code);
42+
## },
43+
## Ok(engine) => {
44+
## if let Some(err) = engine.doit() {
45+
## if debug {
46+
## writeln!(io::stderr(), "{:?}", err).ok();
47+
## } else {
48+
## writeln!(io::stderr(), "{}", err).ok();
49+
## }
50+
## env::set_exit_status(1);
51+
## }
52+
## }
53+
## }
5254
}

0 commit comments

Comments
 (0)