summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock49
-rw-r--r--Cargo.toml3
-rw-r--r--src/init.rs41
-rw-r--r--tests/integration_tests.rs14
4 files changed, 81 insertions, 26 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 22aa252..86d35c5 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -227,6 +227,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
+name = "errno"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
+dependencies = [
+ "libc",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "fastrand"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a"
+
+[[package]]
name = "filetime"
version = "0.2.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -352,6 +368,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
[[package]]
+name = "linux-raw-sys"
+version = "0.4.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
+
+[[package]]
name = "lock_api"
version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -526,6 +548,19 @@ dependencies = [
]
[[package]]
+name = "rustix"
+version = "0.38.34"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f"
+dependencies = [
+ "bitflags 2.6.0",
+ "errno",
+ "libc",
+ "linux-raw-sys",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
name = "rustlings"
version = "6.1.0"
dependencies = [
@@ -538,6 +573,7 @@ dependencies = [
"rustlings-macros",
"serde",
"serde_json",
+ "tempfile",
"toml_edit",
]
@@ -710,6 +746,19 @@ dependencies = [
]
[[package]]
+name = "tempfile"
+version = "3.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64"
+dependencies = [
+ "cfg-if",
+ "fastrand",
+ "once_cell",
+ "rustix",
+ "windows-sys 0.59.0",
+]
+
+[[package]]
name = "toml_datetime"
version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index 47e1530..456f738 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -57,6 +57,9 @@ serde_json = "1.0.122"
serde.workspace = true
toml_edit.workspace = true
+[dev-dependencies]
+tempfile = "3.12.0"
+
[profile.release]
panic = "abort"
diff --git a/src/init.rs b/src/init.rs
index dc23cbb..94551c4 100644
--- a/src/init.rs
+++ b/src/init.rs
@@ -4,7 +4,7 @@ use std::{
env::set_current_dir,
fs::{self, create_dir},
io::{self, Write},
- path::Path,
+ path::{Path, PathBuf},
process::{Command, Stdio},
};
@@ -22,14 +22,27 @@ pub fn init() -> Result<()> {
let mut stdout = io::stdout().lock();
let mut init_git = true;
- if Path::new("Cargo.toml").exists() {
+ let manifest_path = Command::new("cargo")
+ .args(["locate-project", "--message-format=plain"])
+ .output()?;
+ if manifest_path.status.success() {
+ let manifest_path: PathBuf = String::from_utf8_lossy(&manifest_path.stdout).trim().into();
+
if Path::new("exercises").exists() && Path::new("solutions").exists() {
bail!(IN_INITIALIZED_DIR_ERR);
}
-
- stdout.write_all(CARGO_TOML_EXISTS_PROMPT_MSG)?;
- press_enter_prompt(&mut stdout)?;
- init_git = false;
+ if fs::read_to_string(manifest_path)?.contains("[workspace]") {
+ // make sure "rustlings" is added to `workspace.members` by making
+ // cargo initialize a new project
+ let output = Command::new("cargo").args(["new", "rustlings"]).output()?;
+ if !output.status.success() {
+ bail!("Failed to initilize new workspace member");
+ }
+ fs::remove_dir_all("rustlings")?;
+ init_git = false;
+ } else {
+ bail!(IN_NON_WORKSPACE_CARGO_PROJECT_ERR);
+ }
}
stdout.write_all(b"This command will create the directory `rustlings/` which will contain the exercises.\nPress ENTER to continue ")?;
@@ -128,19 +141,9 @@ You probably already initialized Rustlings.
Run `cd rustlings`
Then run `rustlings` again";
-const CARGO_TOML_EXISTS_PROMPT_MSG: &[u8] = br#"You are about to initialize Rustlings in a directory that already contains a `Cargo.toml` file!
-
- => It is recommended to abort with CTRL+C and initialize Rustlings in another directory <=
-
-If you know what you are doing and want to initialize Rustlings in a Cargo workspace,
-then you need to add its directory to `members` in the `workspace` section of the `Cargo.toml` file:
-
-```toml
-[workspace]
-members = ["rustlings"]
-```
-
-Press ENTER if you are sure that you want to continue after reading the warning above "#;
+const IN_NON_WORKSPACE_CARGO_PROJECT_ERR: &str = "\
+The current directory is already part of a cargo project.
+Please initialize rustlings in a different directory.";
const POST_INIT_MSG: &str = "Run `cd rustlings` to go into the generated directory.
Then run `rustlings` to get started.";
diff --git a/tests/integration_tests.rs b/tests/integration_tests.rs
index 3ab54f9..d821e20 100644
--- a/tests/integration_tests.rs
+++ b/tests/integration_tests.rs
@@ -155,28 +155,28 @@ fn hint() {
#[test]
fn init() {
- let _ = fs::remove_dir_all("tests/rustlings");
+ let test_dir = tempfile::TempDir::new().unwrap();
+ let initialized_dir = test_dir.path().join("rustlings");
+ let test_dir = test_dir.path().to_str().unwrap();
- Cmd::default().current_dir("tests").fail();
+ Cmd::default().current_dir(test_dir).fail();
Cmd::default()
- .current_dir("tests")
+ .current_dir(test_dir)
.args(&["init"])
.success();
// Running `init` after a successful initialization.
Cmd::default()
- .current_dir("tests")
+ .current_dir(test_dir)
.args(&["init"])
.output(PartialStderr("`cd rustlings`"))
.fail();
// Running `init` in the initialized directory.
Cmd::default()
- .current_dir("tests/rustlings")
+ .current_dir(initialized_dir.to_str().unwrap())
.args(&["init"])
.output(PartialStderr("already initialized"))
.fail();
-
- fs::remove_dir_all("tests/rustlings").unwrap();
}