@@ -4,8 +4,8 @@ use brush_parser::{
44 Parser , ParserOptions ,
55 ast:: {
66 AndOr , Assignment , AssignmentName , AssignmentValue , Command , CommandPrefix ,
7- CommandPrefixOrSuffixItem , CommandSuffix , CompoundCommand , CompoundList , CompoundListItem ,
8- DoGroupCommand , Pipeline , Program , SeparatorOperator , SimpleCommand , SourceLocation , Word ,
7+ CommandPrefixOrSuffixItem , CommandSuffix , CompoundListItem , Pipeline , Program ,
8+ SeparatorOperator , SimpleCommand , SourceLocation , Word ,
99 } ,
1010 word:: { WordPiece , WordPieceWithSource } ,
1111} ;
@@ -135,139 +135,6 @@ fn pipeline_to_command(pipeline: &Pipeline) -> Option<(TaskParsedCommand, Range<
135135 Some ( ( TaskParsedCommand { envs, program : unquote ( program) ?, args } , range) )
136136}
137137
138- #[ derive( Clone , Copy , Debug , PartialEq , Eq ) ]
139- enum CwdChangingCommand {
140- Cd ,
141- Chdir ,
142- Dot ,
143- Source ,
144- Eval ,
145- }
146-
147- impl CwdChangingCommand {
148- fn from_name ( command_name : & str ) -> Option < Self > {
149- Some ( match command_name {
150- "cd" => Self :: Cd ,
151- "chdir" => Self :: Chdir ,
152- "." => Self :: Dot ,
153- "source" => Self :: Source ,
154- "eval" => Self :: Eval ,
155- _ => return None ,
156- } )
157- }
158- }
159-
160- fn command_name_may_change_cwd ( command_name : & str ) -> bool {
161- CwdChangingCommand :: from_name ( command_name) . is_some ( )
162- }
163-
164- fn wrapper_command_may_change_cwd ( suffix : Option < & CommandSuffix > ) -> bool {
165- let Some ( CommandSuffix ( suffix_items) ) = suffix else {
166- return false ;
167- } ;
168-
169- for suffix_item in suffix_items {
170- let CommandPrefixOrSuffixItem :: Word ( word) = suffix_item else {
171- continue ;
172- } ;
173- let Some ( arg) = unquote ( word) else {
174- return true ;
175- } ;
176- if arg == "--" || arg. starts_with ( '-' ) {
177- continue ;
178- }
179- return command_name_may_change_cwd ( arg. as_str ( ) ) ;
180- }
181-
182- false
183- }
184-
185- fn simple_command_may_change_cwd ( simple_command : & SimpleCommand ) -> bool {
186- let Some ( program) = & simple_command. word_or_name else {
187- return false ;
188- } ;
189- let Some ( program) = unquote ( program) else {
190- return true ;
191- } ;
192-
193- match program. as_str ( ) {
194- "command" | "builtin" | "time" => {
195- wrapper_command_may_change_cwd ( simple_command. suffix . as_ref ( ) )
196- }
197- command_name => command_name_may_change_cwd ( command_name) ,
198- }
199- }
200-
201- fn and_or_list_may_change_cwd ( and_or_list : & brush_parser:: ast:: AndOrList ) -> bool {
202- pipeline_may_change_cwd ( & and_or_list. first )
203- || and_or_list. additional . iter ( ) . any ( |and_or| {
204- let pipeline = match and_or {
205- AndOr :: And ( pipeline) | AndOr :: Or ( pipeline) => pipeline,
206- } ;
207- pipeline_may_change_cwd ( pipeline)
208- } )
209- }
210-
211- fn compound_list_may_change_cwd ( compound_list : & CompoundList ) -> bool {
212- compound_list
213- . 0
214- . iter ( )
215- . any ( |CompoundListItem ( and_or_list, _) | and_or_list_may_change_cwd ( and_or_list) )
216- }
217-
218- fn do_group_may_change_cwd ( do_group : & DoGroupCommand ) -> bool {
219- compound_list_may_change_cwd ( & do_group. list )
220- }
221-
222- fn compound_command_may_change_cwd ( compound_command : & CompoundCommand ) -> bool {
223- match compound_command {
224- CompoundCommand :: Arithmetic ( _) | CompoundCommand :: Subshell ( _) => false ,
225- CompoundCommand :: ArithmeticForClause ( command) => do_group_may_change_cwd ( & command. body ) ,
226- CompoundCommand :: BraceGroup ( command) => compound_list_may_change_cwd ( & command. list ) ,
227- CompoundCommand :: ForClause ( command) => do_group_may_change_cwd ( & command. body ) ,
228- CompoundCommand :: CaseClause ( command) => command
229- . cases
230- . iter ( )
231- . any ( |case| case. cmd . as_ref ( ) . is_some_and ( compound_list_may_change_cwd) ) ,
232- CompoundCommand :: IfClause ( command) => {
233- compound_list_may_change_cwd ( & command. condition )
234- || compound_list_may_change_cwd ( & command. then )
235- || command. elses . as_ref ( ) . is_some_and ( |elses| {
236- elses. iter ( ) . any ( |else_clause| {
237- else_clause. condition . as_ref ( ) . is_some_and ( compound_list_may_change_cwd)
238- || compound_list_may_change_cwd ( & else_clause. body )
239- } )
240- } )
241- }
242- CompoundCommand :: WhileClause ( command) | CompoundCommand :: UntilClause ( command) => {
243- compound_list_may_change_cwd ( & command. 0 ) || do_group_may_change_cwd ( & command. 1 )
244- }
245- }
246- }
247-
248- fn command_may_change_cwd ( command : & Command ) -> bool {
249- match command {
250- Command :: Simple ( simple_command) => simple_command_may_change_cwd ( simple_command) ,
251- Command :: Compound ( compound_command, _) => compound_command_may_change_cwd ( compound_command) ,
252- Command :: Function ( function) => compound_command_may_change_cwd ( & function. body . 0 ) ,
253- Command :: ExtendedTest ( ..) => false ,
254- }
255- }
256-
257- fn pipeline_may_change_cwd ( pipeline : & Pipeline ) -> bool {
258- pipeline. seq . iter ( ) . any ( command_may_change_cwd)
259- }
260-
261- #[ must_use]
262- pub fn shell_command_may_change_cwd ( cmd : & str ) -> bool {
263- let mut parser = Parser :: new ( cmd. as_bytes ( ) , & PARSER_OPTIONS ) ;
264- let Ok ( Program { complete_commands } ) = parser. parse_program ( ) else {
265- return true ;
266- } ;
267-
268- complete_commands. iter ( ) . any ( compound_list_may_change_cwd)
269- }
270-
271138#[ must_use]
272139pub fn try_parse_as_and_list ( cmd : & str ) -> Option < Vec < ( TaskParsedCommand , Range < usize > ) > > {
273140 let mut parser = Parser :: new ( cmd. as_bytes ( ) , & PARSER_OPTIONS ) ;
@@ -295,29 +162,6 @@ pub fn try_parse_as_and_list(cmd: &str) -> Option<Vec<(TaskParsedCommand, Range<
295162mod tests {
296163 use super :: * ;
297164
298- #[ test]
299- fn test_shell_command_may_change_cwd_with_unresolved_arg ( ) {
300- assert ! ( shell_command_may_change_cwd( r#"cd "$APP_DIR""# ) ) ;
301- assert ! ( shell_command_may_change_cwd( r#"echo ok && cd "$APP_DIR""# ) ) ;
302- assert ! ( shell_command_may_change_cwd( r#"FOO=bar 'cd' "$APP_DIR""# ) ) ;
303- }
304-
305- #[ test]
306- fn test_shell_command_may_change_cwd_in_compound_commands ( ) {
307- assert ! ( shell_command_may_change_cwd( "if true; then cd snapshots; fi" ) ) ;
308- assert ! ( shell_command_may_change_cwd( "{ cd snapshots; }" ) ) ;
309- assert ! ( shell_command_may_change_cwd( "f(){ cd snapshots; }; f" ) ) ;
310- assert ! ( shell_command_may_change_cwd( "command cd snapshots" ) ) ;
311- assert ! ( shell_command_may_change_cwd( "time cd snapshots" ) ) ;
312- }
313-
314- #[ test]
315- fn test_shell_command_may_change_cwd_ignores_non_current_shell_cd ( ) {
316- assert ! ( !shell_command_may_change_cwd( r#"echo "cd $APP_DIR""# ) ) ;
317- assert ! ( !shell_command_may_change_cwd( "cdtool $APP_DIR" ) ) ;
318- assert ! ( !shell_command_may_change_cwd( "(cd snapshots)" ) ) ;
319- }
320-
321165 #[ test]
322166 fn test_parse_single_command ( ) {
323167 let source = r"A=B hello world" ;
0 commit comments