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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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 ];