Skip to content
This repository was archived by the owner on Oct 28, 2024. It is now read-only.

Commit abe8108

Browse files
authored
Require Hippo args on push (#52)
1 parent 9d0ca38 commit abe8108

File tree

1 file changed

+84
-49
lines changed

1 file changed

+84
-49
lines changed

src/main.rs

Lines changed: 84 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,19 @@ mod expander;
1313
mod hippo_notifier;
1414
mod hippofacts;
1515

16+
/// Indicate which flags are required for bindle builds
17+
#[allow(dead_code)]
18+
enum BindleBuildRequirements {
19+
/// A Bindle server URL is required
20+
RequireBindleServer,
21+
/// An explicit stage directory is required
22+
RequireStageDirectory,
23+
/// Both the Bindle server and the stage directory are required
24+
RequireBindleServerAndStageDirectory,
25+
/// There are no required arguments for the bindle builds
26+
NoRequirements,
27+
}
28+
1629
const ARG_HIPPOFACTS: &str = "hippofacts_path";
1730
const ARG_STAGING_DIR: &str = "output_dir";
1831
const ARG_OUTPUT: &str = "output_format";
@@ -35,49 +48,6 @@ in which you are running the 'hippo' command.
3548

3649
#[tokio::main]
3750
async fn main() -> anyhow::Result<()> {
38-
// Arguments necessary to build a bindle (but not push it)
39-
// - ARG_HIPPOFACTS
40-
// - ARG_VERSIONING
41-
// - ARG_OUTPUT
42-
// - ARG_BINDLE_URL
43-
// - ARG_STAGING_DIR
44-
let bindle_build_args = vec![
45-
Arg::new(ARG_HIPPOFACTS)
46-
.required(true)
47-
.index(1)
48-
.about("The artifacts spec (file or directory containing HIPPOFACTS file)"),
49-
Arg::new(ARG_VERSIONING)
50-
.possible_values(&["dev", "production"])
51-
.default_value("dev")
52-
.required(false)
53-
.short('v')
54-
.long("invoice-version")
55-
.about("How to version the generated invoice"),
56-
Arg::new(ARG_OUTPUT)
57-
.possible_values(&["id", "message", "none"])
58-
.default_value("message")
59-
.required(false)
60-
.short('o')
61-
.long("output")
62-
.about("What to print on success"),
63-
Arg::new(ARG_BINDLE_URL)
64-
.short('s')
65-
.long("server")
66-
.env("BINDLE_URL")
67-
.about("The Bindle server to push the artifacts to"),
68-
Arg::new(ARG_INSECURE)
69-
.required(false)
70-
.takes_value(false)
71-
.short('k')
72-
.long("insecure")
73-
.about("If set, ignore server certificate errors"),
74-
Arg::new(ARG_STAGING_DIR)
75-
.takes_value(true)
76-
.short('d')
77-
.long("dir")
78-
.about("The path to output the artifacts to. Required when doing a `hippo prepare`. Other commands will use a temp dir if this is not specified."),
79-
];
80-
8151
let matches = App::new(env!("CARGO_PKG_NAME"))
8252
.version(env!("CARGO_PKG_VERSION"))
8353
.author("Deis Labs")
@@ -86,21 +56,24 @@ async fn main() -> anyhow::Result<()> {
8656
.subcommand(
8757
App::new("push")
8858
.about("Packages and uploads Hippo artifacts, notifying Hippo")
89-
.args(&bindle_build_args)
59+
.args(bindle_build_args(BindleBuildRequirements::RequireBindleServer))
9060
.arg(
9161
Arg::new(ARG_HIPPO_URL)
62+
.required(true)
9263
.long("hippo-url")
9364
.env("HIPPO_URL")
9465
.about("The Hippo service to push the artifacts to"),
9566
)
9667
.arg(
9768
Arg::new(ARG_HIPPO_USERNAME)
69+
.required(true)
9870
.long("hippo-username")
9971
.env("HIPPO_USERNAME")
10072
.about("The username for connecting to Hippo"),
10173
)
10274
.arg(
10375
Arg::new(ARG_HIPPO_PASSWORD)
76+
.required(true)
10477
.long("hippo-password")
10578
.env("HIPPO_PASSWORD")
10679
.about("The username for connecting to Hippo"),
@@ -109,12 +82,12 @@ async fn main() -> anyhow::Result<()> {
10982
.subcommand(
11083
App::new("prepare")
11184
.about("Reads a HIPPOFACTS file and prepares a Bindle, caching it locally.")
112-
.args(&bindle_build_args),
85+
.args(bindle_build_args(BindleBuildRequirements::RequireStageDirectory)),
11386
)
11487
.subcommand(
11588
App::new("bindle")
11689
.about("Creates a bindle and pushes it to the Bindle server, but does not notify Hippo")
117-
.args(&bindle_build_args),
90+
.args(bindle_build_args(BindleBuildRequirements::RequireBindleServer)),
11891
)
11992
.get_matches();
12093

@@ -127,6 +100,65 @@ async fn main() -> anyhow::Result<()> {
127100
}
128101
}
129102

103+
/// Constructs arguments used to do a Bindle build.
104+
/// Arguments necessary to build a bindle (but not push it)
105+
/// - ARG_HIPPOFACTS
106+
/// - ARG_VERSIONING
107+
/// - ARG_OUTPUT
108+
/// - ARG_BINDLE_URL
109+
/// - ARG_STAGING_DIR
110+
fn bindle_build_args<'a>(requirements: BindleBuildRequirements) -> Vec<Arg<'a>> {
111+
let require_bindle_server = matches!(
112+
requirements,
113+
BindleBuildRequirements::RequireBindleServer
114+
| BindleBuildRequirements::RequireBindleServerAndStageDirectory
115+
);
116+
let require_stage_dir = matches!(
117+
requirements,
118+
BindleBuildRequirements::RequireStageDirectory
119+
| BindleBuildRequirements::RequireBindleServerAndStageDirectory
120+
);
121+
122+
vec![
123+
Arg::new(ARG_HIPPOFACTS)
124+
.required(true)
125+
.index(1)
126+
.about("The artifacts spec (file or directory containing HIPPOFACTS file)"),
127+
Arg::new(ARG_VERSIONING)
128+
.possible_values(&["dev", "production"])
129+
.default_value("dev")
130+
.required(false)
131+
.short('v')
132+
.long("invoice-version")
133+
.about("How to version the generated invoice"),
134+
Arg::new(ARG_OUTPUT)
135+
.possible_values(&["id", "message", "none"])
136+
.default_value("message")
137+
.required(false)
138+
.short('o')
139+
.long("output")
140+
.about("What to print on success"),
141+
Arg::new(ARG_BINDLE_URL)
142+
.short('s')
143+
.long("server")
144+
.env("BINDLE_URL")
145+
.about("The Bindle server to push the artifacts to")
146+
.required(require_bindle_server),
147+
Arg::new(ARG_INSECURE)
148+
.required(false)
149+
.takes_value(false)
150+
.short('k')
151+
.long("insecure")
152+
.about("If set, ignore server certificate errors"),
153+
Arg::new(ARG_STAGING_DIR)
154+
.takes_value(true)
155+
.short('d')
156+
.long("dir")
157+
.about("The path to output the artifacts to. Required when doing a `hippo prepare`. Other commands will use a temp dir if this is not specified.")
158+
.required(require_stage_dir),
159+
]
160+
}
161+
130162
/// Run the prepare command
131163
///
132164
/// Args:
@@ -231,13 +263,16 @@ async fn push(args: &ArgMatches) -> anyhow::Result<()> {
231263
})?);
232264

233265
// Hippo configuration
234-
let hippo_url = args.value_of(ARG_HIPPO_URL).map(|s| s.to_owned());
266+
let hippo_url = args
267+
.value_of(ARG_HIPPO_URL)
268+
.map(|s| s.to_owned())
269+
.ok_or_else(|| anyhow::anyhow!("A Hippo url is required. Use --hippo-url or $HIPPO_URL"))?;
235270
let hippo_username = args.value_of(ARG_HIPPO_USERNAME);
236271
let hippo_password = args.value_of(ARG_HIPPO_PASSWORD);
237272

238273
// Notification configuration
239-
let notify_to = hippo_url.map(|url| hippo_notifier::ConnectionInfo {
240-
url,
274+
let notify_to = Some(hippo_notifier::ConnectionInfo {
275+
url: hippo_url,
241276
danger_accept_invalid_certs: args.is_present(ARG_INSECURE),
242277
username: hippo_username.unwrap().to_owned(), // Known to be set if the URL is
243278
password: hippo_password.unwrap().to_owned(),

0 commit comments

Comments
 (0)