Skip to content

Commit bf3494d

Browse files
authored
Merge pull request #47 from skipkayhil/hm-no-versions
Remove hardcoded Ruby/Rails versions, add `--rebuild` flag
2 parents 7ba18e0 + 262dc86 commit bf3494d

File tree

3 files changed

+184
-22
lines changed

3 files changed

+184
-22
lines changed

src/docker_client.rs

+124-12
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,23 @@ pub struct DockerClient {}
55
impl DockerClient {
66
pub fn build_image(
77
ruby_version: &str,
8-
rails_version: &str,
8+
maybe_rails_version: Option<&str>,
99
user_id: Option<u32>,
1010
group_id: Option<u32>,
11+
rebuild: bool,
1112
) -> Command {
1213
let mut command = Command::new("docker");
1314

1415
command.arg("build");
1516

17+
if rebuild {
18+
command.arg("--no-cache");
19+
}
20+
1621
Self::set_build_arg(&mut command, "RUBY_VERSION", ruby_version);
17-
Self::set_build_arg(&mut command, "RAILS_VERSION", rails_version);
22+
if let Some(rails_version) = maybe_rails_version {
23+
Self::set_build_arg(&mut command, "RAILS_VERSION", rails_version);
24+
}
1825

1926
if let Some(id) = user_id {
2027
Self::set_build_arg(&mut command, "USER_ID", &id.to_string())
@@ -25,14 +32,18 @@ impl DockerClient {
2532

2633
command.arg("-t");
2734

28-
Self::set_image_name(&mut command, ruby_version, rails_version);
35+
Self::set_image_name(&mut command, ruby_version, maybe_rails_version);
2936

3037
command.arg("-").stdin(Stdio::piped());
3138

3239
command
3340
}
3441

35-
pub fn run_image(ruby_version: &str, rails_version: &str, args: Vec<String>) -> Command {
42+
pub fn run_image(
43+
ruby_version: &str,
44+
rails_version: Option<&str>,
45+
args: Vec<String>,
46+
) -> Command {
3647
let mut command = Self::run();
3748

3849
Self::set_workdir(&mut command);
@@ -42,7 +53,7 @@ impl DockerClient {
4253
command
4354
}
4455

45-
pub fn get_help(ruby_version: &str, rails_version: &str) -> Command {
56+
pub fn get_help(ruby_version: &str, rails_version: Option<&str>) -> Command {
4657
let mut command = Self::run();
4758

4859
Self::set_image_name(&mut command, ruby_version, rails_version);
@@ -76,8 +87,16 @@ impl DockerClient {
7687
.args(["-w", current_dir]);
7788
}
7889

79-
fn set_image_name(command: &mut Command, ruby_version: &str, rails_version: &str) {
80-
command.arg(format!("rails-new-{}-{}", ruby_version, rails_version));
90+
fn set_image_name(
91+
command: &mut Command,
92+
ruby_version: &str,
93+
maybe_rails_version: Option<&str>,
94+
) {
95+
if let Some(rails_version) = maybe_rails_version {
96+
command.arg(format!("rails-new-{}-{}", ruby_version, rails_version));
97+
} else {
98+
command.arg(format!("rails-new-{}", ruby_version));
99+
}
81100
}
82101

83102
fn set_rails_new(command: &mut Command, args: Vec<String>) {
@@ -116,7 +135,7 @@ mod tests {
116135

117136
#[test]
118137
fn build_image() {
119-
let command = DockerClient::build_image("3.2.3", "7.1.3", None, None);
138+
let command = DockerClient::build_image("3.2.3", Some("7.1.3"), None, None, false);
120139

121140
assert_eq!(command.get_program(), "docker");
122141

@@ -139,7 +158,7 @@ mod tests {
139158

140159
#[test]
141160
fn build_image_with_user_id() {
142-
let command = DockerClient::build_image("3.2.3", "7.1.3", Some(1000), None);
161+
let command = DockerClient::build_image("3.2.3", Some("7.1.3"), Some(1000), None, false);
143162

144163
assert_eq!(command.get_program(), "docker");
145164

@@ -164,7 +183,7 @@ mod tests {
164183

165184
#[test]
166185
fn build_image_with_group_id() {
167-
let command = DockerClient::build_image("3.2.3", "7.1.3", None, Some(1000));
186+
let command = DockerClient::build_image("3.2.3", Some("7.1.3"), None, Some(1000), false);
168187

169188
assert_eq!(command.get_program(), "docker");
170189

@@ -187,9 +206,75 @@ mod tests {
187206
);
188207
}
189208

209+
#[test]
210+
fn build_image_with_rebuild_flag() {
211+
let command = DockerClient::build_image("3.2.3", Some("7.1.3"), None, None, true);
212+
213+
let args: Vec<&OsStr> = command.get_args().collect();
214+
215+
assert_eq!(
216+
args,
217+
&[
218+
"build",
219+
"--no-cache",
220+
"--build-arg",
221+
"RUBY_VERSION=3.2.3",
222+
"--build-arg",
223+
"RAILS_VERSION=7.1.3",
224+
"-t",
225+
"rails-new-3.2.3-7.1.3",
226+
"-",
227+
]
228+
);
229+
}
230+
231+
#[test]
232+
fn build_image_without_rails_version() {
233+
let command = DockerClient::build_image("3.2.3", None, None, None, false);
234+
235+
let args: Vec<&OsStr> = command.get_args().collect();
236+
237+
assert_eq!(
238+
args,
239+
&[
240+
"build",
241+
"--build-arg",
242+
"RUBY_VERSION=3.2.3",
243+
"-t",
244+
"rails-new-3.2.3",
245+
"-",
246+
]
247+
);
248+
}
249+
250+
#[test]
251+
fn build_image_with_both_ids() {
252+
let command = DockerClient::build_image("3.2.3", Some("7.1.3"), Some(1000), Some(1000), false);
253+
254+
let args: Vec<&OsStr> = command.get_args().collect();
255+
256+
assert_eq!(
257+
args,
258+
&[
259+
"build",
260+
"--build-arg",
261+
"RUBY_VERSION=3.2.3",
262+
"--build-arg",
263+
"RAILS_VERSION=7.1.3",
264+
"--build-arg",
265+
"USER_ID=1000",
266+
"--build-arg",
267+
"GROUP_ID=1000",
268+
"-t",
269+
"rails-new-3.2.3-7.1.3",
270+
"-",
271+
]
272+
);
273+
}
274+
190275
#[test]
191276
fn run_image() {
192-
let command = DockerClient::run_image("3.2.3", "7.1.3", vec!["my_app".to_string()]);
277+
let command = DockerClient::run_image("3.2.3", Some("7.1.3"), vec!["my_app".to_string()]);
193278

194279
assert_eq!(command.get_program(), "docker");
195280

@@ -216,9 +301,36 @@ mod tests {
216301
);
217302
}
218303

304+
#[test]
305+
fn run_image_without_rails_version() {
306+
let command = DockerClient::run_image("3.2.3", None, vec!["my_app".to_string()]);
307+
308+
let binding = current_dir().unwrap();
309+
let absolute_path = canonicalize_os_path(&binding).unwrap();
310+
let current_dir = absolute_path.to_str().unwrap();
311+
312+
let args: Vec<&OsStr> = command.get_args().collect();
313+
314+
assert_eq!(
315+
args,
316+
&[
317+
"run",
318+
"--rm",
319+
"-v",
320+
&format!("{}:{}", current_dir, current_dir),
321+
"-w",
322+
current_dir,
323+
"rails-new-3.2.3",
324+
"rails",
325+
"new",
326+
"my_app",
327+
]
328+
);
329+
}
330+
219331
#[test]
220332
fn get_help() {
221-
let command = DockerClient::get_help("3.2.3", "7.1.3");
333+
let command = DockerClient::get_help("3.2.3", Some("7.1.3"));
222334

223335
assert_eq!(command.get_program(), "docker");
224336

src/main.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,17 @@ fn main() {
1818
let cli = Cli::parse();
1919

2020
let ruby_version = cli.ruby_version;
21-
let rails_version = cli.rails_version;
21+
let rails_version = cli.rails_version.as_deref();
22+
let rebuild = cli.rebuild;
2223

2324
// Run docker build --build-arg RUBY_VERSION=$RUBY_VERSION --build-arg RAILS_VERSION=$RAILS_VERSION -t rails-new-$RUBY_VERSION-$RAILS_VERSION
2425
// passing the content of DOCKERFILE to the command stdin
2526
let mut child = DockerClient::build_image(
2627
&ruby_version,
27-
&rails_version,
28+
rails_version,
2829
os_specific::get_user_id(),
2930
os_specific::get_group_id(),
31+
rebuild,
3032
)
3133
.spawn()
3234
.expect("Failed to execute process");
@@ -44,12 +46,12 @@ fn main() {
4446

4547
match &cli.command {
4648
Some(Commands::RailsHelp {}) => {
47-
command = DockerClient::get_help(&ruby_version, &rails_version)
49+
command = DockerClient::get_help(&ruby_version, rails_version)
4850
}
4951

5052
None => {
5153
// Run the image with docker run -v $(pwd):/$(pwd) -w $(pwd) rails-new-$RUBY_VERSION-$RAILS_VERSION rails new $@
52-
command = DockerClient::run_image(&ruby_version, &rails_version, cli.args)
54+
command = DockerClient::run_image(&ruby_version, rails_version, cli.args)
5355
}
5456
}
5557

src/rails_new.rs

+54-6
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@ pub struct Cli {
66
#[clap(trailing_var_arg = true, required = true)]
77
/// arguments passed to `rails new`
88
pub args: Vec<String>,
9-
#[clap(long, short = 'u', default_value = "3.4.1")]
9+
#[clap(long, short = 'u', default_value = "latest")]
1010
pub ruby_version: String,
11-
#[clap(long, short = 'r', default_value = "8.0.1")]
12-
pub rails_version: String,
11+
#[clap(long, short = 'r')]
12+
pub rails_version: Option<String>,
13+
#[clap(long)]
14+
pub rebuild: bool,
1315

1416
#[command(subcommand)]
1517
pub command: Option<Commands>,
@@ -52,10 +54,8 @@ mod tests {
5254
let m = Cli::command().get_matches_from(vec!["rails-new", "my_app"]);
5355

5456
let ruby_version = m.get_one::<String>("ruby_version").unwrap();
55-
let rails_version = m.get_one::<String>("rails_version").unwrap();
5657

57-
assert_eq!(ruby_version, "3.4.1");
58-
assert_eq!(rails_version, "8.0.1");
58+
assert_eq!(ruby_version, "latest");
5959

6060
Ok(())
6161
}
@@ -73,4 +73,52 @@ mod tests {
7373

7474
Ok(())
7575
}
76+
77+
#[test]
78+
fn custom_ruby_version() -> Result<(), Box<dyn std::error::Error>> {
79+
use clap::CommandFactory;
80+
81+
let m = Cli::command().get_matches_from(vec!["rails-new", "--ruby-version", "3.2.0", "my_app"]);
82+
let ruby_version = m.get_one::<String>("ruby_version").unwrap();
83+
assert_eq!(ruby_version, "3.2.0");
84+
85+
// Test short form
86+
let m = Cli::command().get_matches_from(vec!["rails-new", "-u", "3.2.0", "my_app"]);
87+
let ruby_version = m.get_one::<String>("ruby_version").unwrap();
88+
assert_eq!(ruby_version, "3.2.0");
89+
90+
Ok(())
91+
}
92+
93+
#[test]
94+
fn rails_version_flag() -> Result<(), Box<dyn std::error::Error>> {
95+
use clap::CommandFactory;
96+
97+
let m = Cli::command().get_matches_from(vec!["rails-new", "--rails-version", "7.1.0", "my_app"]);
98+
let rails_version = m.get_one::<String>("rails_version").unwrap();
99+
assert_eq!(rails_version, "7.1.0");
100+
101+
// Test short form
102+
let m = Cli::command().get_matches_from(vec!["rails-new", "-r", "7.1.0", "my_app"]);
103+
let rails_version = m.get_one::<String>("rails_version").unwrap();
104+
assert_eq!(rails_version, "7.1.0");
105+
106+
Ok(())
107+
}
108+
109+
#[test]
110+
fn rebuild_flag() -> Result<(), Box<dyn std::error::Error>> {
111+
use clap::CommandFactory;
112+
113+
let m = Cli::command().get_matches_from(vec!["rails-new", "--rebuild", "my_app"]);
114+
let rebuild = m.get_flag("rebuild");
115+
assert!(rebuild);
116+
117+
// Test default value (false)
118+
let m = Cli::command().get_matches_from(vec!["rails-new", "my_app"]);
119+
let rebuild = m.get_flag("rebuild");
120+
assert!(!rebuild);
121+
122+
Ok(())
123+
}
76124
}

0 commit comments

Comments
 (0)