just playing with tangled
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::io::Write;
16
17use crate::common::TestEnvironment;
18
19#[test]
20fn test_sparse_manage_patterns() {
21 let mut test_env = TestEnvironment::default();
22 test_env.jj_cmd_ok(test_env.env_root(), &["init", "repo", "--git"]);
23 let repo_path = test_env.env_root().join("repo");
24
25 let edit_script = test_env.set_up_fake_editor();
26
27 // Write some files to the working copy
28 std::fs::write(repo_path.join("file1"), "contents").unwrap();
29 std::fs::write(repo_path.join("file2"), "contents").unwrap();
30 std::fs::write(repo_path.join("file3"), "contents").unwrap();
31
32 // By default, all files are tracked
33 let stdout = test_env.jj_cmd_success(&repo_path, &["sparse", "list"]);
34 insta::assert_snapshot!(stdout, @r###"
35 .
36 "###);
37
38 // Can stop tracking all files
39 let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["sparse", "set", "--remove", "."]);
40 insta::assert_snapshot!(stdout, @"");
41 insta::assert_snapshot!(stderr, @r###"
42 Added 0 files, modified 0 files, removed 3 files
43 "###);
44 // The list is now empty
45 let stdout = test_env.jj_cmd_success(&repo_path, &["sparse", "list"]);
46 insta::assert_snapshot!(stdout, @"");
47 // They're removed from the working copy
48 assert!(!repo_path.join("file1").exists());
49 assert!(!repo_path.join("file2").exists());
50 assert!(!repo_path.join("file3").exists());
51 // But they're still in the commit
52 let stdout = test_env.jj_cmd_success(&repo_path, &["files"]);
53 insta::assert_snapshot!(stdout, @r###"
54 file1
55 file2
56 file3
57 "###);
58
59 // Run commands in sub directory to ensure that patterns are parsed as
60 // workspace-relative paths, not cwd-relative ones.
61 let sub_dir = repo_path.join("sub");
62 std::fs::create_dir(&sub_dir).unwrap();
63
64 // Not a workspace-relative path
65 let stderr = test_env.jj_cmd_cli_error(&sub_dir, &["sparse", "set", "--add=../file2"]);
66 insta::assert_snapshot!(stderr, @r###"
67 error: invalid value '../file2' for '--add <ADD>': Invalid component ".." in repo-relative path "../file2"
68
69 For more information, try '--help'.
70 "###);
71
72 // Can `--add` a few files
73 let (stdout, stderr) = test_env.jj_cmd_ok(
74 &sub_dir,
75 &["sparse", "set", "--add", "file2", "--add", "file3"],
76 );
77 insta::assert_snapshot!(stdout, @"");
78 insta::assert_snapshot!(stderr, @r###"
79 Added 2 files, modified 0 files, removed 0 files
80 "###);
81 let stdout = test_env.jj_cmd_success(&sub_dir, &["sparse", "list"]);
82 insta::assert_snapshot!(stdout, @r###"
83 file2
84 file3
85 "###);
86 assert!(!repo_path.join("file1").exists());
87 assert!(repo_path.join("file2").exists());
88 assert!(repo_path.join("file3").exists());
89
90 // Can combine `--add` and `--remove`
91 let (stdout, stderr) = test_env.jj_cmd_ok(
92 &sub_dir,
93 &[
94 "sparse", "set", "--add", "file1", "--remove", "file2", "--remove", "file3",
95 ],
96 );
97 insta::assert_snapshot!(stdout, @"");
98 insta::assert_snapshot!(stderr, @r###"
99 Added 1 files, modified 0 files, removed 2 files
100 "###);
101 let stdout = test_env.jj_cmd_success(&sub_dir, &["sparse", "list"]);
102 insta::assert_snapshot!(stdout, @r###"
103 file1
104 "###);
105 assert!(repo_path.join("file1").exists());
106 assert!(!repo_path.join("file2").exists());
107 assert!(!repo_path.join("file3").exists());
108
109 // Can use `--clear` and `--add`
110 let (stdout, stderr) =
111 test_env.jj_cmd_ok(&sub_dir, &["sparse", "set", "--clear", "--add", "file2"]);
112 insta::assert_snapshot!(stdout, @"");
113 insta::assert_snapshot!(stderr, @r###"
114 Added 1 files, modified 0 files, removed 1 files
115 "###);
116 let stdout = test_env.jj_cmd_success(&sub_dir, &["sparse", "list"]);
117 insta::assert_snapshot!(stdout, @r###"
118 file2
119 "###);
120 assert!(!repo_path.join("file1").exists());
121 assert!(repo_path.join("file2").exists());
122 assert!(!repo_path.join("file3").exists());
123
124 // Can reset back to all files
125 let (stdout, stderr) = test_env.jj_cmd_ok(&sub_dir, &["sparse", "reset"]);
126 insta::assert_snapshot!(stdout, @"");
127 insta::assert_snapshot!(stderr, @r###"
128 Added 2 files, modified 0 files, removed 0 files
129 "###);
130 let stdout = test_env.jj_cmd_success(&sub_dir, &["sparse", "list"]);
131 insta::assert_snapshot!(stdout, @r###"
132 .
133 "###);
134 assert!(repo_path.join("file1").exists());
135 assert!(repo_path.join("file2").exists());
136 assert!(repo_path.join("file3").exists());
137
138 // Can edit with editor
139 let edit_patterns = |patterns: &[&str]| {
140 let mut file = std::fs::File::create(&edit_script).unwrap();
141 file.write_all(b"dump patterns0\0write\n").unwrap();
142 for pattern in patterns {
143 file.write_all(pattern.as_bytes()).unwrap();
144 file.write_all(b"\n").unwrap();
145 }
146 };
147 let read_patterns = || std::fs::read_to_string(test_env.env_root().join("patterns0")).unwrap();
148
149 edit_patterns(&["file1"]);
150 let (stdout, stderr) = test_env.jj_cmd_ok(&sub_dir, &["sparse", "edit"]);
151 insta::assert_snapshot!(stdout, @"");
152 insta::assert_snapshot!(stderr, @r###"
153 Added 0 files, modified 0 files, removed 2 files
154 "###);
155 insta::assert_snapshot!(read_patterns(), @".");
156 let stdout = test_env.jj_cmd_success(&sub_dir, &["sparse", "list"]);
157 insta::assert_snapshot!(stdout, @r###"
158 file1
159 "###);
160
161 // Can edit with multiple files
162 edit_patterns(&["file3", "file2", "file3"]);
163 let (stdout, stderr) = test_env.jj_cmd_ok(&sub_dir, &["sparse", "edit"]);
164 insta::assert_snapshot!(stdout, @"");
165 insta::assert_snapshot!(stderr, @r###"
166 Added 2 files, modified 0 files, removed 1 files
167 "###);
168 insta::assert_snapshot!(read_patterns(), @r###"
169 file1
170 "###);
171 let stdout = test_env.jj_cmd_success(&sub_dir, &["sparse", "list"]);
172 insta::assert_snapshot!(stdout, @r###"
173 file2
174 file3
175 "###);
176}