| 98 | } |
| 99 | |
| 100 | pub async fn invoke( |
| 101 | &self, |
| 102 | os: &Os, |
| 103 | output: &mut impl Write, |
| 104 | line_tracker: &mut HashMap<String, FileLineTracker>, |
| 105 | ) -> Result<InvokeOutput> { |
| 106 | let cwd = os.env.current_dir()?; |
| 107 | let path = self.path(os); |
| 108 | |
| 109 | self.update_line_tracker_before_invoke(os, line_tracker).await?; |
| 110 | |
| 111 | match self { |
| 112 | FsWrite::Create { .. } => { |
| 113 | let file_text = self.canonical_create_command_text(); |
| 114 | if let Some(parent) = path.parent() { |
| 115 | os.fs.create_dir_all(parent).await?; |
| 116 | } |
| 117 | |
| 118 | let invoke_description = if os.fs.exists(&path) { |
| 119 | "Replacing: " |
| 120 | } else { |
| 121 | "Creating: " |
| 122 | }; |
| 123 | queue!( |
| 124 | output, |
| 125 | style::Print(invoke_description), |
| 126 | StyledText::success_fg(), |
| 127 | style::Print(format_path(cwd, &path)), |
| 128 | StyledText::reset(), |
| 129 | style::Print("\n"), |
| 130 | )?; |
| 131 | |
| 132 | write_to_file(os, &path, file_text).await?; |
| 133 | }, |
| 134 | FsWrite::StrReplace { old_str, new_str, .. } => { |
| 135 | let file = os.fs.read_to_string(&path).await?; |
| 136 | let matches = file.match_indices(old_str).collect::<Vec<_>>(); |
| 137 | queue!( |
| 138 | output, |
| 139 | style::Print("Updating: "), |
| 140 | StyledText::success_fg(), |
| 141 | style::Print(format_path(cwd, &path)), |
| 142 | StyledText::reset(), |
| 143 | style::Print("\n"), |
| 144 | )?; |
| 145 | match matches.len() { |
| 146 | 0 => return Err(eyre!("no occurrences of \"{old_str}\" were found")), |
| 147 | 1 => { |
| 148 | let file = file.replacen(old_str, new_str, 1); |
| 149 | os.fs.write(&path, file).await?; |
| 150 | }, |
| 151 | x => return Err(eyre!("{x} occurrences of old_str were found when only 1 is expected")), |
| 152 | } |
| 153 | }, |
| 154 | FsWrite::Insert { |
| 155 | insert_line, new_str, .. |
| 156 | } => { |
| 157 | let mut file = os.fs.read_to_string(&path).await?; |