##// END OF EJS Templates
rhg: Align with Python on some more error messages...
Simon Sapin -
r47469:12d59eec default
parent child Browse files
Show More
@@ -1,1084 +1,1084 b''
1 # This file is automatically @generated by Cargo.
1 # This file is automatically @generated by Cargo.
2 # It is not intended for manual editing.
2 # It is not intended for manual editing.
3 [[package]]
3 [[package]]
4 name = "adler"
4 name = "adler"
5 version = "0.2.3"
5 version = "0.2.3"
6 source = "registry+https://github.com/rust-lang/crates.io-index"
6 source = "registry+https://github.com/rust-lang/crates.io-index"
7 checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e"
7 checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e"
8
8
9 [[package]]
9 [[package]]
10 name = "aho-corasick"
10 name = "aho-corasick"
11 version = "0.7.15"
11 version = "0.7.15"
12 source = "registry+https://github.com/rust-lang/crates.io-index"
12 source = "registry+https://github.com/rust-lang/crates.io-index"
13 checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
13 checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
14 dependencies = [
14 dependencies = [
15 "memchr",
15 "memchr",
16 ]
16 ]
17
17
18 [[package]]
18 [[package]]
19 name = "ansi_term"
19 name = "ansi_term"
20 version = "0.11.0"
20 version = "0.11.0"
21 source = "registry+https://github.com/rust-lang/crates.io-index"
21 source = "registry+https://github.com/rust-lang/crates.io-index"
22 checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
22 checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
23 dependencies = [
23 dependencies = [
24 "winapi",
24 "winapi",
25 ]
25 ]
26
26
27 [[package]]
27 [[package]]
28 name = "atty"
28 name = "atty"
29 version = "0.2.14"
29 version = "0.2.14"
30 source = "registry+https://github.com/rust-lang/crates.io-index"
30 source = "registry+https://github.com/rust-lang/crates.io-index"
31 checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
31 checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
32 dependencies = [
32 dependencies = [
33 "hermit-abi",
33 "hermit-abi",
34 "libc",
34 "libc",
35 "winapi",
35 "winapi",
36 ]
36 ]
37
37
38 [[package]]
38 [[package]]
39 name = "autocfg"
39 name = "autocfg"
40 version = "1.0.1"
40 version = "1.0.1"
41 source = "registry+https://github.com/rust-lang/crates.io-index"
41 source = "registry+https://github.com/rust-lang/crates.io-index"
42 checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
42 checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
43
43
44 [[package]]
44 [[package]]
45 name = "bitflags"
45 name = "bitflags"
46 version = "1.2.1"
46 version = "1.2.1"
47 source = "registry+https://github.com/rust-lang/crates.io-index"
47 source = "registry+https://github.com/rust-lang/crates.io-index"
48 checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
48 checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
49
49
50 [[package]]
50 [[package]]
51 name = "bitmaps"
51 name = "bitmaps"
52 version = "2.1.0"
52 version = "2.1.0"
53 source = "registry+https://github.com/rust-lang/crates.io-index"
53 source = "registry+https://github.com/rust-lang/crates.io-index"
54 checksum = "031043d04099746d8db04daf1fa424b2bc8bd69d92b25962dcde24da39ab64a2"
54 checksum = "031043d04099746d8db04daf1fa424b2bc8bd69d92b25962dcde24da39ab64a2"
55 dependencies = [
55 dependencies = [
56 "typenum",
56 "typenum",
57 ]
57 ]
58
58
59 [[package]]
59 [[package]]
60 name = "byteorder"
60 name = "byteorder"
61 version = "1.3.4"
61 version = "1.3.4"
62 source = "registry+https://github.com/rust-lang/crates.io-index"
62 source = "registry+https://github.com/rust-lang/crates.io-index"
63 checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
63 checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
64
64
65 [[package]]
65 [[package]]
66 name = "bytes-cast"
66 name = "bytes-cast"
67 version = "0.1.0"
67 version = "0.1.0"
68 source = "registry+https://github.com/rust-lang/crates.io-index"
68 source = "registry+https://github.com/rust-lang/crates.io-index"
69 checksum = "3196ba300c7bc9282a4331e878496cb3e9603a898a8f1446601317163e16ca52"
69 checksum = "3196ba300c7bc9282a4331e878496cb3e9603a898a8f1446601317163e16ca52"
70 dependencies = [
70 dependencies = [
71 "bytes-cast-derive",
71 "bytes-cast-derive",
72 ]
72 ]
73
73
74 [[package]]
74 [[package]]
75 name = "bytes-cast-derive"
75 name = "bytes-cast-derive"
76 version = "0.1.0"
76 version = "0.1.0"
77 source = "registry+https://github.com/rust-lang/crates.io-index"
77 source = "registry+https://github.com/rust-lang/crates.io-index"
78 checksum = "cb936af9de38476664d6b58e529aff30d482e4ce1c5e150293d00730b0d81fdb"
78 checksum = "cb936af9de38476664d6b58e529aff30d482e4ce1c5e150293d00730b0d81fdb"
79 dependencies = [
79 dependencies = [
80 "proc-macro2",
80 "proc-macro2",
81 "quote",
81 "quote",
82 "syn",
82 "syn",
83 ]
83 ]
84
84
85 [[package]]
85 [[package]]
86 name = "cc"
86 name = "cc"
87 version = "1.0.66"
87 version = "1.0.66"
88 source = "registry+https://github.com/rust-lang/crates.io-index"
88 source = "registry+https://github.com/rust-lang/crates.io-index"
89 checksum = "4c0496836a84f8d0495758516b8621a622beb77c0fed418570e50764093ced48"
89 checksum = "4c0496836a84f8d0495758516b8621a622beb77c0fed418570e50764093ced48"
90 dependencies = [
90 dependencies = [
91 "jobserver",
91 "jobserver",
92 ]
92 ]
93
93
94 [[package]]
94 [[package]]
95 name = "cfg-if"
95 name = "cfg-if"
96 version = "0.1.10"
96 version = "0.1.10"
97 source = "registry+https://github.com/rust-lang/crates.io-index"
97 source = "registry+https://github.com/rust-lang/crates.io-index"
98 checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
98 checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
99
99
100 [[package]]
100 [[package]]
101 name = "cfg-if"
101 name = "cfg-if"
102 version = "1.0.0"
102 version = "1.0.0"
103 source = "registry+https://github.com/rust-lang/crates.io-index"
103 source = "registry+https://github.com/rust-lang/crates.io-index"
104 checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
104 checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
105
105
106 [[package]]
106 [[package]]
107 name = "chrono"
107 name = "chrono"
108 version = "0.4.19"
108 version = "0.4.19"
109 source = "registry+https://github.com/rust-lang/crates.io-index"
109 source = "registry+https://github.com/rust-lang/crates.io-index"
110 checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
110 checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
111 dependencies = [
111 dependencies = [
112 "libc",
112 "libc",
113 "num-integer",
113 "num-integer",
114 "num-traits",
114 "num-traits",
115 "time",
115 "time",
116 "winapi",
116 "winapi",
117 ]
117 ]
118
118
119 [[package]]
119 [[package]]
120 name = "clap"
120 name = "clap"
121 version = "2.33.3"
121 version = "2.33.3"
122 source = "registry+https://github.com/rust-lang/crates.io-index"
122 source = "registry+https://github.com/rust-lang/crates.io-index"
123 checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
123 checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
124 dependencies = [
124 dependencies = [
125 "ansi_term",
125 "ansi_term",
126 "atty",
126 "atty",
127 "bitflags",
127 "bitflags",
128 "strsim",
128 "strsim",
129 "textwrap",
129 "textwrap",
130 "unicode-width",
130 "unicode-width",
131 "vec_map",
131 "vec_map",
132 ]
132 ]
133
133
134 [[package]]
134 [[package]]
135 name = "const_fn"
135 name = "const_fn"
136 version = "0.4.4"
136 version = "0.4.4"
137 source = "registry+https://github.com/rust-lang/crates.io-index"
137 source = "registry+https://github.com/rust-lang/crates.io-index"
138 checksum = "cd51eab21ab4fd6a3bf889e2d0958c0a6e3a61ad04260325e919e652a2a62826"
138 checksum = "cd51eab21ab4fd6a3bf889e2d0958c0a6e3a61ad04260325e919e652a2a62826"
139
139
140 [[package]]
140 [[package]]
141 name = "cpython"
141 name = "cpython"
142 version = "0.4.1"
142 version = "0.4.1"
143 source = "registry+https://github.com/rust-lang/crates.io-index"
143 source = "registry+https://github.com/rust-lang/crates.io-index"
144 checksum = "bfaf3847ab963e40c4f6dd8d6be279bdf74007ae2413786a0dcbb28c52139a95"
144 checksum = "bfaf3847ab963e40c4f6dd8d6be279bdf74007ae2413786a0dcbb28c52139a95"
145 dependencies = [
145 dependencies = [
146 "libc",
146 "libc",
147 "num-traits",
147 "num-traits",
148 "python27-sys",
148 "python27-sys",
149 "python3-sys",
149 "python3-sys",
150 ]
150 ]
151
151
152 [[package]]
152 [[package]]
153 name = "crc32fast"
153 name = "crc32fast"
154 version = "1.2.1"
154 version = "1.2.1"
155 source = "registry+https://github.com/rust-lang/crates.io-index"
155 source = "registry+https://github.com/rust-lang/crates.io-index"
156 checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
156 checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
157 dependencies = [
157 dependencies = [
158 "cfg-if 1.0.0",
158 "cfg-if 1.0.0",
159 ]
159 ]
160
160
161 [[package]]
161 [[package]]
162 name = "crossbeam-channel"
162 name = "crossbeam-channel"
163 version = "0.4.4"
163 version = "0.4.4"
164 source = "registry+https://github.com/rust-lang/crates.io-index"
164 source = "registry+https://github.com/rust-lang/crates.io-index"
165 checksum = "b153fe7cbef478c567df0f972e02e6d736db11affe43dfc9c56a9374d1adfb87"
165 checksum = "b153fe7cbef478c567df0f972e02e6d736db11affe43dfc9c56a9374d1adfb87"
166 dependencies = [
166 dependencies = [
167 "crossbeam-utils 0.7.2",
167 "crossbeam-utils 0.7.2",
168 "maybe-uninit",
168 "maybe-uninit",
169 ]
169 ]
170
170
171 [[package]]
171 [[package]]
172 name = "crossbeam-channel"
172 name = "crossbeam-channel"
173 version = "0.5.0"
173 version = "0.5.0"
174 source = "registry+https://github.com/rust-lang/crates.io-index"
174 source = "registry+https://github.com/rust-lang/crates.io-index"
175 checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775"
175 checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775"
176 dependencies = [
176 dependencies = [
177 "cfg-if 1.0.0",
177 "cfg-if 1.0.0",
178 "crossbeam-utils 0.8.1",
178 "crossbeam-utils 0.8.1",
179 ]
179 ]
180
180
181 [[package]]
181 [[package]]
182 name = "crossbeam-deque"
182 name = "crossbeam-deque"
183 version = "0.8.0"
183 version = "0.8.0"
184 source = "registry+https://github.com/rust-lang/crates.io-index"
184 source = "registry+https://github.com/rust-lang/crates.io-index"
185 checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9"
185 checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9"
186 dependencies = [
186 dependencies = [
187 "cfg-if 1.0.0",
187 "cfg-if 1.0.0",
188 "crossbeam-epoch",
188 "crossbeam-epoch",
189 "crossbeam-utils 0.8.1",
189 "crossbeam-utils 0.8.1",
190 ]
190 ]
191
191
192 [[package]]
192 [[package]]
193 name = "crossbeam-epoch"
193 name = "crossbeam-epoch"
194 version = "0.9.1"
194 version = "0.9.1"
195 source = "registry+https://github.com/rust-lang/crates.io-index"
195 source = "registry+https://github.com/rust-lang/crates.io-index"
196 checksum = "a1aaa739f95311c2c7887a76863f500026092fb1dce0161dab577e559ef3569d"
196 checksum = "a1aaa739f95311c2c7887a76863f500026092fb1dce0161dab577e559ef3569d"
197 dependencies = [
197 dependencies = [
198 "cfg-if 1.0.0",
198 "cfg-if 1.0.0",
199 "const_fn",
199 "const_fn",
200 "crossbeam-utils 0.8.1",
200 "crossbeam-utils 0.8.1",
201 "lazy_static",
201 "lazy_static",
202 "memoffset",
202 "memoffset",
203 "scopeguard",
203 "scopeguard",
204 ]
204 ]
205
205
206 [[package]]
206 [[package]]
207 name = "crossbeam-utils"
207 name = "crossbeam-utils"
208 version = "0.7.2"
208 version = "0.7.2"
209 source = "registry+https://github.com/rust-lang/crates.io-index"
209 source = "registry+https://github.com/rust-lang/crates.io-index"
210 checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
210 checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
211 dependencies = [
211 dependencies = [
212 "autocfg",
212 "autocfg",
213 "cfg-if 0.1.10",
213 "cfg-if 0.1.10",
214 "lazy_static",
214 "lazy_static",
215 ]
215 ]
216
216
217 [[package]]
217 [[package]]
218 name = "crossbeam-utils"
218 name = "crossbeam-utils"
219 version = "0.8.1"
219 version = "0.8.1"
220 source = "registry+https://github.com/rust-lang/crates.io-index"
220 source = "registry+https://github.com/rust-lang/crates.io-index"
221 checksum = "02d96d1e189ef58269ebe5b97953da3274d83a93af647c2ddd6f9dab28cedb8d"
221 checksum = "02d96d1e189ef58269ebe5b97953da3274d83a93af647c2ddd6f9dab28cedb8d"
222 dependencies = [
222 dependencies = [
223 "autocfg",
223 "autocfg",
224 "cfg-if 1.0.0",
224 "cfg-if 1.0.0",
225 "lazy_static",
225 "lazy_static",
226 ]
226 ]
227
227
228 [[package]]
228 [[package]]
229 name = "ctor"
229 name = "ctor"
230 version = "0.1.16"
230 version = "0.1.16"
231 source = "registry+https://github.com/rust-lang/crates.io-index"
231 source = "registry+https://github.com/rust-lang/crates.io-index"
232 checksum = "7fbaabec2c953050352311293be5c6aba8e141ba19d6811862b232d6fd020484"
232 checksum = "7fbaabec2c953050352311293be5c6aba8e141ba19d6811862b232d6fd020484"
233 dependencies = [
233 dependencies = [
234 "quote",
234 "quote",
235 "syn",
235 "syn",
236 ]
236 ]
237
237
238 [[package]]
238 [[package]]
239 name = "derive_more"
239 name = "derive_more"
240 version = "0.99.11"
240 version = "0.99.11"
241 source = "registry+https://github.com/rust-lang/crates.io-index"
241 source = "registry+https://github.com/rust-lang/crates.io-index"
242 checksum = "41cb0e6161ad61ed084a36ba71fbba9e3ac5aee3606fb607fe08da6acbcf3d8c"
242 checksum = "41cb0e6161ad61ed084a36ba71fbba9e3ac5aee3606fb607fe08da6acbcf3d8c"
243 dependencies = [
243 dependencies = [
244 "proc-macro2",
244 "proc-macro2",
245 "quote",
245 "quote",
246 "syn",
246 "syn",
247 ]
247 ]
248
248
249 [[package]]
249 [[package]]
250 name = "difference"
250 name = "difference"
251 version = "2.0.0"
251 version = "2.0.0"
252 source = "registry+https://github.com/rust-lang/crates.io-index"
252 source = "registry+https://github.com/rust-lang/crates.io-index"
253 checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
253 checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
254
254
255 [[package]]
255 [[package]]
256 name = "either"
256 name = "either"
257 version = "1.6.1"
257 version = "1.6.1"
258 source = "registry+https://github.com/rust-lang/crates.io-index"
258 source = "registry+https://github.com/rust-lang/crates.io-index"
259 checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
259 checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
260
260
261 [[package]]
261 [[package]]
262 name = "env_logger"
262 name = "env_logger"
263 version = "0.7.1"
263 version = "0.7.1"
264 source = "registry+https://github.com/rust-lang/crates.io-index"
264 source = "registry+https://github.com/rust-lang/crates.io-index"
265 checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
265 checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
266 dependencies = [
266 dependencies = [
267 "atty",
267 "atty",
268 "humantime",
268 "humantime",
269 "log",
269 "log",
270 "regex",
270 "regex",
271 "termcolor",
271 "termcolor",
272 ]
272 ]
273
273
274 [[package]]
274 [[package]]
275 name = "flate2"
275 name = "flate2"
276 version = "1.0.19"
276 version = "1.0.19"
277 source = "registry+https://github.com/rust-lang/crates.io-index"
277 source = "registry+https://github.com/rust-lang/crates.io-index"
278 checksum = "7411863d55df97a419aa64cb4d2f167103ea9d767e2c54a1868b7ac3f6b47129"
278 checksum = "7411863d55df97a419aa64cb4d2f167103ea9d767e2c54a1868b7ac3f6b47129"
279 dependencies = [
279 dependencies = [
280 "cfg-if 1.0.0",
280 "cfg-if 1.0.0",
281 "crc32fast",
281 "crc32fast",
282 "libc",
282 "libc",
283 "libz-sys",
283 "libz-sys",
284 "miniz_oxide",
284 "miniz_oxide",
285 ]
285 ]
286
286
287 [[package]]
287 [[package]]
288 name = "format-bytes"
288 name = "format-bytes"
289 version = "0.2.1"
289 version = "0.2.2"
290 source = "registry+https://github.com/rust-lang/crates.io-index"
290 source = "registry+https://github.com/rust-lang/crates.io-index"
291 checksum = "8030ff4b04f0ca1c612d6fe49f2fc18caf56fb01497cb370b41cfd36d89b3b06"
291 checksum = "1c4e89040c7fd7b4e6ba2820ac705a45def8a0c098ec78d170ae88f1ef1d5762"
292 dependencies = [
292 dependencies = [
293 "format-bytes-macros",
293 "format-bytes-macros",
294 "proc-macro-hack",
294 "proc-macro-hack",
295 ]
295 ]
296
296
297 [[package]]
297 [[package]]
298 name = "format-bytes-macros"
298 name = "format-bytes-macros"
299 version = "0.3.0"
299 version = "0.3.0"
300 source = "registry+https://github.com/rust-lang/crates.io-index"
300 source = "registry+https://github.com/rust-lang/crates.io-index"
301 checksum = "b05089e341a0460449e2210c3bf7b61597860b07f0deae58da38dbed0a4c6b6d"
301 checksum = "b05089e341a0460449e2210c3bf7b61597860b07f0deae58da38dbed0a4c6b6d"
302 dependencies = [
302 dependencies = [
303 "proc-macro-hack",
303 "proc-macro-hack",
304 "proc-macro2",
304 "proc-macro2",
305 "quote",
305 "quote",
306 "syn",
306 "syn",
307 ]
307 ]
308
308
309 [[package]]
309 [[package]]
310 name = "fuchsia-cprng"
310 name = "fuchsia-cprng"
311 version = "0.1.1"
311 version = "0.1.1"
312 source = "registry+https://github.com/rust-lang/crates.io-index"
312 source = "registry+https://github.com/rust-lang/crates.io-index"
313 checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
313 checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
314
314
315 [[package]]
315 [[package]]
316 name = "gcc"
316 name = "gcc"
317 version = "0.3.55"
317 version = "0.3.55"
318 source = "registry+https://github.com/rust-lang/crates.io-index"
318 source = "registry+https://github.com/rust-lang/crates.io-index"
319 checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2"
319 checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2"
320
320
321 [[package]]
321 [[package]]
322 name = "getrandom"
322 name = "getrandom"
323 version = "0.1.15"
323 version = "0.1.15"
324 source = "registry+https://github.com/rust-lang/crates.io-index"
324 source = "registry+https://github.com/rust-lang/crates.io-index"
325 checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6"
325 checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6"
326 dependencies = [
326 dependencies = [
327 "cfg-if 0.1.10",
327 "cfg-if 0.1.10",
328 "libc",
328 "libc",
329 "wasi 0.9.0+wasi-snapshot-preview1",
329 "wasi 0.9.0+wasi-snapshot-preview1",
330 ]
330 ]
331
331
332 [[package]]
332 [[package]]
333 name = "glob"
333 name = "glob"
334 version = "0.3.0"
334 version = "0.3.0"
335 source = "registry+https://github.com/rust-lang/crates.io-index"
335 source = "registry+https://github.com/rust-lang/crates.io-index"
336 checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
336 checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
337
337
338 [[package]]
338 [[package]]
339 name = "hermit-abi"
339 name = "hermit-abi"
340 version = "0.1.17"
340 version = "0.1.17"
341 source = "registry+https://github.com/rust-lang/crates.io-index"
341 source = "registry+https://github.com/rust-lang/crates.io-index"
342 checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8"
342 checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8"
343 dependencies = [
343 dependencies = [
344 "libc",
344 "libc",
345 ]
345 ]
346
346
347 [[package]]
347 [[package]]
348 name = "hg-core"
348 name = "hg-core"
349 version = "0.1.0"
349 version = "0.1.0"
350 dependencies = [
350 dependencies = [
351 "byteorder",
351 "byteorder",
352 "bytes-cast",
352 "bytes-cast",
353 "clap",
353 "clap",
354 "crossbeam-channel 0.4.4",
354 "crossbeam-channel 0.4.4",
355 "derive_more",
355 "derive_more",
356 "flate2",
356 "flate2",
357 "format-bytes",
357 "format-bytes",
358 "home",
358 "home",
359 "im-rc",
359 "im-rc",
360 "lazy_static",
360 "lazy_static",
361 "log",
361 "log",
362 "memmap",
362 "memmap",
363 "micro-timer",
363 "micro-timer",
364 "pretty_assertions",
364 "pretty_assertions",
365 "rand 0.7.3",
365 "rand 0.7.3",
366 "rand_distr",
366 "rand_distr",
367 "rand_pcg",
367 "rand_pcg",
368 "rayon",
368 "rayon",
369 "regex",
369 "regex",
370 "rust-crypto",
370 "rust-crypto",
371 "same-file",
371 "same-file",
372 "tempfile",
372 "tempfile",
373 "twox-hash",
373 "twox-hash",
374 "zstd",
374 "zstd",
375 ]
375 ]
376
376
377 [[package]]
377 [[package]]
378 name = "hg-cpython"
378 name = "hg-cpython"
379 version = "0.1.0"
379 version = "0.1.0"
380 dependencies = [
380 dependencies = [
381 "cpython",
381 "cpython",
382 "crossbeam-channel 0.4.4",
382 "crossbeam-channel 0.4.4",
383 "env_logger",
383 "env_logger",
384 "hg-core",
384 "hg-core",
385 "libc",
385 "libc",
386 "log",
386 "log",
387 ]
387 ]
388
388
389 [[package]]
389 [[package]]
390 name = "home"
390 name = "home"
391 version = "0.5.3"
391 version = "0.5.3"
392 source = "registry+https://github.com/rust-lang/crates.io-index"
392 source = "registry+https://github.com/rust-lang/crates.io-index"
393 checksum = "2456aef2e6b6a9784192ae780c0f15bc57df0e918585282325e8c8ac27737654"
393 checksum = "2456aef2e6b6a9784192ae780c0f15bc57df0e918585282325e8c8ac27737654"
394 dependencies = [
394 dependencies = [
395 "winapi",
395 "winapi",
396 ]
396 ]
397
397
398 [[package]]
398 [[package]]
399 name = "humantime"
399 name = "humantime"
400 version = "1.3.0"
400 version = "1.3.0"
401 source = "registry+https://github.com/rust-lang/crates.io-index"
401 source = "registry+https://github.com/rust-lang/crates.io-index"
402 checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
402 checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
403 dependencies = [
403 dependencies = [
404 "quick-error",
404 "quick-error",
405 ]
405 ]
406
406
407 [[package]]
407 [[package]]
408 name = "im-rc"
408 name = "im-rc"
409 version = "15.0.0"
409 version = "15.0.0"
410 source = "registry+https://github.com/rust-lang/crates.io-index"
410 source = "registry+https://github.com/rust-lang/crates.io-index"
411 checksum = "3ca8957e71f04a205cb162508f9326aea04676c8dfd0711220190d6b83664f3f"
411 checksum = "3ca8957e71f04a205cb162508f9326aea04676c8dfd0711220190d6b83664f3f"
412 dependencies = [
412 dependencies = [
413 "bitmaps",
413 "bitmaps",
414 "rand_core 0.5.1",
414 "rand_core 0.5.1",
415 "rand_xoshiro",
415 "rand_xoshiro",
416 "sized-chunks",
416 "sized-chunks",
417 "typenum",
417 "typenum",
418 "version_check",
418 "version_check",
419 ]
419 ]
420
420
421 [[package]]
421 [[package]]
422 name = "itertools"
422 name = "itertools"
423 version = "0.9.0"
423 version = "0.9.0"
424 source = "registry+https://github.com/rust-lang/crates.io-index"
424 source = "registry+https://github.com/rust-lang/crates.io-index"
425 checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"
425 checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"
426 dependencies = [
426 dependencies = [
427 "either",
427 "either",
428 ]
428 ]
429
429
430 [[package]]
430 [[package]]
431 name = "jobserver"
431 name = "jobserver"
432 version = "0.1.21"
432 version = "0.1.21"
433 source = "registry+https://github.com/rust-lang/crates.io-index"
433 source = "registry+https://github.com/rust-lang/crates.io-index"
434 checksum = "5c71313ebb9439f74b00d9d2dcec36440beaf57a6aa0623068441dd7cd81a7f2"
434 checksum = "5c71313ebb9439f74b00d9d2dcec36440beaf57a6aa0623068441dd7cd81a7f2"
435 dependencies = [
435 dependencies = [
436 "libc",
436 "libc",
437 ]
437 ]
438
438
439 [[package]]
439 [[package]]
440 name = "lazy_static"
440 name = "lazy_static"
441 version = "1.4.0"
441 version = "1.4.0"
442 source = "registry+https://github.com/rust-lang/crates.io-index"
442 source = "registry+https://github.com/rust-lang/crates.io-index"
443 checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
443 checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
444
444
445 [[package]]
445 [[package]]
446 name = "libc"
446 name = "libc"
447 version = "0.2.81"
447 version = "0.2.81"
448 source = "registry+https://github.com/rust-lang/crates.io-index"
448 source = "registry+https://github.com/rust-lang/crates.io-index"
449 checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb"
449 checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb"
450
450
451 [[package]]
451 [[package]]
452 name = "libz-sys"
452 name = "libz-sys"
453 version = "1.1.2"
453 version = "1.1.2"
454 source = "registry+https://github.com/rust-lang/crates.io-index"
454 source = "registry+https://github.com/rust-lang/crates.io-index"
455 checksum = "602113192b08db8f38796c4e85c39e960c145965140e918018bcde1952429655"
455 checksum = "602113192b08db8f38796c4e85c39e960c145965140e918018bcde1952429655"
456 dependencies = [
456 dependencies = [
457 "cc",
457 "cc",
458 "pkg-config",
458 "pkg-config",
459 "vcpkg",
459 "vcpkg",
460 ]
460 ]
461
461
462 [[package]]
462 [[package]]
463 name = "log"
463 name = "log"
464 version = "0.4.11"
464 version = "0.4.11"
465 source = "registry+https://github.com/rust-lang/crates.io-index"
465 source = "registry+https://github.com/rust-lang/crates.io-index"
466 checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
466 checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
467 dependencies = [
467 dependencies = [
468 "cfg-if 0.1.10",
468 "cfg-if 0.1.10",
469 ]
469 ]
470
470
471 [[package]]
471 [[package]]
472 name = "maybe-uninit"
472 name = "maybe-uninit"
473 version = "2.0.0"
473 version = "2.0.0"
474 source = "registry+https://github.com/rust-lang/crates.io-index"
474 source = "registry+https://github.com/rust-lang/crates.io-index"
475 checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
475 checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
476
476
477 [[package]]
477 [[package]]
478 name = "memchr"
478 name = "memchr"
479 version = "2.3.4"
479 version = "2.3.4"
480 source = "registry+https://github.com/rust-lang/crates.io-index"
480 source = "registry+https://github.com/rust-lang/crates.io-index"
481 checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
481 checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
482
482
483 [[package]]
483 [[package]]
484 name = "memmap"
484 name = "memmap"
485 version = "0.7.0"
485 version = "0.7.0"
486 source = "registry+https://github.com/rust-lang/crates.io-index"
486 source = "registry+https://github.com/rust-lang/crates.io-index"
487 checksum = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b"
487 checksum = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b"
488 dependencies = [
488 dependencies = [
489 "libc",
489 "libc",
490 "winapi",
490 "winapi",
491 ]
491 ]
492
492
493 [[package]]
493 [[package]]
494 name = "memoffset"
494 name = "memoffset"
495 version = "0.6.1"
495 version = "0.6.1"
496 source = "registry+https://github.com/rust-lang/crates.io-index"
496 source = "registry+https://github.com/rust-lang/crates.io-index"
497 checksum = "157b4208e3059a8f9e78d559edc658e13df41410cb3ae03979c83130067fdd87"
497 checksum = "157b4208e3059a8f9e78d559edc658e13df41410cb3ae03979c83130067fdd87"
498 dependencies = [
498 dependencies = [
499 "autocfg",
499 "autocfg",
500 ]
500 ]
501
501
502 [[package]]
502 [[package]]
503 name = "micro-timer"
503 name = "micro-timer"
504 version = "0.3.1"
504 version = "0.3.1"
505 source = "registry+https://github.com/rust-lang/crates.io-index"
505 source = "registry+https://github.com/rust-lang/crates.io-index"
506 checksum = "2620153e1d903d26b72b89f0e9c48d8c4756cba941c185461dddc234980c298c"
506 checksum = "2620153e1d903d26b72b89f0e9c48d8c4756cba941c185461dddc234980c298c"
507 dependencies = [
507 dependencies = [
508 "micro-timer-macros",
508 "micro-timer-macros",
509 "scopeguard",
509 "scopeguard",
510 ]
510 ]
511
511
512 [[package]]
512 [[package]]
513 name = "micro-timer-macros"
513 name = "micro-timer-macros"
514 version = "0.3.1"
514 version = "0.3.1"
515 source = "registry+https://github.com/rust-lang/crates.io-index"
515 source = "registry+https://github.com/rust-lang/crates.io-index"
516 checksum = "e28a3473e6abd6e9aab36aaeef32ad22ae0bd34e79f376643594c2b152ec1c5d"
516 checksum = "e28a3473e6abd6e9aab36aaeef32ad22ae0bd34e79f376643594c2b152ec1c5d"
517 dependencies = [
517 dependencies = [
518 "proc-macro2",
518 "proc-macro2",
519 "quote",
519 "quote",
520 "scopeguard",
520 "scopeguard",
521 "syn",
521 "syn",
522 ]
522 ]
523
523
524 [[package]]
524 [[package]]
525 name = "miniz_oxide"
525 name = "miniz_oxide"
526 version = "0.4.3"
526 version = "0.4.3"
527 source = "registry+https://github.com/rust-lang/crates.io-index"
527 source = "registry+https://github.com/rust-lang/crates.io-index"
528 checksum = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d"
528 checksum = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d"
529 dependencies = [
529 dependencies = [
530 "adler",
530 "adler",
531 "autocfg",
531 "autocfg",
532 ]
532 ]
533
533
534 [[package]]
534 [[package]]
535 name = "num-integer"
535 name = "num-integer"
536 version = "0.1.44"
536 version = "0.1.44"
537 source = "registry+https://github.com/rust-lang/crates.io-index"
537 source = "registry+https://github.com/rust-lang/crates.io-index"
538 checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
538 checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
539 dependencies = [
539 dependencies = [
540 "autocfg",
540 "autocfg",
541 "num-traits",
541 "num-traits",
542 ]
542 ]
543
543
544 [[package]]
544 [[package]]
545 name = "num-traits"
545 name = "num-traits"
546 version = "0.2.14"
546 version = "0.2.14"
547 source = "registry+https://github.com/rust-lang/crates.io-index"
547 source = "registry+https://github.com/rust-lang/crates.io-index"
548 checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
548 checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
549 dependencies = [
549 dependencies = [
550 "autocfg",
550 "autocfg",
551 ]
551 ]
552
552
553 [[package]]
553 [[package]]
554 name = "num_cpus"
554 name = "num_cpus"
555 version = "1.13.0"
555 version = "1.13.0"
556 source = "registry+https://github.com/rust-lang/crates.io-index"
556 source = "registry+https://github.com/rust-lang/crates.io-index"
557 checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
557 checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
558 dependencies = [
558 dependencies = [
559 "hermit-abi",
559 "hermit-abi",
560 "libc",
560 "libc",
561 ]
561 ]
562
562
563 [[package]]
563 [[package]]
564 name = "output_vt100"
564 name = "output_vt100"
565 version = "0.1.2"
565 version = "0.1.2"
566 source = "registry+https://github.com/rust-lang/crates.io-index"
566 source = "registry+https://github.com/rust-lang/crates.io-index"
567 checksum = "53cdc5b785b7a58c5aad8216b3dfa114df64b0b06ae6e1501cef91df2fbdf8f9"
567 checksum = "53cdc5b785b7a58c5aad8216b3dfa114df64b0b06ae6e1501cef91df2fbdf8f9"
568 dependencies = [
568 dependencies = [
569 "winapi",
569 "winapi",
570 ]
570 ]
571
571
572 [[package]]
572 [[package]]
573 name = "pkg-config"
573 name = "pkg-config"
574 version = "0.3.19"
574 version = "0.3.19"
575 source = "registry+https://github.com/rust-lang/crates.io-index"
575 source = "registry+https://github.com/rust-lang/crates.io-index"
576 checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c"
576 checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c"
577
577
578 [[package]]
578 [[package]]
579 name = "ppv-lite86"
579 name = "ppv-lite86"
580 version = "0.2.10"
580 version = "0.2.10"
581 source = "registry+https://github.com/rust-lang/crates.io-index"
581 source = "registry+https://github.com/rust-lang/crates.io-index"
582 checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
582 checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
583
583
584 [[package]]
584 [[package]]
585 name = "pretty_assertions"
585 name = "pretty_assertions"
586 version = "0.6.1"
586 version = "0.6.1"
587 source = "registry+https://github.com/rust-lang/crates.io-index"
587 source = "registry+https://github.com/rust-lang/crates.io-index"
588 checksum = "3f81e1644e1b54f5a68959a29aa86cde704219254669da328ecfdf6a1f09d427"
588 checksum = "3f81e1644e1b54f5a68959a29aa86cde704219254669da328ecfdf6a1f09d427"
589 dependencies = [
589 dependencies = [
590 "ansi_term",
590 "ansi_term",
591 "ctor",
591 "ctor",
592 "difference",
592 "difference",
593 "output_vt100",
593 "output_vt100",
594 ]
594 ]
595
595
596 [[package]]
596 [[package]]
597 name = "proc-macro-hack"
597 name = "proc-macro-hack"
598 version = "0.5.19"
598 version = "0.5.19"
599 source = "registry+https://github.com/rust-lang/crates.io-index"
599 source = "registry+https://github.com/rust-lang/crates.io-index"
600 checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
600 checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
601
601
602 [[package]]
602 [[package]]
603 name = "proc-macro2"
603 name = "proc-macro2"
604 version = "1.0.24"
604 version = "1.0.24"
605 source = "registry+https://github.com/rust-lang/crates.io-index"
605 source = "registry+https://github.com/rust-lang/crates.io-index"
606 checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
606 checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
607 dependencies = [
607 dependencies = [
608 "unicode-xid",
608 "unicode-xid",
609 ]
609 ]
610
610
611 [[package]]
611 [[package]]
612 name = "python27-sys"
612 name = "python27-sys"
613 version = "0.4.1"
613 version = "0.4.1"
614 source = "registry+https://github.com/rust-lang/crates.io-index"
614 source = "registry+https://github.com/rust-lang/crates.io-index"
615 checksum = "67cb041de8615111bf224dd75667af5f25c6e032118251426fed7f1b70ce4c8c"
615 checksum = "67cb041de8615111bf224dd75667af5f25c6e032118251426fed7f1b70ce4c8c"
616 dependencies = [
616 dependencies = [
617 "libc",
617 "libc",
618 "regex",
618 "regex",
619 ]
619 ]
620
620
621 [[package]]
621 [[package]]
622 name = "python3-sys"
622 name = "python3-sys"
623 version = "0.4.1"
623 version = "0.4.1"
624 source = "registry+https://github.com/rust-lang/crates.io-index"
624 source = "registry+https://github.com/rust-lang/crates.io-index"
625 checksum = "90af11779515a1e530af60782d273b59ac79d33b0e253c071a728563957c76d4"
625 checksum = "90af11779515a1e530af60782d273b59ac79d33b0e253c071a728563957c76d4"
626 dependencies = [
626 dependencies = [
627 "libc",
627 "libc",
628 "regex",
628 "regex",
629 ]
629 ]
630
630
631 [[package]]
631 [[package]]
632 name = "quick-error"
632 name = "quick-error"
633 version = "1.2.3"
633 version = "1.2.3"
634 source = "registry+https://github.com/rust-lang/crates.io-index"
634 source = "registry+https://github.com/rust-lang/crates.io-index"
635 checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
635 checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
636
636
637 [[package]]
637 [[package]]
638 name = "quote"
638 name = "quote"
639 version = "1.0.7"
639 version = "1.0.7"
640 source = "registry+https://github.com/rust-lang/crates.io-index"
640 source = "registry+https://github.com/rust-lang/crates.io-index"
641 checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
641 checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
642 dependencies = [
642 dependencies = [
643 "proc-macro2",
643 "proc-macro2",
644 ]
644 ]
645
645
646 [[package]]
646 [[package]]
647 name = "rand"
647 name = "rand"
648 version = "0.3.23"
648 version = "0.3.23"
649 source = "registry+https://github.com/rust-lang/crates.io-index"
649 source = "registry+https://github.com/rust-lang/crates.io-index"
650 checksum = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c"
650 checksum = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c"
651 dependencies = [
651 dependencies = [
652 "libc",
652 "libc",
653 "rand 0.4.6",
653 "rand 0.4.6",
654 ]
654 ]
655
655
656 [[package]]
656 [[package]]
657 name = "rand"
657 name = "rand"
658 version = "0.4.6"
658 version = "0.4.6"
659 source = "registry+https://github.com/rust-lang/crates.io-index"
659 source = "registry+https://github.com/rust-lang/crates.io-index"
660 checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293"
660 checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293"
661 dependencies = [
661 dependencies = [
662 "fuchsia-cprng",
662 "fuchsia-cprng",
663 "libc",
663 "libc",
664 "rand_core 0.3.1",
664 "rand_core 0.3.1",
665 "rdrand",
665 "rdrand",
666 "winapi",
666 "winapi",
667 ]
667 ]
668
668
669 [[package]]
669 [[package]]
670 name = "rand"
670 name = "rand"
671 version = "0.7.3"
671 version = "0.7.3"
672 source = "registry+https://github.com/rust-lang/crates.io-index"
672 source = "registry+https://github.com/rust-lang/crates.io-index"
673 checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
673 checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
674 dependencies = [
674 dependencies = [
675 "getrandom",
675 "getrandom",
676 "libc",
676 "libc",
677 "rand_chacha",
677 "rand_chacha",
678 "rand_core 0.5.1",
678 "rand_core 0.5.1",
679 "rand_hc",
679 "rand_hc",
680 ]
680 ]
681
681
682 [[package]]
682 [[package]]
683 name = "rand_chacha"
683 name = "rand_chacha"
684 version = "0.2.2"
684 version = "0.2.2"
685 source = "registry+https://github.com/rust-lang/crates.io-index"
685 source = "registry+https://github.com/rust-lang/crates.io-index"
686 checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
686 checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
687 dependencies = [
687 dependencies = [
688 "ppv-lite86",
688 "ppv-lite86",
689 "rand_core 0.5.1",
689 "rand_core 0.5.1",
690 ]
690 ]
691
691
692 [[package]]
692 [[package]]
693 name = "rand_core"
693 name = "rand_core"
694 version = "0.3.1"
694 version = "0.3.1"
695 source = "registry+https://github.com/rust-lang/crates.io-index"
695 source = "registry+https://github.com/rust-lang/crates.io-index"
696 checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
696 checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
697 dependencies = [
697 dependencies = [
698 "rand_core 0.4.2",
698 "rand_core 0.4.2",
699 ]
699 ]
700
700
701 [[package]]
701 [[package]]
702 name = "rand_core"
702 name = "rand_core"
703 version = "0.4.2"
703 version = "0.4.2"
704 source = "registry+https://github.com/rust-lang/crates.io-index"
704 source = "registry+https://github.com/rust-lang/crates.io-index"
705 checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
705 checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
706
706
707 [[package]]
707 [[package]]
708 name = "rand_core"
708 name = "rand_core"
709 version = "0.5.1"
709 version = "0.5.1"
710 source = "registry+https://github.com/rust-lang/crates.io-index"
710 source = "registry+https://github.com/rust-lang/crates.io-index"
711 checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
711 checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
712 dependencies = [
712 dependencies = [
713 "getrandom",
713 "getrandom",
714 ]
714 ]
715
715
716 [[package]]
716 [[package]]
717 name = "rand_distr"
717 name = "rand_distr"
718 version = "0.2.2"
718 version = "0.2.2"
719 source = "registry+https://github.com/rust-lang/crates.io-index"
719 source = "registry+https://github.com/rust-lang/crates.io-index"
720 checksum = "96977acbdd3a6576fb1d27391900035bf3863d4a16422973a409b488cf29ffb2"
720 checksum = "96977acbdd3a6576fb1d27391900035bf3863d4a16422973a409b488cf29ffb2"
721 dependencies = [
721 dependencies = [
722 "rand 0.7.3",
722 "rand 0.7.3",
723 ]
723 ]
724
724
725 [[package]]
725 [[package]]
726 name = "rand_hc"
726 name = "rand_hc"
727 version = "0.2.0"
727 version = "0.2.0"
728 source = "registry+https://github.com/rust-lang/crates.io-index"
728 source = "registry+https://github.com/rust-lang/crates.io-index"
729 checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
729 checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
730 dependencies = [
730 dependencies = [
731 "rand_core 0.5.1",
731 "rand_core 0.5.1",
732 ]
732 ]
733
733
734 [[package]]
734 [[package]]
735 name = "rand_pcg"
735 name = "rand_pcg"
736 version = "0.2.1"
736 version = "0.2.1"
737 source = "registry+https://github.com/rust-lang/crates.io-index"
737 source = "registry+https://github.com/rust-lang/crates.io-index"
738 checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429"
738 checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429"
739 dependencies = [
739 dependencies = [
740 "rand_core 0.5.1",
740 "rand_core 0.5.1",
741 ]
741 ]
742
742
743 [[package]]
743 [[package]]
744 name = "rand_xoshiro"
744 name = "rand_xoshiro"
745 version = "0.4.0"
745 version = "0.4.0"
746 source = "registry+https://github.com/rust-lang/crates.io-index"
746 source = "registry+https://github.com/rust-lang/crates.io-index"
747 checksum = "a9fcdd2e881d02f1d9390ae47ad8e5696a9e4be7b547a1da2afbc61973217004"
747 checksum = "a9fcdd2e881d02f1d9390ae47ad8e5696a9e4be7b547a1da2afbc61973217004"
748 dependencies = [
748 dependencies = [
749 "rand_core 0.5.1",
749 "rand_core 0.5.1",
750 ]
750 ]
751
751
752 [[package]]
752 [[package]]
753 name = "rayon"
753 name = "rayon"
754 version = "1.5.0"
754 version = "1.5.0"
755 source = "registry+https://github.com/rust-lang/crates.io-index"
755 source = "registry+https://github.com/rust-lang/crates.io-index"
756 checksum = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674"
756 checksum = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674"
757 dependencies = [
757 dependencies = [
758 "autocfg",
758 "autocfg",
759 "crossbeam-deque",
759 "crossbeam-deque",
760 "either",
760 "either",
761 "rayon-core",
761 "rayon-core",
762 ]
762 ]
763
763
764 [[package]]
764 [[package]]
765 name = "rayon-core"
765 name = "rayon-core"
766 version = "1.9.0"
766 version = "1.9.0"
767 source = "registry+https://github.com/rust-lang/crates.io-index"
767 source = "registry+https://github.com/rust-lang/crates.io-index"
768 checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a"
768 checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a"
769 dependencies = [
769 dependencies = [
770 "crossbeam-channel 0.5.0",
770 "crossbeam-channel 0.5.0",
771 "crossbeam-deque",
771 "crossbeam-deque",
772 "crossbeam-utils 0.8.1",
772 "crossbeam-utils 0.8.1",
773 "lazy_static",
773 "lazy_static",
774 "num_cpus",
774 "num_cpus",
775 ]
775 ]
776
776
777 [[package]]
777 [[package]]
778 name = "rdrand"
778 name = "rdrand"
779 version = "0.4.0"
779 version = "0.4.0"
780 source = "registry+https://github.com/rust-lang/crates.io-index"
780 source = "registry+https://github.com/rust-lang/crates.io-index"
781 checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
781 checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
782 dependencies = [
782 dependencies = [
783 "rand_core 0.3.1",
783 "rand_core 0.3.1",
784 ]
784 ]
785
785
786 [[package]]
786 [[package]]
787 name = "redox_syscall"
787 name = "redox_syscall"
788 version = "0.1.57"
788 version = "0.1.57"
789 source = "registry+https://github.com/rust-lang/crates.io-index"
789 source = "registry+https://github.com/rust-lang/crates.io-index"
790 checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
790 checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
791
791
792 [[package]]
792 [[package]]
793 name = "regex"
793 name = "regex"
794 version = "1.4.2"
794 version = "1.4.2"
795 source = "registry+https://github.com/rust-lang/crates.io-index"
795 source = "registry+https://github.com/rust-lang/crates.io-index"
796 checksum = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c"
796 checksum = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c"
797 dependencies = [
797 dependencies = [
798 "aho-corasick",
798 "aho-corasick",
799 "memchr",
799 "memchr",
800 "regex-syntax",
800 "regex-syntax",
801 "thread_local",
801 "thread_local",
802 ]
802 ]
803
803
804 [[package]]
804 [[package]]
805 name = "regex-syntax"
805 name = "regex-syntax"
806 version = "0.6.21"
806 version = "0.6.21"
807 source = "registry+https://github.com/rust-lang/crates.io-index"
807 source = "registry+https://github.com/rust-lang/crates.io-index"
808 checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189"
808 checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189"
809
809
810 [[package]]
810 [[package]]
811 name = "remove_dir_all"
811 name = "remove_dir_all"
812 version = "0.5.3"
812 version = "0.5.3"
813 source = "registry+https://github.com/rust-lang/crates.io-index"
813 source = "registry+https://github.com/rust-lang/crates.io-index"
814 checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
814 checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
815 dependencies = [
815 dependencies = [
816 "winapi",
816 "winapi",
817 ]
817 ]
818
818
819 [[package]]
819 [[package]]
820 name = "rhg"
820 name = "rhg"
821 version = "0.1.0"
821 version = "0.1.0"
822 dependencies = [
822 dependencies = [
823 "chrono",
823 "chrono",
824 "clap",
824 "clap",
825 "derive_more",
825 "derive_more",
826 "env_logger",
826 "env_logger",
827 "format-bytes",
827 "format-bytes",
828 "hg-core",
828 "hg-core",
829 "lazy_static",
829 "lazy_static",
830 "log",
830 "log",
831 "micro-timer",
831 "micro-timer",
832 "regex",
832 "regex",
833 "users",
833 "users",
834 ]
834 ]
835
835
836 [[package]]
836 [[package]]
837 name = "rust-crypto"
837 name = "rust-crypto"
838 version = "0.2.36"
838 version = "0.2.36"
839 source = "registry+https://github.com/rust-lang/crates.io-index"
839 source = "registry+https://github.com/rust-lang/crates.io-index"
840 checksum = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a"
840 checksum = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a"
841 dependencies = [
841 dependencies = [
842 "gcc",
842 "gcc",
843 "libc",
843 "libc",
844 "rand 0.3.23",
844 "rand 0.3.23",
845 "rustc-serialize",
845 "rustc-serialize",
846 "time",
846 "time",
847 ]
847 ]
848
848
849 [[package]]
849 [[package]]
850 name = "rustc-serialize"
850 name = "rustc-serialize"
851 version = "0.3.24"
851 version = "0.3.24"
852 source = "registry+https://github.com/rust-lang/crates.io-index"
852 source = "registry+https://github.com/rust-lang/crates.io-index"
853 checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
853 checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
854
854
855 [[package]]
855 [[package]]
856 name = "same-file"
856 name = "same-file"
857 version = "1.0.6"
857 version = "1.0.6"
858 source = "registry+https://github.com/rust-lang/crates.io-index"
858 source = "registry+https://github.com/rust-lang/crates.io-index"
859 checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
859 checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
860 dependencies = [
860 dependencies = [
861 "winapi-util",
861 "winapi-util",
862 ]
862 ]
863
863
864 [[package]]
864 [[package]]
865 name = "scopeguard"
865 name = "scopeguard"
866 version = "1.1.0"
866 version = "1.1.0"
867 source = "registry+https://github.com/rust-lang/crates.io-index"
867 source = "registry+https://github.com/rust-lang/crates.io-index"
868 checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
868 checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
869
869
870 [[package]]
870 [[package]]
871 name = "sized-chunks"
871 name = "sized-chunks"
872 version = "0.6.2"
872 version = "0.6.2"
873 source = "registry+https://github.com/rust-lang/crates.io-index"
873 source = "registry+https://github.com/rust-lang/crates.io-index"
874 checksum = "1ec31ceca5644fa6d444cc77548b88b67f46db6f7c71683b0f9336e671830d2f"
874 checksum = "1ec31ceca5644fa6d444cc77548b88b67f46db6f7c71683b0f9336e671830d2f"
875 dependencies = [
875 dependencies = [
876 "bitmaps",
876 "bitmaps",
877 "typenum",
877 "typenum",
878 ]
878 ]
879
879
880 [[package]]
880 [[package]]
881 name = "static_assertions"
881 name = "static_assertions"
882 version = "1.1.0"
882 version = "1.1.0"
883 source = "registry+https://github.com/rust-lang/crates.io-index"
883 source = "registry+https://github.com/rust-lang/crates.io-index"
884 checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
884 checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
885
885
886 [[package]]
886 [[package]]
887 name = "strsim"
887 name = "strsim"
888 version = "0.8.0"
888 version = "0.8.0"
889 source = "registry+https://github.com/rust-lang/crates.io-index"
889 source = "registry+https://github.com/rust-lang/crates.io-index"
890 checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
890 checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
891
891
892 [[package]]
892 [[package]]
893 name = "syn"
893 name = "syn"
894 version = "1.0.54"
894 version = "1.0.54"
895 source = "registry+https://github.com/rust-lang/crates.io-index"
895 source = "registry+https://github.com/rust-lang/crates.io-index"
896 checksum = "9a2af957a63d6bd42255c359c93d9bfdb97076bd3b820897ce55ffbfbf107f44"
896 checksum = "9a2af957a63d6bd42255c359c93d9bfdb97076bd3b820897ce55ffbfbf107f44"
897 dependencies = [
897 dependencies = [
898 "proc-macro2",
898 "proc-macro2",
899 "quote",
899 "quote",
900 "unicode-xid",
900 "unicode-xid",
901 ]
901 ]
902
902
903 [[package]]
903 [[package]]
904 name = "tempfile"
904 name = "tempfile"
905 version = "3.1.0"
905 version = "3.1.0"
906 source = "registry+https://github.com/rust-lang/crates.io-index"
906 source = "registry+https://github.com/rust-lang/crates.io-index"
907 checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
907 checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
908 dependencies = [
908 dependencies = [
909 "cfg-if 0.1.10",
909 "cfg-if 0.1.10",
910 "libc",
910 "libc",
911 "rand 0.7.3",
911 "rand 0.7.3",
912 "redox_syscall",
912 "redox_syscall",
913 "remove_dir_all",
913 "remove_dir_all",
914 "winapi",
914 "winapi",
915 ]
915 ]
916
916
917 [[package]]
917 [[package]]
918 name = "termcolor"
918 name = "termcolor"
919 version = "1.1.2"
919 version = "1.1.2"
920 source = "registry+https://github.com/rust-lang/crates.io-index"
920 source = "registry+https://github.com/rust-lang/crates.io-index"
921 checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
921 checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
922 dependencies = [
922 dependencies = [
923 "winapi-util",
923 "winapi-util",
924 ]
924 ]
925
925
926 [[package]]
926 [[package]]
927 name = "textwrap"
927 name = "textwrap"
928 version = "0.11.0"
928 version = "0.11.0"
929 source = "registry+https://github.com/rust-lang/crates.io-index"
929 source = "registry+https://github.com/rust-lang/crates.io-index"
930 checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
930 checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
931 dependencies = [
931 dependencies = [
932 "unicode-width",
932 "unicode-width",
933 ]
933 ]
934
934
935 [[package]]
935 [[package]]
936 name = "thread_local"
936 name = "thread_local"
937 version = "1.0.1"
937 version = "1.0.1"
938 source = "registry+https://github.com/rust-lang/crates.io-index"
938 source = "registry+https://github.com/rust-lang/crates.io-index"
939 checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
939 checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
940 dependencies = [
940 dependencies = [
941 "lazy_static",
941 "lazy_static",
942 ]
942 ]
943
943
944 [[package]]
944 [[package]]
945 name = "time"
945 name = "time"
946 version = "0.1.44"
946 version = "0.1.44"
947 source = "registry+https://github.com/rust-lang/crates.io-index"
947 source = "registry+https://github.com/rust-lang/crates.io-index"
948 checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
948 checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
949 dependencies = [
949 dependencies = [
950 "libc",
950 "libc",
951 "wasi 0.10.0+wasi-snapshot-preview1",
951 "wasi 0.10.0+wasi-snapshot-preview1",
952 "winapi",
952 "winapi",
953 ]
953 ]
954
954
955 [[package]]
955 [[package]]
956 name = "twox-hash"
956 name = "twox-hash"
957 version = "1.6.0"
957 version = "1.6.0"
958 source = "registry+https://github.com/rust-lang/crates.io-index"
958 source = "registry+https://github.com/rust-lang/crates.io-index"
959 checksum = "04f8ab788026715fa63b31960869617cba39117e520eb415b0139543e325ab59"
959 checksum = "04f8ab788026715fa63b31960869617cba39117e520eb415b0139543e325ab59"
960 dependencies = [
960 dependencies = [
961 "cfg-if 0.1.10",
961 "cfg-if 0.1.10",
962 "rand 0.7.3",
962 "rand 0.7.3",
963 "static_assertions",
963 "static_assertions",
964 ]
964 ]
965
965
966 [[package]]
966 [[package]]
967 name = "typenum"
967 name = "typenum"
968 version = "1.12.0"
968 version = "1.12.0"
969 source = "registry+https://github.com/rust-lang/crates.io-index"
969 source = "registry+https://github.com/rust-lang/crates.io-index"
970 checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"
970 checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"
971
971
972 [[package]]
972 [[package]]
973 name = "unicode-width"
973 name = "unicode-width"
974 version = "0.1.8"
974 version = "0.1.8"
975 source = "registry+https://github.com/rust-lang/crates.io-index"
975 source = "registry+https://github.com/rust-lang/crates.io-index"
976 checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
976 checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
977
977
978 [[package]]
978 [[package]]
979 name = "unicode-xid"
979 name = "unicode-xid"
980 version = "0.2.1"
980 version = "0.2.1"
981 source = "registry+https://github.com/rust-lang/crates.io-index"
981 source = "registry+https://github.com/rust-lang/crates.io-index"
982 checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
982 checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
983
983
984 [[package]]
984 [[package]]
985 name = "users"
985 name = "users"
986 version = "0.11.0"
986 version = "0.11.0"
987 source = "registry+https://github.com/rust-lang/crates.io-index"
987 source = "registry+https://github.com/rust-lang/crates.io-index"
988 checksum = "24cc0f6d6f267b73e5a2cadf007ba8f9bc39c6a6f9666f8cf25ea809a153b032"
988 checksum = "24cc0f6d6f267b73e5a2cadf007ba8f9bc39c6a6f9666f8cf25ea809a153b032"
989 dependencies = [
989 dependencies = [
990 "libc",
990 "libc",
991 "log",
991 "log",
992 ]
992 ]
993
993
994 [[package]]
994 [[package]]
995 name = "vcpkg"
995 name = "vcpkg"
996 version = "0.2.11"
996 version = "0.2.11"
997 source = "registry+https://github.com/rust-lang/crates.io-index"
997 source = "registry+https://github.com/rust-lang/crates.io-index"
998 checksum = "b00bca6106a5e23f3eee943593759b7fcddb00554332e856d990c893966879fb"
998 checksum = "b00bca6106a5e23f3eee943593759b7fcddb00554332e856d990c893966879fb"
999
999
1000 [[package]]
1000 [[package]]
1001 name = "vec_map"
1001 name = "vec_map"
1002 version = "0.8.2"
1002 version = "0.8.2"
1003 source = "registry+https://github.com/rust-lang/crates.io-index"
1003 source = "registry+https://github.com/rust-lang/crates.io-index"
1004 checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
1004 checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
1005
1005
1006 [[package]]
1006 [[package]]
1007 name = "version_check"
1007 name = "version_check"
1008 version = "0.9.2"
1008 version = "0.9.2"
1009 source = "registry+https://github.com/rust-lang/crates.io-index"
1009 source = "registry+https://github.com/rust-lang/crates.io-index"
1010 checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
1010 checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
1011
1011
1012 [[package]]
1012 [[package]]
1013 name = "wasi"
1013 name = "wasi"
1014 version = "0.9.0+wasi-snapshot-preview1"
1014 version = "0.9.0+wasi-snapshot-preview1"
1015 source = "registry+https://github.com/rust-lang/crates.io-index"
1015 source = "registry+https://github.com/rust-lang/crates.io-index"
1016 checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
1016 checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
1017
1017
1018 [[package]]
1018 [[package]]
1019 name = "wasi"
1019 name = "wasi"
1020 version = "0.10.0+wasi-snapshot-preview1"
1020 version = "0.10.0+wasi-snapshot-preview1"
1021 source = "registry+https://github.com/rust-lang/crates.io-index"
1021 source = "registry+https://github.com/rust-lang/crates.io-index"
1022 checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
1022 checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
1023
1023
1024 [[package]]
1024 [[package]]
1025 name = "winapi"
1025 name = "winapi"
1026 version = "0.3.9"
1026 version = "0.3.9"
1027 source = "registry+https://github.com/rust-lang/crates.io-index"
1027 source = "registry+https://github.com/rust-lang/crates.io-index"
1028 checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
1028 checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
1029 dependencies = [
1029 dependencies = [
1030 "winapi-i686-pc-windows-gnu",
1030 "winapi-i686-pc-windows-gnu",
1031 "winapi-x86_64-pc-windows-gnu",
1031 "winapi-x86_64-pc-windows-gnu",
1032 ]
1032 ]
1033
1033
1034 [[package]]
1034 [[package]]
1035 name = "winapi-i686-pc-windows-gnu"
1035 name = "winapi-i686-pc-windows-gnu"
1036 version = "0.4.0"
1036 version = "0.4.0"
1037 source = "registry+https://github.com/rust-lang/crates.io-index"
1037 source = "registry+https://github.com/rust-lang/crates.io-index"
1038 checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
1038 checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
1039
1039
1040 [[package]]
1040 [[package]]
1041 name = "winapi-util"
1041 name = "winapi-util"
1042 version = "0.1.5"
1042 version = "0.1.5"
1043 source = "registry+https://github.com/rust-lang/crates.io-index"
1043 source = "registry+https://github.com/rust-lang/crates.io-index"
1044 checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
1044 checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
1045 dependencies = [
1045 dependencies = [
1046 "winapi",
1046 "winapi",
1047 ]
1047 ]
1048
1048
1049 [[package]]
1049 [[package]]
1050 name = "winapi-x86_64-pc-windows-gnu"
1050 name = "winapi-x86_64-pc-windows-gnu"
1051 version = "0.4.0"
1051 version = "0.4.0"
1052 source = "registry+https://github.com/rust-lang/crates.io-index"
1052 source = "registry+https://github.com/rust-lang/crates.io-index"
1053 checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
1053 checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
1054
1054
1055 [[package]]
1055 [[package]]
1056 name = "zstd"
1056 name = "zstd"
1057 version = "0.5.3+zstd.1.4.5"
1057 version = "0.5.3+zstd.1.4.5"
1058 source = "registry+https://github.com/rust-lang/crates.io-index"
1058 source = "registry+https://github.com/rust-lang/crates.io-index"
1059 checksum = "01b32eaf771efa709e8308605bbf9319bf485dc1503179ec0469b611937c0cd8"
1059 checksum = "01b32eaf771efa709e8308605bbf9319bf485dc1503179ec0469b611937c0cd8"
1060 dependencies = [
1060 dependencies = [
1061 "zstd-safe",
1061 "zstd-safe",
1062 ]
1062 ]
1063
1063
1064 [[package]]
1064 [[package]]
1065 name = "zstd-safe"
1065 name = "zstd-safe"
1066 version = "2.0.5+zstd.1.4.5"
1066 version = "2.0.5+zstd.1.4.5"
1067 source = "registry+https://github.com/rust-lang/crates.io-index"
1067 source = "registry+https://github.com/rust-lang/crates.io-index"
1068 checksum = "1cfb642e0d27f64729a639c52db457e0ae906e7bc6f5fe8f5c453230400f1055"
1068 checksum = "1cfb642e0d27f64729a639c52db457e0ae906e7bc6f5fe8f5c453230400f1055"
1069 dependencies = [
1069 dependencies = [
1070 "libc",
1070 "libc",
1071 "zstd-sys",
1071 "zstd-sys",
1072 ]
1072 ]
1073
1073
1074 [[package]]
1074 [[package]]
1075 name = "zstd-sys"
1075 name = "zstd-sys"
1076 version = "1.4.17+zstd.1.4.5"
1076 version = "1.4.17+zstd.1.4.5"
1077 source = "registry+https://github.com/rust-lang/crates.io-index"
1077 source = "registry+https://github.com/rust-lang/crates.io-index"
1078 checksum = "b89249644df056b522696b1bb9e7c18c87e8ffa3e2f0dc3b0155875d6498f01b"
1078 checksum = "b89249644df056b522696b1bb9e7c18c87e8ffa3e2f0dc3b0155875d6498f01b"
1079 dependencies = [
1079 dependencies = [
1080 "cc",
1080 "cc",
1081 "glob",
1081 "glob",
1082 "itertools",
1082 "itertools",
1083 "libc",
1083 "libc",
1084 ]
1084 ]
@@ -1,49 +1,49 b''
1 [package]
1 [package]
2 name = "hg-core"
2 name = "hg-core"
3 version = "0.1.0"
3 version = "0.1.0"
4 authors = ["Georges Racinet <gracinet@anybox.fr>"]
4 authors = ["Georges Racinet <gracinet@anybox.fr>"]
5 description = "Mercurial pure Rust core library, with no assumption on Python bindings (FFI)"
5 description = "Mercurial pure Rust core library, with no assumption on Python bindings (FFI)"
6 edition = "2018"
6 edition = "2018"
7
7
8 [lib]
8 [lib]
9 name = "hg"
9 name = "hg"
10
10
11 [dependencies]
11 [dependencies]
12 bytes-cast = "0.1"
12 bytes-cast = "0.1"
13 byteorder = "1.3.4"
13 byteorder = "1.3.4"
14 derive_more = "0.99"
14 derive_more = "0.99"
15 home = "0.5"
15 home = "0.5"
16 im-rc = "15.0.*"
16 im-rc = "15.0.*"
17 lazy_static = "1.4.0"
17 lazy_static = "1.4.0"
18 rand = "0.7.3"
18 rand = "0.7.3"
19 rand_pcg = "0.2.1"
19 rand_pcg = "0.2.1"
20 rand_distr = "0.2.2"
20 rand_distr = "0.2.2"
21 rayon = "1.3.0"
21 rayon = "1.3.0"
22 regex = "1.3.9"
22 regex = "1.3.9"
23 twox-hash = "1.5.0"
23 twox-hash = "1.5.0"
24 same-file = "1.0.6"
24 same-file = "1.0.6"
25 crossbeam-channel = "0.4"
25 crossbeam-channel = "0.4"
26 micro-timer = "0.3.0"
26 micro-timer = "0.3.0"
27 log = "0.4.8"
27 log = "0.4.8"
28 memmap = "0.7.0"
28 memmap = "0.7.0"
29 zstd = "0.5.3"
29 zstd = "0.5.3"
30 rust-crypto = "0.2.36"
30 rust-crypto = "0.2.36"
31 format-bytes = "0.2.0"
31 format-bytes = "0.2.2"
32
32
33 # We don't use the `miniz-oxide` backend to not change rhg benchmarks and until
33 # We don't use the `miniz-oxide` backend to not change rhg benchmarks and until
34 # we have a clearer view of which backend is the fastest.
34 # we have a clearer view of which backend is the fastest.
35 [dependencies.flate2]
35 [dependencies.flate2]
36 version = "1.0.16"
36 version = "1.0.16"
37 features = ["zlib"]
37 features = ["zlib"]
38 default-features = false
38 default-features = false
39
39
40 [dev-dependencies]
40 [dev-dependencies]
41 clap = "*"
41 clap = "*"
42 pretty_assertions = "0.6.1"
42 pretty_assertions = "0.6.1"
43 tempfile = "3.1.0"
43 tempfile = "3.1.0"
44
44
45 [features]
45 [features]
46 # Use a (still unoptimized) tree for the dirstate instead of the current flat
46 # Use a (still unoptimized) tree for the dirstate instead of the current flat
47 # dirstate. This is not yet recommended for performance reasons. A future
47 # dirstate. This is not yet recommended for performance reasons. A future
48 # version might make it the default, or make it a runtime option.
48 # version might make it the default, or make it a runtime option.
49 dirstate-tree = []
49 dirstate-tree = []
@@ -1,305 +1,310 b''
1 // layer.rs
1 // layer.rs
2 //
2 //
3 // Copyright 2020
3 // Copyright 2020
4 // Valentin Gatien-Baron,
4 // Valentin Gatien-Baron,
5 // Raphaël Gomès <rgomes@octobus.net>
5 // Raphaël Gomès <rgomes@octobus.net>
6 //
6 //
7 // This software may be used and distributed according to the terms of the
7 // This software may be used and distributed according to the terms of the
8 // GNU General Public License version 2 or any later version.
8 // GNU General Public License version 2 or any later version.
9
9
10 use crate::errors::{HgError, IoResultExt};
10 use crate::errors::HgError;
11 use crate::utils::files::{get_bytes_from_path, get_path_from_bytes};
11 use crate::utils::files::{get_bytes_from_path, get_path_from_bytes};
12 use format_bytes::{format_bytes, write_bytes, DisplayBytes};
12 use format_bytes::{format_bytes, write_bytes, DisplayBytes};
13 use lazy_static::lazy_static;
13 use lazy_static::lazy_static;
14 use regex::bytes::Regex;
14 use regex::bytes::Regex;
15 use std::collections::HashMap;
15 use std::collections::HashMap;
16 use std::path::{Path, PathBuf};
16 use std::path::{Path, PathBuf};
17
17
18 lazy_static! {
18 lazy_static! {
19 static ref SECTION_RE: Regex = make_regex(r"^\[([^\[]+)\]");
19 static ref SECTION_RE: Regex = make_regex(r"^\[([^\[]+)\]");
20 static ref ITEM_RE: Regex = make_regex(r"^([^=\s][^=]*?)\s*=\s*((.*\S)?)");
20 static ref ITEM_RE: Regex = make_regex(r"^([^=\s][^=]*?)\s*=\s*((.*\S)?)");
21 /// Continuation whitespace
21 /// Continuation whitespace
22 static ref CONT_RE: Regex = make_regex(r"^\s+(\S|\S.*\S)\s*$");
22 static ref CONT_RE: Regex = make_regex(r"^\s+(\S|\S.*\S)\s*$");
23 static ref EMPTY_RE: Regex = make_regex(r"^(;|#|\s*$)");
23 static ref EMPTY_RE: Regex = make_regex(r"^(;|#|\s*$)");
24 static ref COMMENT_RE: Regex = make_regex(r"^(;|#)");
24 static ref COMMENT_RE: Regex = make_regex(r"^(;|#)");
25 /// A directive that allows for removing previous entries
25 /// A directive that allows for removing previous entries
26 static ref UNSET_RE: Regex = make_regex(r"^%unset\s+(\S+)");
26 static ref UNSET_RE: Regex = make_regex(r"^%unset\s+(\S+)");
27 /// A directive that allows for including other config files
27 /// A directive that allows for including other config files
28 static ref INCLUDE_RE: Regex = make_regex(r"^%include\s+(\S|\S.*\S)\s*$");
28 static ref INCLUDE_RE: Regex = make_regex(r"^%include\s+(\S|\S.*\S)\s*$");
29 }
29 }
30
30
31 /// All config values separated by layers of precedence.
31 /// All config values separated by layers of precedence.
32 /// Each config source may be split in multiple layers if `%include` directives
32 /// Each config source may be split in multiple layers if `%include` directives
33 /// are used.
33 /// are used.
34 /// TODO detail the general precedence
34 /// TODO detail the general precedence
35 #[derive(Clone)]
35 #[derive(Clone)]
36 pub struct ConfigLayer {
36 pub struct ConfigLayer {
37 /// Mapping of the sections to their items
37 /// Mapping of the sections to their items
38 sections: HashMap<Vec<u8>, ConfigItem>,
38 sections: HashMap<Vec<u8>, ConfigItem>,
39 /// All sections (and their items/values) in a layer share the same origin
39 /// All sections (and their items/values) in a layer share the same origin
40 pub origin: ConfigOrigin,
40 pub origin: ConfigOrigin,
41 /// Whether this layer comes from a trusted user or group
41 /// Whether this layer comes from a trusted user or group
42 pub trusted: bool,
42 pub trusted: bool,
43 }
43 }
44
44
45 impl ConfigLayer {
45 impl ConfigLayer {
46 pub fn new(origin: ConfigOrigin) -> Self {
46 pub fn new(origin: ConfigOrigin) -> Self {
47 ConfigLayer {
47 ConfigLayer {
48 sections: HashMap::new(),
48 sections: HashMap::new(),
49 trusted: true, // TODO check
49 trusted: true, // TODO check
50 origin,
50 origin,
51 }
51 }
52 }
52 }
53
53
54 /// Parse `--config` CLI arguments and return a layer if there’s any
54 /// Parse `--config` CLI arguments and return a layer if there’s any
55 pub(crate) fn parse_cli_args(
55 pub(crate) fn parse_cli_args(
56 cli_config_args: impl IntoIterator<Item = impl AsRef<[u8]>>,
56 cli_config_args: impl IntoIterator<Item = impl AsRef<[u8]>>,
57 ) -> Result<Option<Self>, ConfigError> {
57 ) -> Result<Option<Self>, ConfigError> {
58 fn parse_one(arg: &[u8]) -> Option<(Vec<u8>, Vec<u8>, Vec<u8>)> {
58 fn parse_one(arg: &[u8]) -> Option<(Vec<u8>, Vec<u8>, Vec<u8>)> {
59 use crate::utils::SliceExt;
59 use crate::utils::SliceExt;
60
60
61 let (section_and_item, value) = arg.split_2(b'=')?;
61 let (section_and_item, value) = arg.split_2(b'=')?;
62 let (section, item) = section_and_item.trim().split_2(b'.')?;
62 let (section, item) = section_and_item.trim().split_2(b'.')?;
63 Some((
63 Some((
64 section.to_owned(),
64 section.to_owned(),
65 item.to_owned(),
65 item.to_owned(),
66 value.trim().to_owned(),
66 value.trim().to_owned(),
67 ))
67 ))
68 }
68 }
69
69
70 let mut layer = Self::new(ConfigOrigin::CommandLine);
70 let mut layer = Self::new(ConfigOrigin::CommandLine);
71 for arg in cli_config_args {
71 for arg in cli_config_args {
72 let arg = arg.as_ref();
72 let arg = arg.as_ref();
73 if let Some((section, item, value)) = parse_one(arg) {
73 if let Some((section, item, value)) = parse_one(arg) {
74 layer.add(section, item, value, None);
74 layer.add(section, item, value, None);
75 } else {
75 } else {
76 Err(HgError::abort(format!(
76 Err(HgError::abort(format!(
77 "malformed --config option: '{}' \
77 "abort: malformed --config option: '{}' \
78 (use --config section.name=value)",
78 (use --config section.name=value)",
79 String::from_utf8_lossy(arg),
79 String::from_utf8_lossy(arg),
80 )))?
80 )))?
81 }
81 }
82 }
82 }
83 if layer.sections.is_empty() {
83 if layer.sections.is_empty() {
84 Ok(None)
84 Ok(None)
85 } else {
85 } else {
86 Ok(Some(layer))
86 Ok(Some(layer))
87 }
87 }
88 }
88 }
89
89
90 /// Returns whether this layer comes from `--config` CLI arguments
90 /// Returns whether this layer comes from `--config` CLI arguments
91 pub(crate) fn is_from_command_line(&self) -> bool {
91 pub(crate) fn is_from_command_line(&self) -> bool {
92 if let ConfigOrigin::CommandLine = self.origin {
92 if let ConfigOrigin::CommandLine = self.origin {
93 true
93 true
94 } else {
94 } else {
95 false
95 false
96 }
96 }
97 }
97 }
98
98
99 /// Add an entry to the config, overwriting the old one if already present.
99 /// Add an entry to the config, overwriting the old one if already present.
100 pub fn add(
100 pub fn add(
101 &mut self,
101 &mut self,
102 section: Vec<u8>,
102 section: Vec<u8>,
103 item: Vec<u8>,
103 item: Vec<u8>,
104 value: Vec<u8>,
104 value: Vec<u8>,
105 line: Option<usize>,
105 line: Option<usize>,
106 ) {
106 ) {
107 self.sections
107 self.sections
108 .entry(section)
108 .entry(section)
109 .or_insert_with(|| HashMap::new())
109 .or_insert_with(|| HashMap::new())
110 .insert(item, ConfigValue { bytes: value, line });
110 .insert(item, ConfigValue { bytes: value, line });
111 }
111 }
112
112
113 /// Returns the config value in `<section>.<item>` if it exists
113 /// Returns the config value in `<section>.<item>` if it exists
114 pub fn get(&self, section: &[u8], item: &[u8]) -> Option<&ConfigValue> {
114 pub fn get(&self, section: &[u8], item: &[u8]) -> Option<&ConfigValue> {
115 Some(self.sections.get(section)?.get(item)?)
115 Some(self.sections.get(section)?.get(item)?)
116 }
116 }
117
117
118 /// Returns the keys defined in the given section
118 /// Returns the keys defined in the given section
119 pub fn iter_keys(&self, section: &[u8]) -> impl Iterator<Item = &[u8]> {
119 pub fn iter_keys(&self, section: &[u8]) -> impl Iterator<Item = &[u8]> {
120 self.sections
120 self.sections
121 .get(section)
121 .get(section)
122 .into_iter()
122 .into_iter()
123 .flat_map(|section| section.keys().map(|vec| &**vec))
123 .flat_map(|section| section.keys().map(|vec| &**vec))
124 }
124 }
125
125
126 pub fn is_empty(&self) -> bool {
126 pub fn is_empty(&self) -> bool {
127 self.sections.is_empty()
127 self.sections.is_empty()
128 }
128 }
129
129
130 /// Returns a `Vec` of layers in order of precedence (so, in read order),
130 /// Returns a `Vec` of layers in order of precedence (so, in read order),
131 /// recursively parsing the `%include` directives if any.
131 /// recursively parsing the `%include` directives if any.
132 pub fn parse(src: &Path, data: &[u8]) -> Result<Vec<Self>, ConfigError> {
132 pub fn parse(src: &Path, data: &[u8]) -> Result<Vec<Self>, ConfigError> {
133 let mut layers = vec![];
133 let mut layers = vec![];
134
134
135 // Discard byte order mark if any
135 // Discard byte order mark if any
136 let data = if data.starts_with(b"\xef\xbb\xbf") {
136 let data = if data.starts_with(b"\xef\xbb\xbf") {
137 &data[3..]
137 &data[3..]
138 } else {
138 } else {
139 data
139 data
140 };
140 };
141
141
142 // TODO check if it's trusted
142 // TODO check if it's trusted
143 let mut current_layer = Self::new(ConfigOrigin::File(src.to_owned()));
143 let mut current_layer = Self::new(ConfigOrigin::File(src.to_owned()));
144
144
145 let mut lines_iter =
145 let mut lines_iter =
146 data.split(|b| *b == b'\n').enumerate().peekable();
146 data.split(|b| *b == b'\n').enumerate().peekable();
147 let mut section = b"".to_vec();
147 let mut section = b"".to_vec();
148
148
149 while let Some((index, bytes)) = lines_iter.next() {
149 while let Some((index, bytes)) = lines_iter.next() {
150 let line = Some(index + 1);
150 if let Some(m) = INCLUDE_RE.captures(&bytes) {
151 if let Some(m) = INCLUDE_RE.captures(&bytes) {
151 let filename_bytes = &m[1];
152 let filename_bytes = &m[1];
152 // `Path::parent` only fails for the root directory,
153 // `Path::parent` only fails for the root directory,
153 // which `src` can’t be since we’ve managed to open it as a
154 // which `src` can’t be since we’ve managed to open it as a
154 // file.
155 // file.
155 let dir = src
156 let dir = src
156 .parent()
157 .parent()
157 .expect("Path::parent fail on a file we’ve read");
158 .expect("Path::parent fail on a file we’ve read");
158 // `Path::join` with an absolute argument correctly ignores the
159 // `Path::join` with an absolute argument correctly ignores the
159 // base path
160 // base path
160 let filename = dir.join(&get_path_from_bytes(&filename_bytes));
161 let filename = dir.join(&get_path_from_bytes(&filename_bytes));
161 let data =
162 let data = std::fs::read(&filename).map_err(|io_error| {
162 std::fs::read(&filename).when_reading_file(&filename)?;
163 ConfigParseError {
164 origin: ConfigOrigin::File(src.to_owned()),
165 line,
166 message: format_bytes!(
167 b"cannot include {} ({})",
168 filename_bytes,
169 format_bytes::Utf8(io_error)
170 ),
171 }
172 })?;
163 layers.push(current_layer);
173 layers.push(current_layer);
164 layers.extend(Self::parse(&filename, &data)?);
174 layers.extend(Self::parse(&filename, &data)?);
165 current_layer = Self::new(ConfigOrigin::File(src.to_owned()));
175 current_layer = Self::new(ConfigOrigin::File(src.to_owned()));
166 } else if let Some(_) = EMPTY_RE.captures(&bytes) {
176 } else if let Some(_) = EMPTY_RE.captures(&bytes) {
167 } else if let Some(m) = SECTION_RE.captures(&bytes) {
177 } else if let Some(m) = SECTION_RE.captures(&bytes) {
168 section = m[1].to_vec();
178 section = m[1].to_vec();
169 } else if let Some(m) = ITEM_RE.captures(&bytes) {
179 } else if let Some(m) = ITEM_RE.captures(&bytes) {
170 let item = m[1].to_vec();
180 let item = m[1].to_vec();
171 let mut value = m[2].to_vec();
181 let mut value = m[2].to_vec();
172 loop {
182 loop {
173 match lines_iter.peek() {
183 match lines_iter.peek() {
174 None => break,
184 None => break,
175 Some((_, v)) => {
185 Some((_, v)) => {
176 if let Some(_) = COMMENT_RE.captures(&v) {
186 if let Some(_) = COMMENT_RE.captures(&v) {
177 } else if let Some(_) = CONT_RE.captures(&v) {
187 } else if let Some(_) = CONT_RE.captures(&v) {
178 value.extend(b"\n");
188 value.extend(b"\n");
179 value.extend(&m[1]);
189 value.extend(&m[1]);
180 } else {
190 } else {
181 break;
191 break;
182 }
192 }
183 }
193 }
184 };
194 };
185 lines_iter.next();
195 lines_iter.next();
186 }
196 }
187 current_layer.add(
197 current_layer.add(section.clone(), item, value, line);
188 section.clone(),
189 item,
190 value,
191 Some(index + 1),
192 );
193 } else if let Some(m) = UNSET_RE.captures(&bytes) {
198 } else if let Some(m) = UNSET_RE.captures(&bytes) {
194 if let Some(map) = current_layer.sections.get_mut(&section) {
199 if let Some(map) = current_layer.sections.get_mut(&section) {
195 map.remove(&m[1]);
200 map.remove(&m[1]);
196 }
201 }
197 } else {
202 } else {
198 let message = if bytes.starts_with(b" ") {
203 let message = if bytes.starts_with(b" ") {
199 format_bytes!(b"unexpected leading whitespace: {}", bytes)
204 format_bytes!(b"unexpected leading whitespace: {}", bytes)
200 } else {
205 } else {
201 bytes.to_owned()
206 bytes.to_owned()
202 };
207 };
203 return Err(ConfigParseError {
208 return Err(ConfigParseError {
204 origin: ConfigOrigin::File(src.to_owned()),
209 origin: ConfigOrigin::File(src.to_owned()),
205 line: Some(index + 1),
210 line,
206 message,
211 message,
207 }
212 }
208 .into());
213 .into());
209 }
214 }
210 }
215 }
211 if !current_layer.is_empty() {
216 if !current_layer.is_empty() {
212 layers.push(current_layer);
217 layers.push(current_layer);
213 }
218 }
214 Ok(layers)
219 Ok(layers)
215 }
220 }
216 }
221 }
217
222
218 impl DisplayBytes for ConfigLayer {
223 impl DisplayBytes for ConfigLayer {
219 fn display_bytes(
224 fn display_bytes(
220 &self,
225 &self,
221 out: &mut dyn std::io::Write,
226 out: &mut dyn std::io::Write,
222 ) -> std::io::Result<()> {
227 ) -> std::io::Result<()> {
223 let mut sections: Vec<_> = self.sections.iter().collect();
228 let mut sections: Vec<_> = self.sections.iter().collect();
224 sections.sort_by(|e0, e1| e0.0.cmp(e1.0));
229 sections.sort_by(|e0, e1| e0.0.cmp(e1.0));
225
230
226 for (section, items) in sections.into_iter() {
231 for (section, items) in sections.into_iter() {
227 let mut items: Vec<_> = items.into_iter().collect();
232 let mut items: Vec<_> = items.into_iter().collect();
228 items.sort_by(|e0, e1| e0.0.cmp(e1.0));
233 items.sort_by(|e0, e1| e0.0.cmp(e1.0));
229
234
230 for (item, config_entry) in items {
235 for (item, config_entry) in items {
231 write_bytes!(
236 write_bytes!(
232 out,
237 out,
233 b"{}.{}={} # {}\n",
238 b"{}.{}={} # {}\n",
234 section,
239 section,
235 item,
240 item,
236 &config_entry.bytes,
241 &config_entry.bytes,
237 &self.origin,
242 &self.origin,
238 )?
243 )?
239 }
244 }
240 }
245 }
241 Ok(())
246 Ok(())
242 }
247 }
243 }
248 }
244
249
245 /// Mapping of section item to value.
250 /// Mapping of section item to value.
246 /// In the following:
251 /// In the following:
247 /// ```text
252 /// ```text
248 /// [ui]
253 /// [ui]
249 /// paginate=no
254 /// paginate=no
250 /// ```
255 /// ```
251 /// "paginate" is the section item and "no" the value.
256 /// "paginate" is the section item and "no" the value.
252 pub type ConfigItem = HashMap<Vec<u8>, ConfigValue>;
257 pub type ConfigItem = HashMap<Vec<u8>, ConfigValue>;
253
258
254 #[derive(Clone, Debug, PartialEq)]
259 #[derive(Clone, Debug, PartialEq)]
255 pub struct ConfigValue {
260 pub struct ConfigValue {
256 /// The raw bytes of the value (be it from the CLI, env or from a file)
261 /// The raw bytes of the value (be it from the CLI, env or from a file)
257 pub bytes: Vec<u8>,
262 pub bytes: Vec<u8>,
258 /// Only present if the value comes from a file, 1-indexed.
263 /// Only present if the value comes from a file, 1-indexed.
259 pub line: Option<usize>,
264 pub line: Option<usize>,
260 }
265 }
261
266
262 #[derive(Clone, Debug)]
267 #[derive(Clone, Debug)]
263 pub enum ConfigOrigin {
268 pub enum ConfigOrigin {
264 /// From a configuration file
269 /// From a configuration file
265 File(PathBuf),
270 File(PathBuf),
266 /// From a `--config` CLI argument
271 /// From a `--config` CLI argument
267 CommandLine,
272 CommandLine,
268 /// From environment variables like `$PAGER` or `$EDITOR`
273 /// From environment variables like `$PAGER` or `$EDITOR`
269 Environment(Vec<u8>),
274 Environment(Vec<u8>),
270 /* TODO cli
275 /* TODO cli
271 * TODO defaults (configitems.py)
276 * TODO defaults (configitems.py)
272 * TODO extensions
277 * TODO extensions
273 * TODO Python resources?
278 * TODO Python resources?
274 * Others? */
279 * Others? */
275 }
280 }
276
281
277 impl DisplayBytes for ConfigOrigin {
282 impl DisplayBytes for ConfigOrigin {
278 fn display_bytes(
283 fn display_bytes(
279 &self,
284 &self,
280 out: &mut dyn std::io::Write,
285 out: &mut dyn std::io::Write,
281 ) -> std::io::Result<()> {
286 ) -> std::io::Result<()> {
282 match self {
287 match self {
283 ConfigOrigin::File(p) => out.write_all(&get_bytes_from_path(p)),
288 ConfigOrigin::File(p) => out.write_all(&get_bytes_from_path(p)),
284 ConfigOrigin::CommandLine => out.write_all(b"--config"),
289 ConfigOrigin::CommandLine => out.write_all(b"--config"),
285 ConfigOrigin::Environment(e) => write_bytes!(out, b"${}", e),
290 ConfigOrigin::Environment(e) => write_bytes!(out, b"${}", e),
286 }
291 }
287 }
292 }
288 }
293 }
289
294
290 #[derive(Debug)]
295 #[derive(Debug)]
291 pub struct ConfigParseError {
296 pub struct ConfigParseError {
292 pub origin: ConfigOrigin,
297 pub origin: ConfigOrigin,
293 pub line: Option<usize>,
298 pub line: Option<usize>,
294 pub message: Vec<u8>,
299 pub message: Vec<u8>,
295 }
300 }
296
301
297 #[derive(Debug, derive_more::From)]
302 #[derive(Debug, derive_more::From)]
298 pub enum ConfigError {
303 pub enum ConfigError {
299 Parse(ConfigParseError),
304 Parse(ConfigParseError),
300 Other(HgError),
305 Other(HgError),
301 }
306 }
302
307
303 fn make_regex(pattern: &'static str) -> Regex {
308 fn make_regex(pattern: &'static str) -> Regex {
304 Regex::new(pattern).expect("expected a valid regex")
309 Regex::new(pattern).expect("expected a valid regex")
305 }
310 }
@@ -1,196 +1,196 b''
1 use crate::config::ConfigValueParseError;
1 use crate::config::ConfigValueParseError;
2 use std::fmt;
2 use std::fmt;
3
3
4 /// Common error cases that can happen in many different APIs
4 /// Common error cases that can happen in many different APIs
5 #[derive(Debug, derive_more::From)]
5 #[derive(Debug, derive_more::From)]
6 pub enum HgError {
6 pub enum HgError {
7 IoError {
7 IoError {
8 error: std::io::Error,
8 error: std::io::Error,
9 context: IoErrorContext,
9 context: IoErrorContext,
10 },
10 },
11
11
12 /// A file under `.hg/` normally only written by Mercurial is not in the
12 /// A file under `.hg/` normally only written by Mercurial is not in the
13 /// expected format. This indicates a bug in Mercurial, filesystem
13 /// expected format. This indicates a bug in Mercurial, filesystem
14 /// corruption, or hardware failure.
14 /// corruption, or hardware failure.
15 ///
15 ///
16 /// The given string is a short explanation for users, not intended to be
16 /// The given string is a short explanation for users, not intended to be
17 /// machine-readable.
17 /// machine-readable.
18 CorruptedRepository(String),
18 CorruptedRepository(String),
19
19
20 /// The respository or requested operation involves a feature not
20 /// The respository or requested operation involves a feature not
21 /// supported by the Rust implementation. Falling back to the Python
21 /// supported by the Rust implementation. Falling back to the Python
22 /// implementation may or may not work.
22 /// implementation may or may not work.
23 ///
23 ///
24 /// The given string is a short explanation for users, not intended to be
24 /// The given string is a short explanation for users, not intended to be
25 /// machine-readable.
25 /// machine-readable.
26 UnsupportedFeature(String),
26 UnsupportedFeature(String),
27
27
28 /// Operation cannot proceed for some other reason.
28 /// Operation cannot proceed for some other reason.
29 ///
29 ///
30 /// The given string is a short explanation for users, not intended to be
30 /// The given string is a short explanation for users, not intended to be
31 /// machine-readable.
31 /// machine-readable.
32 Abort(String),
32 Abort(String),
33
33
34 /// A configuration value is not in the expected syntax.
34 /// A configuration value is not in the expected syntax.
35 ///
35 ///
36 /// These errors can happen in many places in the code because values are
36 /// These errors can happen in many places in the code because values are
37 /// parsed lazily as the file-level parser does not know the expected type
37 /// parsed lazily as the file-level parser does not know the expected type
38 /// and syntax of each value.
38 /// and syntax of each value.
39 #[from]
39 #[from]
40 ConfigValueParseError(ConfigValueParseError),
40 ConfigValueParseError(ConfigValueParseError),
41 }
41 }
42
42
43 /// Details about where an I/O error happened
43 /// Details about where an I/O error happened
44 #[derive(Debug)]
44 #[derive(Debug)]
45 pub enum IoErrorContext {
45 pub enum IoErrorContext {
46 ReadingFile(std::path::PathBuf),
46 ReadingFile(std::path::PathBuf),
47 WritingFile(std::path::PathBuf),
47 WritingFile(std::path::PathBuf),
48 RemovingFile(std::path::PathBuf),
48 RemovingFile(std::path::PathBuf),
49 RenamingFile {
49 RenamingFile {
50 from: std::path::PathBuf,
50 from: std::path::PathBuf,
51 to: std::path::PathBuf,
51 to: std::path::PathBuf,
52 },
52 },
53 /// `std::env::current_dir`
53 /// `std::env::current_dir`
54 CurrentDir,
54 CurrentDir,
55 /// `std::env::current_exe`
55 /// `std::env::current_exe`
56 CurrentExe,
56 CurrentExe,
57 }
57 }
58
58
59 impl HgError {
59 impl HgError {
60 pub fn corrupted(explanation: impl Into<String>) -> Self {
60 pub fn corrupted(explanation: impl Into<String>) -> Self {
61 // TODO: capture a backtrace here and keep it in the error value
61 // TODO: capture a backtrace here and keep it in the error value
62 // to aid debugging?
62 // to aid debugging?
63 // https://doc.rust-lang.org/std/backtrace/struct.Backtrace.html
63 // https://doc.rust-lang.org/std/backtrace/struct.Backtrace.html
64 HgError::CorruptedRepository(explanation.into())
64 HgError::CorruptedRepository(explanation.into())
65 }
65 }
66
66
67 pub fn unsupported(explanation: impl Into<String>) -> Self {
67 pub fn unsupported(explanation: impl Into<String>) -> Self {
68 HgError::UnsupportedFeature(explanation.into())
68 HgError::UnsupportedFeature(explanation.into())
69 }
69 }
70 pub fn abort(explanation: impl Into<String>) -> Self {
70 pub fn abort(explanation: impl Into<String>) -> Self {
71 HgError::Abort(explanation.into())
71 HgError::Abort(explanation.into())
72 }
72 }
73 }
73 }
74
74
75 // TODO: use `DisplayBytes` instead to show non-Unicode filenames losslessly?
75 // TODO: use `DisplayBytes` instead to show non-Unicode filenames losslessly?
76 impl fmt::Display for HgError {
76 impl fmt::Display for HgError {
77 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
77 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
78 match self {
78 match self {
79 HgError::Abort(explanation) => write!(f, "{}", explanation),
79 HgError::Abort(explanation) => write!(f, "{}", explanation),
80 HgError::IoError { error, context } => {
80 HgError::IoError { error, context } => {
81 write!(f, "abort: {}: {}", context, error)
81 write!(f, "abort: {}: {}", context, error)
82 }
82 }
83 HgError::CorruptedRepository(explanation) => {
83 HgError::CorruptedRepository(explanation) => {
84 write!(f, "abort: corrupted repository: {}", explanation)
84 write!(f, "abort: {}", explanation)
85 }
85 }
86 HgError::UnsupportedFeature(explanation) => {
86 HgError::UnsupportedFeature(explanation) => {
87 write!(f, "unsupported feature: {}", explanation)
87 write!(f, "unsupported feature: {}", explanation)
88 }
88 }
89 HgError::ConfigValueParseError(ConfigValueParseError {
89 HgError::ConfigValueParseError(ConfigValueParseError {
90 origin: _,
90 origin: _,
91 line: _,
91 line: _,
92 section,
92 section,
93 item,
93 item,
94 value,
94 value,
95 expected_type,
95 expected_type,
96 }) => {
96 }) => {
97 // TODO: add origin and line number information, here and in
97 // TODO: add origin and line number information, here and in
98 // corresponding python code
98 // corresponding python code
99 write!(
99 write!(
100 f,
100 f,
101 "config error: {}.{} is not a {} ('{}')",
101 "config error: {}.{} is not a {} ('{}')",
102 String::from_utf8_lossy(section),
102 String::from_utf8_lossy(section),
103 String::from_utf8_lossy(item),
103 String::from_utf8_lossy(item),
104 expected_type,
104 expected_type,
105 String::from_utf8_lossy(value)
105 String::from_utf8_lossy(value)
106 )
106 )
107 }
107 }
108 }
108 }
109 }
109 }
110 }
110 }
111
111
112 // TODO: use `DisplayBytes` instead to show non-Unicode filenames losslessly?
112 // TODO: use `DisplayBytes` instead to show non-Unicode filenames losslessly?
113 impl fmt::Display for IoErrorContext {
113 impl fmt::Display for IoErrorContext {
114 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
114 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
115 match self {
115 match self {
116 IoErrorContext::ReadingFile(path) => {
116 IoErrorContext::ReadingFile(path) => {
117 write!(f, "when reading {}", path.display())
117 write!(f, "when reading {}", path.display())
118 }
118 }
119 IoErrorContext::WritingFile(path) => {
119 IoErrorContext::WritingFile(path) => {
120 write!(f, "when writing {}", path.display())
120 write!(f, "when writing {}", path.display())
121 }
121 }
122 IoErrorContext::RemovingFile(path) => {
122 IoErrorContext::RemovingFile(path) => {
123 write!(f, "when removing {}", path.display())
123 write!(f, "when removing {}", path.display())
124 }
124 }
125 IoErrorContext::RenamingFile { from, to } => write!(
125 IoErrorContext::RenamingFile { from, to } => write!(
126 f,
126 f,
127 "when renaming {} to {}",
127 "when renaming {} to {}",
128 from.display(),
128 from.display(),
129 to.display()
129 to.display()
130 ),
130 ),
131 IoErrorContext::CurrentDir => {
131 IoErrorContext::CurrentDir => {
132 write!(f, "error getting current working directory")
132 write!(f, "error getting current working directory")
133 }
133 }
134 IoErrorContext::CurrentExe => {
134 IoErrorContext::CurrentExe => {
135 write!(f, "error getting current executable")
135 write!(f, "error getting current executable")
136 }
136 }
137 }
137 }
138 }
138 }
139 }
139 }
140
140
141 pub trait IoResultExt<T> {
141 pub trait IoResultExt<T> {
142 /// Annotate a possible I/O error as related to a reading a file at the
142 /// Annotate a possible I/O error as related to a reading a file at the
143 /// given path.
143 /// given path.
144 ///
144 ///
145 /// This allows printing something like β€œFile not found when reading
145 /// This allows printing something like β€œFile not found when reading
146 /// example.txt” instead of just β€œFile not found”.
146 /// example.txt” instead of just β€œFile not found”.
147 ///
147 ///
148 /// Converts a `Result` with `std::io::Error` into one with `HgError`.
148 /// Converts a `Result` with `std::io::Error` into one with `HgError`.
149 fn when_reading_file(self, path: &std::path::Path) -> Result<T, HgError>;
149 fn when_reading_file(self, path: &std::path::Path) -> Result<T, HgError>;
150
150
151 fn with_context(
151 fn with_context(
152 self,
152 self,
153 context: impl FnOnce() -> IoErrorContext,
153 context: impl FnOnce() -> IoErrorContext,
154 ) -> Result<T, HgError>;
154 ) -> Result<T, HgError>;
155 }
155 }
156
156
157 impl<T> IoResultExt<T> for std::io::Result<T> {
157 impl<T> IoResultExt<T> for std::io::Result<T> {
158 fn when_reading_file(self, path: &std::path::Path) -> Result<T, HgError> {
158 fn when_reading_file(self, path: &std::path::Path) -> Result<T, HgError> {
159 self.with_context(|| IoErrorContext::ReadingFile(path.to_owned()))
159 self.with_context(|| IoErrorContext::ReadingFile(path.to_owned()))
160 }
160 }
161
161
162 fn with_context(
162 fn with_context(
163 self,
163 self,
164 context: impl FnOnce() -> IoErrorContext,
164 context: impl FnOnce() -> IoErrorContext,
165 ) -> Result<T, HgError> {
165 ) -> Result<T, HgError> {
166 self.map_err(|error| HgError::IoError {
166 self.map_err(|error| HgError::IoError {
167 error,
167 error,
168 context: context(),
168 context: context(),
169 })
169 })
170 }
170 }
171 }
171 }
172
172
173 pub trait HgResultExt<T> {
173 pub trait HgResultExt<T> {
174 /// Handle missing files separately from other I/O error cases.
174 /// Handle missing files separately from other I/O error cases.
175 ///
175 ///
176 /// Wraps the `Ok` type in an `Option`:
176 /// Wraps the `Ok` type in an `Option`:
177 ///
177 ///
178 /// * `Ok(x)` becomes `Ok(Some(x))`
178 /// * `Ok(x)` becomes `Ok(Some(x))`
179 /// * An I/O "not found" error becomes `Ok(None)`
179 /// * An I/O "not found" error becomes `Ok(None)`
180 /// * Other errors are unchanged
180 /// * Other errors are unchanged
181 fn io_not_found_as_none(self) -> Result<Option<T>, HgError>;
181 fn io_not_found_as_none(self) -> Result<Option<T>, HgError>;
182 }
182 }
183
183
184 impl<T> HgResultExt<T> for Result<T, HgError> {
184 impl<T> HgResultExt<T> for Result<T, HgError> {
185 fn io_not_found_as_none(self) -> Result<Option<T>, HgError> {
185 fn io_not_found_as_none(self) -> Result<Option<T>, HgError> {
186 match self {
186 match self {
187 Ok(x) => Ok(Some(x)),
187 Ok(x) => Ok(Some(x)),
188 Err(HgError::IoError { error, .. })
188 Err(HgError::IoError { error, .. })
189 if error.kind() == std::io::ErrorKind::NotFound =>
189 if error.kind() == std::io::ErrorKind::NotFound =>
190 {
190 {
191 Ok(None)
191 Ok(None)
192 }
192 }
193 Err(other_error) => Err(other_error),
193 Err(other_error) => Err(other_error),
194 }
194 }
195 }
195 }
196 }
196 }
@@ -1,266 +1,268 b''
1 use crate::config::{Config, ConfigError, ConfigParseError};
1 use crate::config::{Config, ConfigError, ConfigParseError};
2 use crate::errors::{HgError, IoErrorContext, IoResultExt};
2 use crate::errors::{HgError, IoErrorContext, IoResultExt};
3 use crate::requirements;
3 use crate::requirements;
4 use crate::utils::files::get_path_from_bytes;
4 use crate::utils::files::get_path_from_bytes;
5 use crate::utils::{current_dir, SliceExt};
5 use crate::utils::{current_dir, SliceExt};
6 use memmap::{Mmap, MmapOptions};
6 use memmap::{Mmap, MmapOptions};
7 use std::collections::HashSet;
7 use std::collections::HashSet;
8 use std::path::{Path, PathBuf};
8 use std::path::{Path, PathBuf};
9
9
10 /// A repository on disk
10 /// A repository on disk
11 pub struct Repo {
11 pub struct Repo {
12 working_directory: PathBuf,
12 working_directory: PathBuf,
13 dot_hg: PathBuf,
13 dot_hg: PathBuf,
14 store: PathBuf,
14 store: PathBuf,
15 requirements: HashSet<String>,
15 requirements: HashSet<String>,
16 config: Config,
16 config: Config,
17 }
17 }
18
18
19 #[derive(Debug, derive_more::From)]
19 #[derive(Debug, derive_more::From)]
20 pub enum RepoError {
20 pub enum RepoError {
21 NotFound {
21 NotFound {
22 at: PathBuf,
22 at: PathBuf,
23 },
23 },
24 #[from]
24 #[from]
25 ConfigParseError(ConfigParseError),
25 ConfigParseError(ConfigParseError),
26 #[from]
26 #[from]
27 Other(HgError),
27 Other(HgError),
28 }
28 }
29
29
30 impl From<ConfigError> for RepoError {
30 impl From<ConfigError> for RepoError {
31 fn from(error: ConfigError) -> Self {
31 fn from(error: ConfigError) -> Self {
32 match error {
32 match error {
33 ConfigError::Parse(error) => error.into(),
33 ConfigError::Parse(error) => error.into(),
34 ConfigError::Other(error) => error.into(),
34 ConfigError::Other(error) => error.into(),
35 }
35 }
36 }
36 }
37 }
37 }
38
38
39 /// Filesystem access abstraction for the contents of a given "base" diretory
39 /// Filesystem access abstraction for the contents of a given "base" diretory
40 #[derive(Clone, Copy)]
40 #[derive(Clone, Copy)]
41 pub struct Vfs<'a> {
41 pub struct Vfs<'a> {
42 pub(crate) base: &'a Path,
42 pub(crate) base: &'a Path,
43 }
43 }
44
44
45 impl Repo {
45 impl Repo {
46 /// Find a repository, either at the given path (which must contain a `.hg`
46 /// Find a repository, either at the given path (which must contain a `.hg`
47 /// sub-directory) or by searching the current directory and its
47 /// sub-directory) or by searching the current directory and its
48 /// ancestors.
48 /// ancestors.
49 ///
49 ///
50 /// A method with two very different "modes" like this usually a code smell
50 /// A method with two very different "modes" like this usually a code smell
51 /// to make two methods instead, but in this case an `Option` is what rhg
51 /// to make two methods instead, but in this case an `Option` is what rhg
52 /// sub-commands get from Clap for the `-R` / `--repository` CLI argument.
52 /// sub-commands get from Clap for the `-R` / `--repository` CLI argument.
53 /// Having two methods would just move that `if` to almost all callers.
53 /// Having two methods would just move that `if` to almost all callers.
54 pub fn find(
54 pub fn find(
55 config: &Config,
55 config: &Config,
56 explicit_path: Option<&Path>,
56 explicit_path: Option<&Path>,
57 ) -> Result<Self, RepoError> {
57 ) -> Result<Self, RepoError> {
58 if let Some(root) = explicit_path {
58 if let Some(root) = explicit_path {
59 // Having an absolute path isn’t necessary here but can help code
59 // Having an absolute path isn’t necessary here but can help code
60 // elsewhere
60 // elsewhere
61 let absolute_root = current_dir()?.join(root);
61 let absolute_root = current_dir()?.join(root);
62 if absolute_root.join(".hg").is_dir() {
62 if absolute_root.join(".hg").is_dir() {
63 Self::new_at_path(absolute_root, config)
63 Self::new_at_path(absolute_root, config)
64 } else if absolute_root.is_file() {
64 } else if absolute_root.is_file() {
65 Err(HgError::unsupported("bundle repository").into())
65 Err(HgError::unsupported("bundle repository").into())
66 } else {
66 } else {
67 Err(RepoError::NotFound {
67 Err(RepoError::NotFound {
68 at: root.to_owned(),
68 at: root.to_owned(),
69 })
69 })
70 }
70 }
71 } else {
71 } else {
72 let current_directory = crate::utils::current_dir()?;
72 let current_directory = crate::utils::current_dir()?;
73 // ancestors() is inclusive: it first yields `current_directory`
73 // ancestors() is inclusive: it first yields `current_directory`
74 // as-is.
74 // as-is.
75 for ancestor in current_directory.ancestors() {
75 for ancestor in current_directory.ancestors() {
76 if ancestor.join(".hg").is_dir() {
76 if ancestor.join(".hg").is_dir() {
77 return Self::new_at_path(ancestor.to_owned(), config);
77 return Self::new_at_path(ancestor.to_owned(), config);
78 }
78 }
79 }
79 }
80 Err(RepoError::NotFound {
80 Err(RepoError::NotFound {
81 at: current_directory,
81 at: current_directory,
82 })
82 })
83 }
83 }
84 }
84 }
85
85
86 /// To be called after checking that `.hg` is a sub-directory
86 /// To be called after checking that `.hg` is a sub-directory
87 fn new_at_path(
87 fn new_at_path(
88 working_directory: PathBuf,
88 working_directory: PathBuf,
89 config: &Config,
89 config: &Config,
90 ) -> Result<Self, RepoError> {
90 ) -> Result<Self, RepoError> {
91 let dot_hg = working_directory.join(".hg");
91 let dot_hg = working_directory.join(".hg");
92
92
93 let mut repo_config_files = Vec::new();
93 let mut repo_config_files = Vec::new();
94 repo_config_files.push(dot_hg.join("hgrc"));
94 repo_config_files.push(dot_hg.join("hgrc"));
95 repo_config_files.push(dot_hg.join("hgrc-not-shared"));
95 repo_config_files.push(dot_hg.join("hgrc-not-shared"));
96
96
97 let hg_vfs = Vfs { base: &dot_hg };
97 let hg_vfs = Vfs { base: &dot_hg };
98 let mut reqs = requirements::load_if_exists(hg_vfs)?;
98 let mut reqs = requirements::load_if_exists(hg_vfs)?;
99 let relative =
99 let relative =
100 reqs.contains(requirements::RELATIVE_SHARED_REQUIREMENT);
100 reqs.contains(requirements::RELATIVE_SHARED_REQUIREMENT);
101 let shared =
101 let shared =
102 reqs.contains(requirements::SHARED_REQUIREMENT) || relative;
102 reqs.contains(requirements::SHARED_REQUIREMENT) || relative;
103
103
104 // From `mercurial/localrepo.py`:
104 // From `mercurial/localrepo.py`:
105 //
105 //
106 // if .hg/requires contains the sharesafe requirement, it means
106 // if .hg/requires contains the sharesafe requirement, it means
107 // there exists a `.hg/store/requires` too and we should read it
107 // there exists a `.hg/store/requires` too and we should read it
108 // NOTE: presence of SHARESAFE_REQUIREMENT imply that store requirement
108 // NOTE: presence of SHARESAFE_REQUIREMENT imply that store requirement
109 // is present. We never write SHARESAFE_REQUIREMENT for a repo if store
109 // is present. We never write SHARESAFE_REQUIREMENT for a repo if store
110 // is not present, refer checkrequirementscompat() for that
110 // is not present, refer checkrequirementscompat() for that
111 //
111 //
112 // However, if SHARESAFE_REQUIREMENT is not present, it means that the
112 // However, if SHARESAFE_REQUIREMENT is not present, it means that the
113 // repository was shared the old way. We check the share source
113 // repository was shared the old way. We check the share source
114 // .hg/requires for SHARESAFE_REQUIREMENT to detect whether the
114 // .hg/requires for SHARESAFE_REQUIREMENT to detect whether the
115 // current repository needs to be reshared
115 // current repository needs to be reshared
116 let share_safe = reqs.contains(requirements::SHARESAFE_REQUIREMENT);
116 let share_safe = reqs.contains(requirements::SHARESAFE_REQUIREMENT);
117
117
118 let store_path;
118 let store_path;
119 if !shared {
119 if !shared {
120 store_path = dot_hg.join("store");
120 store_path = dot_hg.join("store");
121 } else {
121 } else {
122 let bytes = hg_vfs.read("sharedpath")?;
122 let bytes = hg_vfs.read("sharedpath")?;
123 let mut shared_path =
123 let mut shared_path =
124 get_path_from_bytes(bytes.trim_end_newlines()).to_owned();
124 get_path_from_bytes(bytes.trim_end_newlines()).to_owned();
125 if relative {
125 if relative {
126 shared_path = dot_hg.join(shared_path)
126 shared_path = dot_hg.join(shared_path)
127 }
127 }
128 if !shared_path.is_dir() {
128 if !shared_path.is_dir() {
129 return Err(HgError::corrupted(format!(
129 return Err(HgError::corrupted(format!(
130 ".hg/sharedpath points to nonexistent directory {}",
130 ".hg/sharedpath points to nonexistent directory {}",
131 shared_path.display()
131 shared_path.display()
132 ))
132 ))
133 .into());
133 .into());
134 }
134 }
135
135
136 store_path = shared_path.join("store");
136 store_path = shared_path.join("store");
137
137
138 let source_is_share_safe =
138 let source_is_share_safe =
139 requirements::load(Vfs { base: &shared_path })?
139 requirements::load(Vfs { base: &shared_path })?
140 .contains(requirements::SHARESAFE_REQUIREMENT);
140 .contains(requirements::SHARESAFE_REQUIREMENT);
141
141
142 if share_safe && !source_is_share_safe {
142 if share_safe && !source_is_share_safe {
143 return Err(match config
143 return Err(match config
144 .get(b"safe-mismatch", b"source-not-safe")
144 .get(b"share", b"safe-mismatch.source-not-safe")
145 {
145 {
146 Some(b"abort") | None => HgError::abort(
146 Some(b"abort") | None => HgError::abort(
147 "share source does not support share-safe requirement",
147 "abort: share source does not support share-safe requirement\n\
148 (see `hg help config.format.use-share-safe` for more information)",
148 ),
149 ),
149 _ => HgError::unsupported("share-safe downgrade"),
150 _ => HgError::unsupported("share-safe downgrade"),
150 }
151 }
151 .into());
152 .into());
152 } else if source_is_share_safe && !share_safe {
153 } else if source_is_share_safe && !share_safe {
153 return Err(
154 return Err(
154 match config.get(b"safe-mismatch", b"source-safe") {
155 match config.get(b"share", b"safe-mismatch.source-safe") {
155 Some(b"abort") | None => HgError::abort(
156 Some(b"abort") | None => HgError::abort(
156 "version mismatch: source uses share-safe \
157 "abort: version mismatch: source uses share-safe \
157 functionality while the current share does not",
158 functionality while the current share does not\n\
159 (see `hg help config.format.use-share-safe` for more information)",
158 ),
160 ),
159 _ => HgError::unsupported("share-safe upgrade"),
161 _ => HgError::unsupported("share-safe upgrade"),
160 }
162 }
161 .into(),
163 .into(),
162 );
164 );
163 }
165 }
164
166
165 if share_safe {
167 if share_safe {
166 repo_config_files.insert(0, shared_path.join("hgrc"))
168 repo_config_files.insert(0, shared_path.join("hgrc"))
167 }
169 }
168 }
170 }
169 if share_safe {
171 if share_safe {
170 reqs.extend(requirements::load(Vfs { base: &store_path })?);
172 reqs.extend(requirements::load(Vfs { base: &store_path })?);
171 }
173 }
172
174
173 let repo_config = config.combine_with_repo(&repo_config_files)?;
175 let repo_config = config.combine_with_repo(&repo_config_files)?;
174
176
175 let repo = Self {
177 let repo = Self {
176 requirements: reqs,
178 requirements: reqs,
177 working_directory,
179 working_directory,
178 store: store_path,
180 store: store_path,
179 dot_hg,
181 dot_hg,
180 config: repo_config,
182 config: repo_config,
181 };
183 };
182
184
183 requirements::check(&repo)?;
185 requirements::check(&repo)?;
184
186
185 Ok(repo)
187 Ok(repo)
186 }
188 }
187
189
188 pub fn working_directory_path(&self) -> &Path {
190 pub fn working_directory_path(&self) -> &Path {
189 &self.working_directory
191 &self.working_directory
190 }
192 }
191
193
192 pub fn requirements(&self) -> &HashSet<String> {
194 pub fn requirements(&self) -> &HashSet<String> {
193 &self.requirements
195 &self.requirements
194 }
196 }
195
197
196 pub fn config(&self) -> &Config {
198 pub fn config(&self) -> &Config {
197 &self.config
199 &self.config
198 }
200 }
199
201
200 /// For accessing repository files (in `.hg`), except for the store
202 /// For accessing repository files (in `.hg`), except for the store
201 /// (`.hg/store`).
203 /// (`.hg/store`).
202 pub fn hg_vfs(&self) -> Vfs<'_> {
204 pub fn hg_vfs(&self) -> Vfs<'_> {
203 Vfs { base: &self.dot_hg }
205 Vfs { base: &self.dot_hg }
204 }
206 }
205
207
206 /// For accessing repository store files (in `.hg/store`)
208 /// For accessing repository store files (in `.hg/store`)
207 pub fn store_vfs(&self) -> Vfs<'_> {
209 pub fn store_vfs(&self) -> Vfs<'_> {
208 Vfs { base: &self.store }
210 Vfs { base: &self.store }
209 }
211 }
210
212
211 /// For accessing the working copy
213 /// For accessing the working copy
212
214
213 // The undescore prefix silences the "never used" warning. Remove before
215 // The undescore prefix silences the "never used" warning. Remove before
214 // using.
216 // using.
215 pub fn _working_directory_vfs(&self) -> Vfs<'_> {
217 pub fn _working_directory_vfs(&self) -> Vfs<'_> {
216 Vfs {
218 Vfs {
217 base: &self.working_directory,
219 base: &self.working_directory,
218 }
220 }
219 }
221 }
220
222
221 pub fn dirstate_parents(
223 pub fn dirstate_parents(
222 &self,
224 &self,
223 ) -> Result<crate::dirstate::DirstateParents, HgError> {
225 ) -> Result<crate::dirstate::DirstateParents, HgError> {
224 let dirstate = self.hg_vfs().mmap_open("dirstate")?;
226 let dirstate = self.hg_vfs().mmap_open("dirstate")?;
225 let parents =
227 let parents =
226 crate::dirstate::parsers::parse_dirstate_parents(&dirstate)?;
228 crate::dirstate::parsers::parse_dirstate_parents(&dirstate)?;
227 Ok(parents.clone())
229 Ok(parents.clone())
228 }
230 }
229 }
231 }
230
232
231 impl Vfs<'_> {
233 impl Vfs<'_> {
232 pub fn join(&self, relative_path: impl AsRef<Path>) -> PathBuf {
234 pub fn join(&self, relative_path: impl AsRef<Path>) -> PathBuf {
233 self.base.join(relative_path)
235 self.base.join(relative_path)
234 }
236 }
235
237
236 pub fn read(
238 pub fn read(
237 &self,
239 &self,
238 relative_path: impl AsRef<Path>,
240 relative_path: impl AsRef<Path>,
239 ) -> Result<Vec<u8>, HgError> {
241 ) -> Result<Vec<u8>, HgError> {
240 let path = self.join(relative_path);
242 let path = self.join(relative_path);
241 std::fs::read(&path).when_reading_file(&path)
243 std::fs::read(&path).when_reading_file(&path)
242 }
244 }
243
245
244 pub fn mmap_open(
246 pub fn mmap_open(
245 &self,
247 &self,
246 relative_path: impl AsRef<Path>,
248 relative_path: impl AsRef<Path>,
247 ) -> Result<Mmap, HgError> {
249 ) -> Result<Mmap, HgError> {
248 let path = self.base.join(relative_path);
250 let path = self.base.join(relative_path);
249 let file = std::fs::File::open(&path).when_reading_file(&path)?;
251 let file = std::fs::File::open(&path).when_reading_file(&path)?;
250 // TODO: what are the safety requirements here?
252 // TODO: what are the safety requirements here?
251 let mmap = unsafe { MmapOptions::new().map(&file) }
253 let mmap = unsafe { MmapOptions::new().map(&file) }
252 .when_reading_file(&path)?;
254 .when_reading_file(&path)?;
253 Ok(mmap)
255 Ok(mmap)
254 }
256 }
255
257
256 pub fn rename(
258 pub fn rename(
257 &self,
259 &self,
258 relative_from: impl AsRef<Path>,
260 relative_from: impl AsRef<Path>,
259 relative_to: impl AsRef<Path>,
261 relative_to: impl AsRef<Path>,
260 ) -> Result<(), HgError> {
262 ) -> Result<(), HgError> {
261 let from = self.join(relative_from);
263 let from = self.join(relative_from);
262 let to = self.join(relative_to);
264 let to = self.join(relative_to);
263 std::fs::rename(&from, &to)
265 std::fs::rename(&from, &to)
264 .with_context(|| IoErrorContext::RenamingFile { from, to })
266 .with_context(|| IoErrorContext::RenamingFile { from, to })
265 }
267 }
266 }
268 }
@@ -1,143 +1,143 b''
1 use crate::ui::utf8_to_local;
1 use crate::ui::utf8_to_local;
2 use crate::ui::UiError;
2 use crate::ui::UiError;
3 use crate::NoRepoInCwdError;
3 use crate::NoRepoInCwdError;
4 use format_bytes::format_bytes;
4 use format_bytes::format_bytes;
5 use hg::config::{ConfigError, ConfigParseError};
5 use hg::config::{ConfigError, ConfigParseError};
6 use hg::errors::HgError;
6 use hg::errors::HgError;
7 use hg::repo::RepoError;
7 use hg::repo::RepoError;
8 use hg::revlog::revlog::RevlogError;
8 use hg::revlog::revlog::RevlogError;
9 use hg::utils::files::get_bytes_from_path;
9 use hg::utils::files::get_bytes_from_path;
10 use std::convert::From;
10 use std::convert::From;
11
11
12 /// The kind of command error
12 /// The kind of command error
13 #[derive(Debug)]
13 #[derive(Debug)]
14 pub enum CommandError {
14 pub enum CommandError {
15 /// Exit with an error message and "standard" failure exit code.
15 /// Exit with an error message and "standard" failure exit code.
16 Abort { message: Vec<u8> },
16 Abort { message: Vec<u8> },
17
17
18 /// Encountered something (such as a CLI argument, repository layout, …)
18 /// Encountered something (such as a CLI argument, repository layout, …)
19 /// not supported by this version of `rhg`. Depending on configuration
19 /// not supported by this version of `rhg`. Depending on configuration
20 /// `rhg` may attempt to silently fall back to Python-based `hg`, which
20 /// `rhg` may attempt to silently fall back to Python-based `hg`, which
21 /// may or may not support this feature.
21 /// may or may not support this feature.
22 UnsupportedFeature { message: Vec<u8> },
22 UnsupportedFeature { message: Vec<u8> },
23 }
23 }
24
24
25 impl CommandError {
25 impl CommandError {
26 pub fn abort(message: impl AsRef<str>) -> Self {
26 pub fn abort(message: impl AsRef<str>) -> Self {
27 CommandError::Abort {
27 CommandError::Abort {
28 // TODO: bytes-based (instead of Unicode-based) formatting
28 // TODO: bytes-based (instead of Unicode-based) formatting
29 // of error messages to handle non-UTF-8 filenames etc:
29 // of error messages to handle non-UTF-8 filenames etc:
30 // https://www.mercurial-scm.org/wiki/EncodingStrategy#Mixing_output
30 // https://www.mercurial-scm.org/wiki/EncodingStrategy#Mixing_output
31 message: utf8_to_local(message.as_ref()).into(),
31 message: utf8_to_local(message.as_ref()).into(),
32 }
32 }
33 }
33 }
34
34
35 pub fn unsupported(message: impl AsRef<str>) -> Self {
35 pub fn unsupported(message: impl AsRef<str>) -> Self {
36 CommandError::UnsupportedFeature {
36 CommandError::UnsupportedFeature {
37 message: utf8_to_local(message.as_ref()).into(),
37 message: utf8_to_local(message.as_ref()).into(),
38 }
38 }
39 }
39 }
40 }
40 }
41
41
42 /// For now we don’t differenciate between invalid CLI args and valid for `hg`
42 /// For now we don’t differenciate between invalid CLI args and valid for `hg`
43 /// but not supported yet by `rhg`.
43 /// but not supported yet by `rhg`.
44 impl From<clap::Error> for CommandError {
44 impl From<clap::Error> for CommandError {
45 fn from(error: clap::Error) -> Self {
45 fn from(error: clap::Error) -> Self {
46 CommandError::unsupported(error.to_string())
46 CommandError::unsupported(error.to_string())
47 }
47 }
48 }
48 }
49
49
50 impl From<HgError> for CommandError {
50 impl From<HgError> for CommandError {
51 fn from(error: HgError) -> Self {
51 fn from(error: HgError) -> Self {
52 match error {
52 match error {
53 HgError::UnsupportedFeature(message) => {
53 HgError::UnsupportedFeature(message) => {
54 CommandError::unsupported(message)
54 CommandError::unsupported(message)
55 }
55 }
56 _ => CommandError::abort(error.to_string()),
56 _ => CommandError::abort(error.to_string()),
57 }
57 }
58 }
58 }
59 }
59 }
60
60
61 impl From<UiError> for CommandError {
61 impl From<UiError> for CommandError {
62 fn from(_error: UiError) -> Self {
62 fn from(_error: UiError) -> Self {
63 // If we already failed writing to stdout or stderr,
63 // If we already failed writing to stdout or stderr,
64 // writing an error message to stderr about it would be likely to fail
64 // writing an error message to stderr about it would be likely to fail
65 // too.
65 // too.
66 CommandError::abort("")
66 CommandError::abort("")
67 }
67 }
68 }
68 }
69
69
70 impl From<RepoError> for CommandError {
70 impl From<RepoError> for CommandError {
71 fn from(error: RepoError) -> Self {
71 fn from(error: RepoError) -> Self {
72 match error {
72 match error {
73 RepoError::NotFound { at } => CommandError::Abort {
73 RepoError::NotFound { at } => CommandError::Abort {
74 message: format_bytes!(
74 message: format_bytes!(
75 b"repository {} not found",
75 b"abort: repository {} not found",
76 get_bytes_from_path(at)
76 get_bytes_from_path(at)
77 ),
77 ),
78 },
78 },
79 RepoError::ConfigParseError(error) => error.into(),
79 RepoError::ConfigParseError(error) => error.into(),
80 RepoError::Other(error) => error.into(),
80 RepoError::Other(error) => error.into(),
81 }
81 }
82 }
82 }
83 }
83 }
84
84
85 impl<'a> From<&'a NoRepoInCwdError> for CommandError {
85 impl<'a> From<&'a NoRepoInCwdError> for CommandError {
86 fn from(error: &'a NoRepoInCwdError) -> Self {
86 fn from(error: &'a NoRepoInCwdError) -> Self {
87 let NoRepoInCwdError { cwd } = error;
87 let NoRepoInCwdError { cwd } = error;
88 CommandError::Abort {
88 CommandError::Abort {
89 message: format_bytes!(
89 message: format_bytes!(
90 b"abort: no repository found in '{}' (.hg not found)!",
90 b"abort: no repository found in '{}' (.hg not found)!",
91 get_bytes_from_path(cwd)
91 get_bytes_from_path(cwd)
92 ),
92 ),
93 }
93 }
94 }
94 }
95 }
95 }
96
96
97 impl From<ConfigError> for CommandError {
97 impl From<ConfigError> for CommandError {
98 fn from(error: ConfigError) -> Self {
98 fn from(error: ConfigError) -> Self {
99 match error {
99 match error {
100 ConfigError::Parse(error) => error.into(),
100 ConfigError::Parse(error) => error.into(),
101 ConfigError::Other(error) => error.into(),
101 ConfigError::Other(error) => error.into(),
102 }
102 }
103 }
103 }
104 }
104 }
105
105
106 impl From<ConfigParseError> for CommandError {
106 impl From<ConfigParseError> for CommandError {
107 fn from(error: ConfigParseError) -> Self {
107 fn from(error: ConfigParseError) -> Self {
108 let ConfigParseError {
108 let ConfigParseError {
109 origin,
109 origin,
110 line,
110 line,
111 message,
111 message,
112 } = error;
112 } = error;
113 let line_message = if let Some(line_number) = line {
113 let line_message = if let Some(line_number) = line {
114 format_bytes!(b":{}", line_number.to_string().into_bytes())
114 format_bytes!(b":{}", line_number.to_string().into_bytes())
115 } else {
115 } else {
116 Vec::new()
116 Vec::new()
117 };
117 };
118 CommandError::Abort {
118 CommandError::Abort {
119 message: format_bytes!(
119 message: format_bytes!(
120 b"config error at {}{}: {}",
120 b"config error at {}{}: {}",
121 origin,
121 origin,
122 line_message,
122 line_message,
123 message
123 message
124 ),
124 ),
125 }
125 }
126 }
126 }
127 }
127 }
128
128
129 impl From<(RevlogError, &str)> for CommandError {
129 impl From<(RevlogError, &str)> for CommandError {
130 fn from((err, rev): (RevlogError, &str)) -> CommandError {
130 fn from((err, rev): (RevlogError, &str)) -> CommandError {
131 match err {
131 match err {
132 RevlogError::InvalidRevision => CommandError::abort(format!(
132 RevlogError::InvalidRevision => CommandError::abort(format!(
133 "abort: invalid revision identifier: {}",
133 "abort: invalid revision identifier: {}",
134 rev
134 rev
135 )),
135 )),
136 RevlogError::AmbiguousPrefix => CommandError::abort(format!(
136 RevlogError::AmbiguousPrefix => CommandError::abort(format!(
137 "abort: ambiguous revision identifier: {}",
137 "abort: ambiguous revision identifier: {}",
138 rev
138 rev
139 )),
139 )),
140 RevlogError::Other(error) => error.into(),
140 RevlogError::Other(error) => error.into(),
141 }
141 }
142 }
142 }
143 }
143 }
@@ -1,299 +1,299 b''
1 #require rhg
1 #require rhg
2
2
3 $ NO_FALLBACK="env RHG_ON_UNSUPPORTED=abort"
3 $ NO_FALLBACK="env RHG_ON_UNSUPPORTED=abort"
4
4
5 Unimplemented command
5 Unimplemented command
6 $ $NO_FALLBACK rhg unimplemented-command
6 $ $NO_FALLBACK rhg unimplemented-command
7 unsupported feature: error: Found argument 'unimplemented-command' which wasn't expected, or isn't valid in this context
7 unsupported feature: error: Found argument 'unimplemented-command' which wasn't expected, or isn't valid in this context
8
8
9 USAGE:
9 USAGE:
10 rhg [OPTIONS] <SUBCOMMAND>
10 rhg [OPTIONS] <SUBCOMMAND>
11
11
12 For more information try --help
12 For more information try --help
13
13
14 [252]
14 [252]
15 $ rhg unimplemented-command --config rhg.on-unsupported=abort-silent
15 $ rhg unimplemented-command --config rhg.on-unsupported=abort-silent
16 [252]
16 [252]
17
17
18 Finding root
18 Finding root
19 $ $NO_FALLBACK rhg root
19 $ $NO_FALLBACK rhg root
20 abort: no repository found in '$TESTTMP' (.hg not found)!
20 abort: no repository found in '$TESTTMP' (.hg not found)!
21 [255]
21 [255]
22
22
23 $ hg init repository
23 $ hg init repository
24 $ cd repository
24 $ cd repository
25 $ $NO_FALLBACK rhg root
25 $ $NO_FALLBACK rhg root
26 $TESTTMP/repository
26 $TESTTMP/repository
27
27
28 Reading and setting configuration
28 Reading and setting configuration
29 $ echo "[ui]" >> $HGRCPATH
29 $ echo "[ui]" >> $HGRCPATH
30 $ echo "username = user1" >> $HGRCPATH
30 $ echo "username = user1" >> $HGRCPATH
31 $ $NO_FALLBACK rhg config ui.username
31 $ $NO_FALLBACK rhg config ui.username
32 user1
32 user1
33 $ echo "[ui]" >> .hg/hgrc
33 $ echo "[ui]" >> .hg/hgrc
34 $ echo "username = user2" >> .hg/hgrc
34 $ echo "username = user2" >> .hg/hgrc
35 $ $NO_FALLBACK rhg config ui.username
35 $ $NO_FALLBACK rhg config ui.username
36 user2
36 user2
37 $ $NO_FALLBACK rhg --config ui.username=user3 config ui.username
37 $ $NO_FALLBACK rhg --config ui.username=user3 config ui.username
38 user3
38 user3
39
39
40 Unwritable file descriptor
40 Unwritable file descriptor
41 $ $NO_FALLBACK rhg root > /dev/full
41 $ $NO_FALLBACK rhg root > /dev/full
42 abort: No space left on device (os error 28)
42 abort: No space left on device (os error 28)
43 [255]
43 [255]
44
44
45 Deleted repository
45 Deleted repository
46 $ rm -rf `pwd`
46 $ rm -rf `pwd`
47 $ $NO_FALLBACK rhg root
47 $ $NO_FALLBACK rhg root
48 abort: error getting current working directory: $ENOENT$
48 abort: error getting current working directory: $ENOENT$
49 [255]
49 [255]
50
50
51 Listing tracked files
51 Listing tracked files
52 $ cd $TESTTMP
52 $ cd $TESTTMP
53 $ hg init repository
53 $ hg init repository
54 $ cd repository
54 $ cd repository
55 $ for i in 1 2 3; do
55 $ for i in 1 2 3; do
56 > echo $i >> file$i
56 > echo $i >> file$i
57 > hg add file$i
57 > hg add file$i
58 > done
58 > done
59 > hg commit -m "commit $i" -q
59 > hg commit -m "commit $i" -q
60
60
61 Listing tracked files from root
61 Listing tracked files from root
62 $ $NO_FALLBACK rhg files
62 $ $NO_FALLBACK rhg files
63 file1
63 file1
64 file2
64 file2
65 file3
65 file3
66
66
67 Listing tracked files from subdirectory
67 Listing tracked files from subdirectory
68 $ mkdir -p path/to/directory
68 $ mkdir -p path/to/directory
69 $ cd path/to/directory
69 $ cd path/to/directory
70 $ $NO_FALLBACK rhg files
70 $ $NO_FALLBACK rhg files
71 ../../../file1
71 ../../../file1
72 ../../../file2
72 ../../../file2
73 ../../../file3
73 ../../../file3
74
74
75 Listing tracked files through broken pipe
75 Listing tracked files through broken pipe
76 $ $NO_FALLBACK rhg files | head -n 1
76 $ $NO_FALLBACK rhg files | head -n 1
77 ../../../file1
77 ../../../file1
78
78
79 Debuging data in inline index
79 Debuging data in inline index
80 $ cd $TESTTMP
80 $ cd $TESTTMP
81 $ rm -rf repository
81 $ rm -rf repository
82 $ hg init repository
82 $ hg init repository
83 $ cd repository
83 $ cd repository
84 $ for i in 1 2 3 4 5 6; do
84 $ for i in 1 2 3 4 5 6; do
85 > echo $i >> file-$i
85 > echo $i >> file-$i
86 > hg add file-$i
86 > hg add file-$i
87 > hg commit -m "Commit $i" -q
87 > hg commit -m "Commit $i" -q
88 > done
88 > done
89 $ $NO_FALLBACK rhg debugdata -c 2
89 $ $NO_FALLBACK rhg debugdata -c 2
90 8d0267cb034247ebfa5ee58ce59e22e57a492297
90 8d0267cb034247ebfa5ee58ce59e22e57a492297
91 test
91 test
92 0 0
92 0 0
93 file-3
93 file-3
94
94
95 Commit 3 (no-eol)
95 Commit 3 (no-eol)
96 $ $NO_FALLBACK rhg debugdata -m 2
96 $ $NO_FALLBACK rhg debugdata -m 2
97 file-1\x00b8e02f6433738021a065f94175c7cd23db5f05be (esc)
97 file-1\x00b8e02f6433738021a065f94175c7cd23db5f05be (esc)
98 file-2\x005d9299349fc01ddd25d0070d149b124d8f10411e (esc)
98 file-2\x005d9299349fc01ddd25d0070d149b124d8f10411e (esc)
99 file-3\x002661d26c649684b482d10f91960cc3db683c38b4 (esc)
99 file-3\x002661d26c649684b482d10f91960cc3db683c38b4 (esc)
100
100
101 Debuging with full node id
101 Debuging with full node id
102 $ $NO_FALLBACK rhg debugdata -c `hg log -r 0 -T '{node}'`
102 $ $NO_FALLBACK rhg debugdata -c `hg log -r 0 -T '{node}'`
103 d1d1c679d3053e8926061b6f45ca52009f011e3f
103 d1d1c679d3053e8926061b6f45ca52009f011e3f
104 test
104 test
105 0 0
105 0 0
106 file-1
106 file-1
107
107
108 Commit 1 (no-eol)
108 Commit 1 (no-eol)
109
109
110 Specifying revisions by changeset ID
110 Specifying revisions by changeset ID
111 $ hg log -T '{node}\n'
111 $ hg log -T '{node}\n'
112 c6ad58c44207b6ff8a4fbbca7045a5edaa7e908b
112 c6ad58c44207b6ff8a4fbbca7045a5edaa7e908b
113 d654274993d0149eecc3cc03214f598320211900
113 d654274993d0149eecc3cc03214f598320211900
114 f646af7e96481d3a5470b695cf30ad8e3ab6c575
114 f646af7e96481d3a5470b695cf30ad8e3ab6c575
115 cf8b83f14ead62b374b6e91a0e9303b85dfd9ed7
115 cf8b83f14ead62b374b6e91a0e9303b85dfd9ed7
116 91c6f6e73e39318534dc415ea4e8a09c99cd74d6
116 91c6f6e73e39318534dc415ea4e8a09c99cd74d6
117 6ae9681c6d30389694d8701faf24b583cf3ccafe
117 6ae9681c6d30389694d8701faf24b583cf3ccafe
118 $ $NO_FALLBACK rhg files -r cf8b83
118 $ $NO_FALLBACK rhg files -r cf8b83
119 file-1
119 file-1
120 file-2
120 file-2
121 file-3
121 file-3
122 $ $NO_FALLBACK rhg cat -r cf8b83 file-2
122 $ $NO_FALLBACK rhg cat -r cf8b83 file-2
123 2
123 2
124 $ $NO_FALLBACK rhg cat -r c file-2
124 $ $NO_FALLBACK rhg cat -r c file-2
125 abort: ambiguous revision identifier: c
125 abort: ambiguous revision identifier: c
126 [255]
126 [255]
127 $ $NO_FALLBACK rhg cat -r d file-2
127 $ $NO_FALLBACK rhg cat -r d file-2
128 2
128 2
129
129
130 Cat files
130 Cat files
131 $ cd $TESTTMP
131 $ cd $TESTTMP
132 $ rm -rf repository
132 $ rm -rf repository
133 $ hg init repository
133 $ hg init repository
134 $ cd repository
134 $ cd repository
135 $ echo "original content" > original
135 $ echo "original content" > original
136 $ hg add original
136 $ hg add original
137 $ hg commit -m "add original" original
137 $ hg commit -m "add original" original
138 $ $NO_FALLBACK rhg cat -r 0 original
138 $ $NO_FALLBACK rhg cat -r 0 original
139 original content
139 original content
140 Cat copied file should not display copy metadata
140 Cat copied file should not display copy metadata
141 $ hg copy original copy_of_original
141 $ hg copy original copy_of_original
142 $ hg commit -m "add copy of original"
142 $ hg commit -m "add copy of original"
143 $ $NO_FALLBACK rhg cat -r 1 copy_of_original
143 $ $NO_FALLBACK rhg cat -r 1 copy_of_original
144 original content
144 original content
145
145
146 Fallback to Python
146 Fallback to Python
147 $ $NO_FALLBACK rhg cat original
147 $ $NO_FALLBACK rhg cat original
148 unsupported feature: `rhg cat` without `--rev` / `-r`
148 unsupported feature: `rhg cat` without `--rev` / `-r`
149 [252]
149 [252]
150 $ rhg cat original
150 $ rhg cat original
151 original content
151 original content
152
152
153 $ rhg cat original --config rhg.fallback-executable=false
153 $ rhg cat original --config rhg.fallback-executable=false
154 [1]
154 [1]
155
155
156 $ rhg cat original --config rhg.fallback-executable=hg-non-existent
156 $ rhg cat original --config rhg.fallback-executable=hg-non-existent
157 tried to fall back to a 'hg-non-existent' sub-process but got error $ENOENT$
157 tried to fall back to a 'hg-non-existent' sub-process but got error $ENOENT$
158 unsupported feature: `rhg cat` without `--rev` / `-r`
158 unsupported feature: `rhg cat` without `--rev` / `-r`
159 [252]
159 [252]
160
160
161 $ rhg cat original --config rhg.fallback-executable=rhg
161 $ rhg cat original --config rhg.fallback-executable=rhg
162 Blocking recursive fallback. The 'rhg.fallback-executable = rhg' config points to `rhg` itself.
162 Blocking recursive fallback. The 'rhg.fallback-executable = rhg' config points to `rhg` itself.
163 unsupported feature: `rhg cat` without `--rev` / `-r`
163 unsupported feature: `rhg cat` without `--rev` / `-r`
164 [252]
164 [252]
165
165
166 Requirements
166 Requirements
167 $ $NO_FALLBACK rhg debugrequirements
167 $ $NO_FALLBACK rhg debugrequirements
168 dotencode
168 dotencode
169 fncache
169 fncache
170 generaldelta
170 generaldelta
171 revlogv1
171 revlogv1
172 sparserevlog
172 sparserevlog
173 store
173 store
174
174
175 $ echo indoor-pool >> .hg/requires
175 $ echo indoor-pool >> .hg/requires
176 $ $NO_FALLBACK rhg files
176 $ $NO_FALLBACK rhg files
177 unsupported feature: repository requires feature unknown to this Mercurial: indoor-pool
177 unsupported feature: repository requires feature unknown to this Mercurial: indoor-pool
178 [252]
178 [252]
179
179
180 $ $NO_FALLBACK rhg cat -r 1 copy_of_original
180 $ $NO_FALLBACK rhg cat -r 1 copy_of_original
181 unsupported feature: repository requires feature unknown to this Mercurial: indoor-pool
181 unsupported feature: repository requires feature unknown to this Mercurial: indoor-pool
182 [252]
182 [252]
183
183
184 $ $NO_FALLBACK rhg debugrequirements
184 $ $NO_FALLBACK rhg debugrequirements
185 unsupported feature: repository requires feature unknown to this Mercurial: indoor-pool
185 unsupported feature: repository requires feature unknown to this Mercurial: indoor-pool
186 [252]
186 [252]
187
187
188 $ echo -e '\xFF' >> .hg/requires
188 $ echo -e '\xFF' >> .hg/requires
189 $ $NO_FALLBACK rhg debugrequirements
189 $ $NO_FALLBACK rhg debugrequirements
190 abort: corrupted repository: parse error in 'requires' file
190 abort: parse error in 'requires' file
191 [255]
191 [255]
192
192
193 Persistent nodemap
193 Persistent nodemap
194 $ cd $TESTTMP
194 $ cd $TESTTMP
195 $ rm -rf repository
195 $ rm -rf repository
196 $ hg init repository
196 $ hg init repository
197 $ cd repository
197 $ cd repository
198 $ $NO_FALLBACK rhg debugrequirements | grep nodemap
198 $ $NO_FALLBACK rhg debugrequirements | grep nodemap
199 [1]
199 [1]
200 $ hg debugbuilddag .+5000 --overwritten-file --config "storage.revlog.nodemap.mode=warn"
200 $ hg debugbuilddag .+5000 --overwritten-file --config "storage.revlog.nodemap.mode=warn"
201 $ hg id -r tip
201 $ hg id -r tip
202 c3ae8dec9fad tip
202 c3ae8dec9fad tip
203 $ ls .hg/store/00changelog*
203 $ ls .hg/store/00changelog*
204 .hg/store/00changelog.d
204 .hg/store/00changelog.d
205 .hg/store/00changelog.i
205 .hg/store/00changelog.i
206 $ $NO_FALLBACK rhg files -r c3ae8dec9fad
206 $ $NO_FALLBACK rhg files -r c3ae8dec9fad
207 of
207 of
208
208
209 $ cd $TESTTMP
209 $ cd $TESTTMP
210 $ rm -rf repository
210 $ rm -rf repository
211 $ hg --config format.use-persistent-nodemap=True init repository
211 $ hg --config format.use-persistent-nodemap=True init repository
212 $ cd repository
212 $ cd repository
213 $ $NO_FALLBACK rhg debugrequirements | grep nodemap
213 $ $NO_FALLBACK rhg debugrequirements | grep nodemap
214 persistent-nodemap
214 persistent-nodemap
215 $ hg debugbuilddag .+5000 --overwritten-file --config "storage.revlog.nodemap.mode=warn"
215 $ hg debugbuilddag .+5000 --overwritten-file --config "storage.revlog.nodemap.mode=warn"
216 $ hg id -r tip
216 $ hg id -r tip
217 c3ae8dec9fad tip
217 c3ae8dec9fad tip
218 $ ls .hg/store/00changelog*
218 $ ls .hg/store/00changelog*
219 .hg/store/00changelog-*.nd (glob)
219 .hg/store/00changelog-*.nd (glob)
220 .hg/store/00changelog.d
220 .hg/store/00changelog.d
221 .hg/store/00changelog.i
221 .hg/store/00changelog.i
222 .hg/store/00changelog.n
222 .hg/store/00changelog.n
223
223
224 Specifying revisions by changeset ID
224 Specifying revisions by changeset ID
225 $ $NO_FALLBACK rhg files -r c3ae8dec9fad
225 $ $NO_FALLBACK rhg files -r c3ae8dec9fad
226 of
226 of
227 $ $NO_FALLBACK rhg cat -r c3ae8dec9fad of
227 $ $NO_FALLBACK rhg cat -r c3ae8dec9fad of
228 r5000
228 r5000
229
229
230 Crate a shared repository
230 Crate a shared repository
231
231
232 $ echo "[extensions]" >> $HGRCPATH
232 $ echo "[extensions]" >> $HGRCPATH
233 $ echo "share = " >> $HGRCPATH
233 $ echo "share = " >> $HGRCPATH
234
234
235 $ cd $TESTTMP
235 $ cd $TESTTMP
236 $ hg init repo1
236 $ hg init repo1
237 $ echo a > repo1/a
237 $ echo a > repo1/a
238 $ hg -R repo1 commit -A -m'init'
238 $ hg -R repo1 commit -A -m'init'
239 adding a
239 adding a
240
240
241 $ hg share repo1 repo2
241 $ hg share repo1 repo2
242 updating working directory
242 updating working directory
243 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
243 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
244
244
245 And check that basic rhg commands work with sharing
245 And check that basic rhg commands work with sharing
246
246
247 $ $NO_FALLBACK rhg files -R repo2
247 $ $NO_FALLBACK rhg files -R repo2
248 repo2/a
248 repo2/a
249 $ $NO_FALLBACK rhg -R repo2 cat -r 0 repo2/a
249 $ $NO_FALLBACK rhg -R repo2 cat -r 0 repo2/a
250 a
250 a
251
251
252 Same with relative sharing
252 Same with relative sharing
253
253
254 $ hg share repo2 repo3 --relative
254 $ hg share repo2 repo3 --relative
255 updating working directory
255 updating working directory
256 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
256 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
257
257
258 $ $NO_FALLBACK rhg files -R repo3
258 $ $NO_FALLBACK rhg files -R repo3
259 repo3/a
259 repo3/a
260 $ $NO_FALLBACK rhg -R repo3 cat -r 0 repo3/a
260 $ $NO_FALLBACK rhg -R repo3 cat -r 0 repo3/a
261 a
261 a
262
262
263 Same with share-safe
263 Same with share-safe
264
264
265 $ echo "[format]" >> $HGRCPATH
265 $ echo "[format]" >> $HGRCPATH
266 $ echo "use-share-safe = True" >> $HGRCPATH
266 $ echo "use-share-safe = True" >> $HGRCPATH
267
267
268 $ cd $TESTTMP
268 $ cd $TESTTMP
269 $ hg init repo4
269 $ hg init repo4
270 $ cd repo4
270 $ cd repo4
271 $ echo a > a
271 $ echo a > a
272 $ hg commit -A -m'init'
272 $ hg commit -A -m'init'
273 adding a
273 adding a
274
274
275 $ cd ..
275 $ cd ..
276 $ hg share repo4 repo5
276 $ hg share repo4 repo5
277 updating working directory
277 updating working directory
278 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
278 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
279
279
280 And check that basic rhg commands work with sharing
280 And check that basic rhg commands work with sharing
281
281
282 $ cd repo5
282 $ cd repo5
283 $ $NO_FALLBACK rhg files
283 $ $NO_FALLBACK rhg files
284 a
284 a
285 $ $NO_FALLBACK rhg cat -r 0 a
285 $ $NO_FALLBACK rhg cat -r 0 a
286 a
286 a
287
287
288 The blackbox extension is supported
288 The blackbox extension is supported
289
289
290 $ echo "[extensions]" >> $HGRCPATH
290 $ echo "[extensions]" >> $HGRCPATH
291 $ echo "blackbox =" >> $HGRCPATH
291 $ echo "blackbox =" >> $HGRCPATH
292 $ echo "[blackbox]" >> $HGRCPATH
292 $ echo "[blackbox]" >> $HGRCPATH
293 $ echo "maxsize = 1" >> $HGRCPATH
293 $ echo "maxsize = 1" >> $HGRCPATH
294 $ $NO_FALLBACK rhg files > /dev/null
294 $ $NO_FALLBACK rhg files > /dev/null
295 $ cat .hg/blackbox.log
295 $ cat .hg/blackbox.log
296 ????/??/?? ??:??:??.??? * @d3873e73d99ef67873dac33fbcc66268d5d2b6f4 (*)> (rust) files exited 0 after 0.??? seconds (glob)
296 ????/??/?? ??:??:??.??? * @d3873e73d99ef67873dac33fbcc66268d5d2b6f4 (*)> (rust) files exited 0 after 0.??? seconds (glob)
297 $ cat .hg/blackbox.log.1
297 $ cat .hg/blackbox.log.1
298 ????/??/?? ??:??:??.??? * @d3873e73d99ef67873dac33fbcc66268d5d2b6f4 (*)> (rust) files (glob)
298 ????/??/?? ??:??:??.??? * @d3873e73d99ef67873dac33fbcc66268d5d2b6f4 (*)> (rust) files (glob)
299
299
General Comments 0
You need to be logged in to leave comments. Login now