@@ -3,30 +3,40 @@ use ratatui::crossterm::style::Stylize;
3
3
use std:: {
4
4
env:: set_current_dir,
5
5
fs:: { self , create_dir} ,
6
- io:: ErrorKind ,
6
+ io:: { self , Write } ,
7
7
path:: Path ,
8
8
process:: { Command , Stdio } ,
9
9
} ;
10
10
11
- use crate :: { cargo_toml:: updated_cargo_toml, embedded:: EMBEDDED_FILES , info_file:: InfoFile } ;
11
+ use crate :: {
12
+ cargo_toml:: updated_cargo_toml, embedded:: EMBEDDED_FILES , info_file:: InfoFile ,
13
+ term:: press_enter_prompt,
14
+ } ;
12
15
13
16
pub fn init ( ) -> Result < ( ) > {
14
- // Prevent initialization in a directory that contains the file `Cargo.toml`.
15
- // This can mean that Rustlings was already initialized in this directory.
16
- // Otherwise, this can cause problems with Cargo workspaces.
17
- if Path :: new ( "Cargo.toml" ) . exists ( ) {
18
- bail ! ( CARGO_TOML_EXISTS_ERR ) ;
17
+ let rustlings_dir = Path :: new ( "rustlings" ) ;
18
+ if rustlings_dir. exists ( ) {
19
+ bail ! ( RUSTLINGS_DIR_ALREADY_EXISTS_ERR ) ;
19
20
}
20
21
21
- let rustlings_path = Path :: new ( "rustlings" ) ;
22
- if let Err ( e) = create_dir ( rustlings_path) {
23
- if e. kind ( ) == ErrorKind :: AlreadyExists {
24
- bail ! ( RUSTLINGS_DIR_ALREADY_EXISTS_ERR ) ;
22
+ let mut stdout = io:: stdout ( ) . lock ( ) ;
23
+ let mut init_git = true ;
24
+
25
+ if Path :: new ( "Cargo.toml" ) . exists ( ) {
26
+ if Path :: new ( "exercises" ) . exists ( ) && Path :: new ( "solutions" ) . exists ( ) {
27
+ bail ! ( IN_INITIALIZED_DIR_ERR ) ;
25
28
}
26
- return Err ( e. into ( ) ) ;
29
+
30
+ stdout. write_all ( CARGO_TOML_EXISTS_PROMPT_MSG ) ?;
31
+ press_enter_prompt ( & mut stdout) ?;
32
+ init_git = false ;
27
33
}
28
34
29
- set_current_dir ( "rustlings" )
35
+ stdout. write_all ( b"This command will create the directory `rustlings/` which will contain the exercises.\n Press ENTER to continue " ) ?;
36
+ press_enter_prompt ( & mut stdout) ?;
37
+
38
+ create_dir ( rustlings_dir) . context ( "Failed to create the `rustlings/` directory" ) ?;
39
+ set_current_dir ( rustlings_dir)
30
40
. context ( "Failed to change the current directory to `rustlings/`" ) ?;
31
41
32
42
let info_file = InfoFile :: parse ( ) ?;
@@ -75,18 +85,21 @@ pub fn init() -> Result<()> {
75
85
fs:: write ( ".vscode/extensions.json" , VS_CODE_EXTENSIONS_JSON )
76
86
. context ( "Failed to create the file `rustlings/.vscode/extensions.json`" ) ?;
77
87
78
- // Ignore any Git error because Git initialization is not required.
79
- let _ = Command :: new ( "git" )
80
- . arg ( "init" )
81
- . stdin ( Stdio :: null ( ) )
82
- . stderr ( Stdio :: null ( ) )
83
- . status ( ) ;
88
+ if init_git {
89
+ // Ignore any Git error because Git initialization is not required.
90
+ let _ = Command :: new ( "git" )
91
+ . arg ( "init" )
92
+ . stdin ( Stdio :: null ( ) )
93
+ . stderr ( Stdio :: null ( ) )
94
+ . status ( ) ;
95
+ }
84
96
85
- println ! (
97
+ writeln ! (
98
+ stdout,
86
99
"\n {}\n \n {}" ,
87
100
"Initialization done ✓" . green( ) ,
88
101
POST_INIT_MSG . bold( ) ,
89
- ) ;
102
+ ) ? ;
90
103
91
104
Ok ( ( ) )
92
105
}
@@ -104,7 +117,7 @@ target/
104
117
105
118
pub const VS_CODE_EXTENSIONS_JSON : & [ u8 ] = br#"{"recommendations":["rust-lang.rust-analyzer"]}"# ;
106
119
107
- const CARGO_TOML_EXISTS_ERR : & str = "The current directory contains the file `Cargo.toml` .
120
+ const IN_INITIALIZED_DIR_ERR : & str = "It looks like Rustlings is already initialized in this directory .
108
121
109
122
If you already initialized Rustlings, run the command `rustlings` for instructions on getting started with the exercises.
110
123
Otherwise, please run `rustlings init` again in another directory." ;
@@ -115,5 +128,19 @@ You probably already initialized Rustlings.
115
128
Run `cd rustlings`
116
129
Then run `rustlings` again" ;
117
130
131
+ const CARGO_TOML_EXISTS_PROMPT_MSG : & [ u8 ] = br#"You are about to initialize Rustlings in a directory that already contains a `Cargo.toml` file!
132
+
133
+ => It is recommended to abort with CTRL+C and initialize Rustlings in another directory <=
134
+
135
+ If you know what you are doing and want to initialize Rustlings in a Cargo workspace,
136
+ then you need to add its directory to `members` in the `workspace` section of the `Cargo.toml` file:
137
+
138
+ ```toml
139
+ [workspace]
140
+ members = ["rustlings"]
141
+ ```
142
+
143
+ Press ENTER if you are sure that you want to continue after reading the warning above "# ;
144
+
118
145
const POST_INIT_MSG : & str = "Run `cd rustlings` to go into the generated directory.
119
146
Then run `rustlings` to get started." ;
0 commit comments