Skip to content

Commit 186bd22

Browse files
committed
feat: List images to show, move CLI arguments
1 parent 068784d commit 186bd22

File tree

9 files changed

+150
-88
lines changed

9 files changed

+150
-88
lines changed

rust/boil/src/build/bakefile.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -123,12 +123,10 @@ impl Targets {
123123
targets.insert_targets(image_name.to_owned(), pairs, &options, true)?;
124124
}
125125

126-
println!("{targets:#?}");
127-
128126
Ok(targets)
129127
}
130128

131-
pub fn from_images(images: &[Image], options: TargetsOptions) -> Result<Self, TargetsError> {
129+
pub fn set(images: &[Image], options: TargetsOptions) -> Result<Self, TargetsError> {
132130
let mut targets = Self::default();
133131

134132
for image in images {
@@ -214,9 +212,9 @@ impl Bakefile {
214212
/// This will only create targets for selected entry images and their dependencies. There is no
215213
/// need to filter anything out afterwards. The filtering is done automatically internally.
216214
pub fn from_args(args: &cli::BuildArguments, config: Config) -> Result<Self, Error> {
217-
let graph = Targets::from_images(&args.images, TargetsOptions::default())
218-
.context(CreateGraphSnafu)?;
219-
Self::from_targets(graph, args, config)
215+
let targets =
216+
Targets::set(&args.images, TargetsOptions::default()).context(CreateGraphSnafu)?;
217+
Self::from_targets(targets, args, config)
220218
}
221219

222220
/// Returns all image manifest URIs for entry images.

rust/boil/src/build/cli.rs

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
1-
use std::path::PathBuf;
1+
use std::{path::PathBuf, str::FromStr};
22

33
use clap::{Args, ValueHint, value_parser};
44
use semver::Version;
5+
use snafu::{ResultExt, Snafu, ensure};
56
use url::Host;
67

7-
use crate::{
8-
build::{
9-
docker::BuildArgument,
10-
image::Image,
11-
platform::{Architecture, TargetPlatform},
12-
},
13-
cli::parse_image_version,
8+
use crate::build::{
9+
docker::BuildArgument,
10+
image::Image,
11+
platform::{Architecture, TargetPlatform},
1412
};
1513

1614
#[derive(Debug, Args)]
@@ -124,3 +122,19 @@ impl BuildArguments {
124122
PathBuf::from("Dockerfile")
125123
}
126124
}
125+
126+
#[derive(Debug, Snafu)]
127+
pub enum ParseImageVersionError {
128+
#[snafu(display("failed to parse semantic version"))]
129+
ParseVersion { source: semver::Error },
130+
131+
#[snafu(display("semantic version must not contain build metadata"))]
132+
ContainsBuildMetadata,
133+
}
134+
135+
pub fn parse_image_version(input: &str) -> Result<Version, ParseImageVersionError> {
136+
let version = Version::from_str(input).context(ParseVersionSnafu)?;
137+
ensure!(version.build.is_empty(), ContainsBuildMetadataSnafu);
138+
139+
Ok(version)
140+
}

rust/boil/src/cli.rs

Lines changed: 3 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
1-
use std::{path::PathBuf, str::FromStr};
1+
use std::path::PathBuf;
22

3-
use clap::{Args, Parser, Subcommand};
4-
use clap_complete::Shell;
5-
use semver::Version;
6-
use snafu::{ResultExt, Snafu, ensure};
3+
use clap::{Parser, Subcommand};
74

8-
use crate::build::cli::BuildArguments;
5+
use crate::{build::cli::BuildArguments, completions::CompletionsArguments, show::ShowArguments};
96

107
#[derive(Debug, Parser)]
118
#[command(author, version, about)]
@@ -53,37 +50,3 @@ pub enum Command {
5350
/// Generate shell completions.
5451
Completions(CompletionsArguments),
5552
}
56-
57-
#[derive(Debug, Args)]
58-
pub struct ShowArguments {
59-
#[command(subcommand)]
60-
pub commands: ShowCommand,
61-
}
62-
63-
#[derive(Debug, Subcommand)]
64-
pub enum ShowCommand {
65-
Images,
66-
Tree,
67-
}
68-
69-
#[derive(Debug, Args)]
70-
pub struct CompletionsArguments {
71-
/// Shell to generate completions for.
72-
pub shell: Shell,
73-
}
74-
75-
#[derive(Debug, Snafu)]
76-
pub enum ParseImageVersionError {
77-
#[snafu(display("failed to parse semantic version"))]
78-
ParseVersion { source: semver::Error },
79-
80-
#[snafu(display("semantic version must not contain build metadata"))]
81-
ContainsBuildMetadata,
82-
}
83-
84-
pub fn parse_image_version(input: &str) -> Result<Version, ParseImageVersionError> {
85-
let version = Version::from_str(input).context(ParseVersionSnafu)?;
86-
ensure!(version.build.is_empty(), ContainsBuildMetadataSnafu);
87-
88-
Ok(version)
89-
}

rust/boil/src/completions/mod.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
1-
use clap::CommandFactory;
1+
use clap::{Args, CommandFactory};
2+
use clap_complete::Shell;
23

3-
use crate::cli::{Cli, CompletionsArguments};
4+
use crate::cli::Cli;
5+
6+
#[derive(Debug, Args)]
7+
pub struct CompletionsArguments {
8+
/// Shell to generate completions for.
9+
pub shell: Shell,
10+
}
411

512
pub fn run_command(arguments: CompletionsArguments) {
613
let mut cli = Cli::command();

rust/boil/src/main.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ use semver::Version;
33
use snafu::{ResultExt, Snafu};
44

55
use crate::{
6-
cli::{Cli, Command, ShowCommand},
6+
cli::{Cli, Command},
77
config::Config,
8+
show::ShowCommand,
89
};
910

1011
// Common modules
@@ -83,7 +84,9 @@ async fn main() -> Result<(), Error> {
8384
build::run_command(arguments, config).context(BuildSnafu)
8485
}
8586
Command::Show(arguments) => match arguments.commands {
86-
ShowCommand::Images => show::images::run_command().context(ShowSnafu),
87+
ShowCommand::Images(arguments) => {
88+
show::images::run_command(arguments).context(ShowSnafu)
89+
}
8790
ShowCommand::Tree => todo!(),
8891
},
8992
Command::Completions(arguments) => {

rust/boil/src/show/images.rs

Lines changed: 0 additions & 30 deletions
This file was deleted.

rust/boil/src/show/images/cli.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
use clap::Args;
2+
3+
use crate::build::image::Image;
4+
5+
#[derive(Debug, Args)]
6+
pub struct ShowImagesArguments {
7+
/// Optionally specify one or more images to display.
8+
pub image: Vec<Image>,
9+
10+
/// Pretty print the structured output.
11+
#[arg(long)]
12+
pub pretty: bool,
13+
}

rust/boil/src/show/images/mod.rs

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
use std::collections::BTreeMap;
2+
3+
use serde::{Serialize, ser::SerializeSeq};
4+
use snafu::{ResultExt, Snafu};
5+
6+
use crate::{
7+
build::bakefile::{Targets, TargetsError, TargetsOptions},
8+
show::images::cli::ShowImagesArguments,
9+
};
10+
11+
pub mod cli;
12+
13+
#[derive(Debug, Snafu)]
14+
pub enum Error {
15+
#[snafu(display("failed to serialize list as JSON"))]
16+
SerializeList { source: serde_json::Error },
17+
18+
#[snafu(display("failed to build list of targets"))]
19+
BuildTargets { source: TargetsError },
20+
}
21+
22+
// NOTE (@Techassi): I don't know if I like this... but this makes the stdout output very convient
23+
// to consume.
24+
struct OneOrMany(BTreeMap<String, Vec<String>>);
25+
26+
impl Serialize for OneOrMany {
27+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
28+
where
29+
S: serde::Serializer,
30+
{
31+
if self.0.len() == 1 {
32+
let mut seq = serializer.serialize_seq(Some(1))?;
33+
for entry in &self.0 {
34+
for version in entry.1 {
35+
seq.serialize_element(&version)?;
36+
}
37+
}
38+
39+
Ok(seq.end()?)
40+
} else {
41+
self.0.serialize(serializer)
42+
}
43+
}
44+
}
45+
46+
pub fn run_command(arguments: ShowImagesArguments) -> Result<(), Error> {
47+
let list: BTreeMap<_, _> = if arguments.image.is_empty() {
48+
Targets::all(TargetsOptions { only_entry: true })
49+
.context(BuildTargetsSnafu)?
50+
.into_iter()
51+
} else {
52+
Targets::set(&arguments.image, TargetsOptions { only_entry: true })
53+
.context(BuildTargetsSnafu)?
54+
.into_iter()
55+
}
56+
.map(|(image_name, image_versions)| {
57+
let versions: Vec<_> = image_versions
58+
.into_iter()
59+
.map(|(image_version, (_, _))| image_version)
60+
.collect();
61+
(image_name, versions)
62+
})
63+
.collect();
64+
65+
print_to_stdout(list, arguments.pretty)
66+
}
67+
68+
fn print_to_stdout(list: BTreeMap<String, Vec<String>>, pretty: bool) -> Result<(), Error> {
69+
let stdout = std::io::stdout();
70+
71+
let list = OneOrMany(list);
72+
73+
if pretty {
74+
serde_json::to_writer_pretty(stdout, &list).context(SerializeListSnafu)
75+
} else {
76+
serde_json::to_writer(stdout, &list).context(SerializeListSnafu)
77+
}
78+
}

rust/boil/src/show/mod.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,17 @@
1+
use clap::{Args, Subcommand};
2+
3+
use crate::show::images::cli::ShowImagesArguments;
4+
15
pub mod images;
6+
7+
#[derive(Debug, Args)]
8+
pub struct ShowArguments {
9+
#[command(subcommand)]
10+
pub commands: ShowCommand,
11+
}
12+
13+
#[derive(Debug, Subcommand)]
14+
pub enum ShowCommand {
15+
Images(ShowImagesArguments),
16+
Tree,
17+
}

0 commit comments

Comments
 (0)