just playing with tangled
at diffedit3 119 lines 4.4 kB view raw
1// Copyright 2022 The Jujutsu Authors 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// https://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15use std::collections::HashSet; 16use std::path::{Path, PathBuf}; 17use std::process::exit; 18 19use clap::Parser; 20use itertools::Itertools; 21 22/// A fake diff-editor, useful for testing 23#[derive(Parser, Debug)] 24#[clap()] 25struct Args { 26 /// Path to the "before" directory 27 before: PathBuf, 28 29 /// Path to the "after" directory 30 after: PathBuf, 31 32 /// Ignored argument 33 #[arg(long)] 34 _ignore: Vec<String>, 35} 36 37fn files_recursively(dir: &Path) -> HashSet<String> { 38 let mut files = HashSet::new(); 39 for dir_entry in std::fs::read_dir(dir).unwrap() { 40 let dir_entry = dir_entry.unwrap(); 41 let base_name = dir_entry.file_name().to_str().unwrap().to_string(); 42 if dir_entry.path().is_dir() { 43 for sub_path in files_recursively(&dir_entry.path()) { 44 files.insert(format!("{base_name}/{sub_path}")); 45 } 46 } else { 47 files.insert(base_name); 48 } 49 } 50 files 51} 52 53fn main() { 54 let args: Args = Args::parse(); 55 let edit_script_path = PathBuf::from(std::env::var_os("DIFF_EDIT_SCRIPT").unwrap()); 56 let edit_script = String::from_utf8(std::fs::read(edit_script_path).unwrap()).unwrap(); 57 for instruction in edit_script.split('\0') { 58 let (command, payload) = instruction.split_once('\n').unwrap_or((instruction, "")); 59 let parts = command.split(' ').collect_vec(); 60 match parts.as_slice() { 61 [""] => {} 62 ["fail"] => exit(1), 63 ["files-before", ..] => { 64 let expected = parts[1..].iter().copied().map(str::to_string).collect(); 65 let actual = files_recursively(&args.before); 66 if actual != expected { 67 eprintln!( 68 "fake-diff-editor: unexpected files before. EXPECTED: {:?} ACTUAL: {:?}", 69 expected.iter().sorted().collect_vec(), 70 actual.iter().sorted().collect_vec(), 71 ); 72 exit(1) 73 } 74 } 75 ["files-after", ..] => { 76 let expected = parts[1..].iter().copied().map(str::to_string).collect(); 77 let actual = files_recursively(&args.after); 78 if actual != expected { 79 eprintln!( 80 "fake-diff-editor: unexpected files after. EXPECTED: {:?} ACTUAL: {:?}", 81 expected.iter().sorted().collect_vec(), 82 actual.iter().sorted().collect_vec(), 83 ); 84 exit(1) 85 } 86 } 87 ["print", message] => { 88 println!("{message}"); 89 } 90 ["print-files-before"] => { 91 for base_name in files_recursively(&args.before).iter().sorted() { 92 println!("{base_name}"); 93 } 94 } 95 ["print-files-after"] => { 96 for base_name in files_recursively(&args.after).iter().sorted() { 97 println!("{base_name}"); 98 } 99 } 100 ["rm", file] => { 101 std::fs::remove_file(args.after.join(file)).unwrap(); 102 } 103 ["reset", file] => { 104 if args.before.join(file).exists() { 105 std::fs::copy(args.before.join(file), args.after.join(file)).unwrap(); 106 } else { 107 std::fs::remove_file(args.after.join(file)).unwrap(); 108 } 109 } 110 ["write", file] => { 111 std::fs::write(args.after.join(file), payload).unwrap(); 112 } 113 _ => { 114 eprintln!("fake-diff-editor: unexpected command: {command}"); 115 exit(1) 116 } 117 } 118 } 119}