Skip to content

Commit 7e09c15

Browse files
committed
Remove bash script and push logic to Rust binary
1 parent 017510d commit 7e09c15

File tree

5 files changed

+72
-36
lines changed

5 files changed

+72
-36
lines changed

README.md

+5-8
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,19 @@ Rails versions for you, so you don't have to worry about it.
88
You need to have Docker installed on your machine. You can find instructions on how to install Docker on your machine
99
[here](https://docs.docker.com/engine/install/).
1010

11-
## Usage
11+
## Installation
1212

13-
First, clone the repository:
1413

15-
```bash
16-
git clone https://github.com/rails/rails-new.git
17-
cd rails-new
18-
```
14+
15+
## Usage
1916

2017
To generate a new Rails application, you can run the following command:
2118

2219
```bash
23-
bin/rails-new myapp
20+
rails-new myapp
2421
```
2522

2623
Or with options:
2724
```bash
28-
bin/rails-new myapp --main
25+
rails-new myapp --main
2926
```

bin/rails-new

-20
This file was deleted.

src/main.rs

+44-5
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,56 @@
33
// use std::process::Command;
44
mod rails_new;
55
use rails_new::Cli;
6-
use std::process::Command;
6+
use std::io::Write;
7+
use std::process::{Command, Stdio};
78

89
use clap::Parser;
910

1011
fn main() {
1112
let cli = Cli::parse();
1213

13-
// Execute the bash file rails-new
14-
let status = Command::new("bash")
15-
.arg("bin/rails-new")
16-
.arg(cli.name)
14+
// read the content of the DOCKERFILE and store it in a variable
15+
let dockerfile = include_str!("../Dockerfile");
16+
17+
let ruby_version = cli.ruby_version.unwrap();
18+
let rails_version = cli.rails_version.unwrap();
19+
20+
// Run docker build --build-arg RUBY_VERSION=$RUBY_VERSION --build-arg RAILS_VERSION=$RAILS_VERSION -t rails-new-$RUBY_VERSION-$RAILS_VERSION
21+
// passing the content of DOCKERFILE to the command stdin
22+
let mut child = Command::new("docker")
23+
.arg("build")
24+
.arg("--build-arg")
25+
.arg(format!("RUBY_VERSION={}", ruby_version))
26+
.arg("--build-arg")
27+
.arg(format!("RAILS_VERSION={}", rails_version))
28+
.arg("-t")
29+
.arg(format!("rails-new-{}-{}", ruby_version, rails_version))
30+
.arg("-")
31+
.stdin(Stdio::piped())
32+
.spawn()
33+
.expect("Failed to execute process");
34+
35+
let stdin = child.stdin.as_mut().expect("Failed to open stdin");
36+
stdin.write_all(dockerfile.as_bytes()).unwrap();
37+
38+
let status = child.wait().expect("failed to wait on child");
39+
40+
assert!(status.success());
41+
42+
// Run the image with docker run -v $(pwd):/$(pwd) -w $(pwd) rails-new-$RUBY_VERSION-$RAILS_VERSION rails new $@
43+
let binding = std::env::current_dir().unwrap();
44+
let current_dir = binding.to_str().unwrap();
45+
46+
let status = Command::new("docker")
47+
.arg("run")
48+
.arg("-v")
49+
.arg(format!("{}:{}", current_dir, current_dir))
50+
.arg("-w")
51+
.arg(current_dir)
52+
.arg(format!("rails-new-{}-{}", ruby_version, rails_version))
53+
.arg("rails")
54+
.arg("new")
55+
.args(cli.args)
1756
.status()
1857
.expect("Failed to execute process");
1958

src/rails_new.rs

+19-1
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,29 @@ use clap::Parser;
33
#[derive(Parser)]
44
#[command(version, about, long_about = None)]
55
pub struct Cli {
6-
pub name: String,
6+
#[clap(trailing_var_arg = true, required = true)]
7+
pub args: Vec<String>,
8+
#[clap(long, short = 'u', default_value = "3.2.3")]
9+
pub ruby_version: Option<String>,
10+
#[clap(long, short = 'r', default_value = "7.1.3")]
11+
pub rails_version: Option<String>,
712
}
813

914
#[test]
1015
fn verify_cli() {
1116
use clap::CommandFactory;
1217
Cli::command().debug_assert()
1318
}
19+
20+
#[test]
21+
fn arguments_are_directed_to_rails_new() -> Result<(), Box<dyn std::error::Error>> {
22+
use clap::CommandFactory;
23+
24+
let m = Cli::command().get_matches_from(vec!["rails-new", "my_app", "--main"]);
25+
26+
let trail: Vec<_> = m.get_many::<String>("args").unwrap().collect();
27+
28+
assert_eq!(trail, &["my_app", "--main"]);
29+
30+
Ok(())
31+
}

tests/cli.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@ fn requires_a_name() -> Result<(), Box<dyn std::error::Error>> {
88

99
cmd.assert()
1010
.failure()
11-
.stderr(predicate::str::contains("the following required arguments were not provided:"))
12-
.stderr(predicate::str::contains("<NAME>"));
11+
.stderr(predicate::str::contains(
12+
"the following required arguments were not provided:",
13+
))
14+
.stderr(predicate::str::contains("<ARGS>..."));
1315

1416
Ok(())
1517
}

0 commit comments

Comments
 (0)