Mercurial > hg
annotate rust/hg-core/src/requirements.rs @ 46167:8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
This is similar to the corresponding Python classes.
Repo represents a repository and knows the path to the `.hg` directory,
the `store` directory, and the working directory.
Separating these will enable supporting the share extension.
A Vfs is created from a Repo for one of these three directories.
It has filesystem access APIs that take a relative std::path::Path
as a parameter.
Differential Revision: https://phab.mercurial-scm.org/D9596
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Mon, 14 Dec 2020 16:33:15 +0100 |
parents | 9eb07ab3f2d4 |
children | 02d3bb972121 |
rev | line source |
---|---|
46167
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
46090
diff
changeset
|
1 use crate::repo::Repo; |
45924
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
2 use std::io; |
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
3 |
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
4 #[derive(Debug)] |
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
5 pub enum RequirementsError { |
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
6 // TODO: include a path? |
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
7 Io(io::Error), |
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
8 /// The `requires` file is corrupted |
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
9 Corrupted, |
45956
40f79997e81f
rust: fix non-utf8 char in requirements.rs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
45938
diff
changeset
|
10 /// The repository requires a feature that we don't support |
45924
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
11 Unsupported { |
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
12 feature: String, |
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
13 }, |
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
14 } |
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
15 |
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
16 fn parse(bytes: &[u8]) -> Result<Vec<String>, ()> { |
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
17 // The Python code reading this file uses `str.splitlines` |
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
18 // which looks for a number of line separators (even including a couple of |
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
19 // non-ASCII ones), but Python code writing it always uses `\n`. |
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
20 let lines = bytes.split(|&byte| byte == b'\n'); |
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
21 |
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
22 lines |
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
23 .filter(|line| !line.is_empty()) |
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
24 .map(|line| { |
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
25 // Python uses Unicode `str.isalnum` but feature names are all |
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
26 // ASCII |
45938
f5d62f4d5327
rhg: check that .hg/requires is ASCII
Simon Sapin <simon-commits@exyr.org>
parents:
45937
diff
changeset
|
27 if line[0].is_ascii_alphanumeric() && line.is_ascii() { |
45924
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
28 Ok(String::from_utf8(line.into()).unwrap()) |
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
29 } else { |
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
30 Err(()) |
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
31 } |
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
32 }) |
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
33 .collect() |
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
34 } |
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
35 |
46167
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
46090
diff
changeset
|
36 pub fn load(repo: &Repo) -> Result<Vec<String>, RequirementsError> { |
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
46090
diff
changeset
|
37 match repo.hg_vfs().read("requires") { |
45924
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
38 Ok(bytes) => parse(&bytes).map_err(|()| RequirementsError::Corrupted), |
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
39 |
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
40 // Treat a missing file the same as an empty file. |
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
41 // From `mercurial/localrepo.py`: |
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
42 // > requires file contains a newline-delimited list of |
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
43 // > features/capabilities the opener (us) must have in order to use |
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
44 // > the repository. This file was introduced in Mercurial 0.9.2, |
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
45 // > which means very old repositories may not have one. We assume |
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
46 // > a missing file translates to no requirements. |
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
47 Err(error) if error.kind() == std::io::ErrorKind::NotFound => { |
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
48 Ok(Vec::new()) |
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
49 } |
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
50 |
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
51 Err(error) => Err(RequirementsError::Io(error))?, |
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
52 } |
a2eda1ff22aa
requirements: move loading to hg-core and add parsing
Simon Sapin <simon-commits@exyr.org>
parents:
diff
changeset
|
53 } |
45937
2ad2745e0be9
rhg: exit with relevant code for unsupported requirements
Simon Sapin <simon-commits@exyr.org>
parents:
45924
diff
changeset
|
54 |
46167
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
46090
diff
changeset
|
55 pub fn check(repo: &Repo) -> Result<(), RequirementsError> { |
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
46090
diff
changeset
|
56 for feature in load(repo)? { |
45937
2ad2745e0be9
rhg: exit with relevant code for unsupported requirements
Simon Sapin <simon-commits@exyr.org>
parents:
45924
diff
changeset
|
57 if !SUPPORTED.contains(&&*feature) { |
45956
40f79997e81f
rust: fix non-utf8 char in requirements.rs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
45938
diff
changeset
|
58 return Err(RequirementsError::Unsupported { feature }); |
45937
2ad2745e0be9
rhg: exit with relevant code for unsupported requirements
Simon Sapin <simon-commits@exyr.org>
parents:
45924
diff
changeset
|
59 } |
2ad2745e0be9
rhg: exit with relevant code for unsupported requirements
Simon Sapin <simon-commits@exyr.org>
parents:
45924
diff
changeset
|
60 } |
2ad2745e0be9
rhg: exit with relevant code for unsupported requirements
Simon Sapin <simon-commits@exyr.org>
parents:
45924
diff
changeset
|
61 Ok(()) |
2ad2745e0be9
rhg: exit with relevant code for unsupported requirements
Simon Sapin <simon-commits@exyr.org>
parents:
45924
diff
changeset
|
62 } |
2ad2745e0be9
rhg: exit with relevant code for unsupported requirements
Simon Sapin <simon-commits@exyr.org>
parents:
45924
diff
changeset
|
63 |
2ad2745e0be9
rhg: exit with relevant code for unsupported requirements
Simon Sapin <simon-commits@exyr.org>
parents:
45924
diff
changeset
|
64 // TODO: set this to actually-supported features |
2ad2745e0be9
rhg: exit with relevant code for unsupported requirements
Simon Sapin <simon-commits@exyr.org>
parents:
45924
diff
changeset
|
65 const SUPPORTED: &[&str] = &[ |
2ad2745e0be9
rhg: exit with relevant code for unsupported requirements
Simon Sapin <simon-commits@exyr.org>
parents:
45924
diff
changeset
|
66 "dotencode", |
2ad2745e0be9
rhg: exit with relevant code for unsupported requirements
Simon Sapin <simon-commits@exyr.org>
parents:
45924
diff
changeset
|
67 "fncache", |
2ad2745e0be9
rhg: exit with relevant code for unsupported requirements
Simon Sapin <simon-commits@exyr.org>
parents:
45924
diff
changeset
|
68 "generaldelta", |
2ad2745e0be9
rhg: exit with relevant code for unsupported requirements
Simon Sapin <simon-commits@exyr.org>
parents:
45924
diff
changeset
|
69 "revlogv1", |
2ad2745e0be9
rhg: exit with relevant code for unsupported requirements
Simon Sapin <simon-commits@exyr.org>
parents:
45924
diff
changeset
|
70 "sparserevlog", |
2ad2745e0be9
rhg: exit with relevant code for unsupported requirements
Simon Sapin <simon-commits@exyr.org>
parents:
45924
diff
changeset
|
71 "store", |
46090
9eb07ab3f2d4
rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents:
45956
diff
changeset
|
72 // As of this writing everything rhg does is read-only. |
9eb07ab3f2d4
rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents:
45956
diff
changeset
|
73 // When it starts writing to the repository, it’ll need to either keep the |
9eb07ab3f2d4
rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents:
45956
diff
changeset
|
74 // persistent nodemap up to date or remove this entry: |
9eb07ab3f2d4
rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents:
45956
diff
changeset
|
75 "persistent-nodemap", |
45937
2ad2745e0be9
rhg: exit with relevant code for unsupported requirements
Simon Sapin <simon-commits@exyr.org>
parents:
45924
diff
changeset
|
76 ]; |