##// END OF EJS Templates
rust: fix non-utf8 char in requirements.rs...
marmoute -
r46570:40f79997 default
parent child Browse files
Show More
@@ -1,72 +1,72
1 use std::io;
1 use std::io;
2 use std::path::Path;
2 use std::path::Path;
3
3
4 #[derive(Debug)]
4 #[derive(Debug)]
5 pub enum RequirementsError {
5 pub enum RequirementsError {
6 // TODO: include a path?
6 // TODO: include a path?
7 Io(io::Error),
7 Io(io::Error),
8 /// The `requires` file is corrupted
8 /// The `requires` file is corrupted
9 Corrupted,
9 Corrupted,
10 /// The repository requires a feature that we dont support
10 /// The repository requires a feature that we don't support
11 Unsupported {
11 Unsupported {
12 feature: String,
12 feature: String,
13 },
13 },
14 }
14 }
15
15
16 fn parse(bytes: &[u8]) -> Result<Vec<String>, ()> {
16 fn parse(bytes: &[u8]) -> Result<Vec<String>, ()> {
17 // The Python code reading this file uses `str.splitlines`
17 // The Python code reading this file uses `str.splitlines`
18 // which looks for a number of line separators (even including a couple of
18 // which looks for a number of line separators (even including a couple of
19 // non-ASCII ones), but Python code writing it always uses `\n`.
19 // non-ASCII ones), but Python code writing it always uses `\n`.
20 let lines = bytes.split(|&byte| byte == b'\n');
20 let lines = bytes.split(|&byte| byte == b'\n');
21
21
22 lines
22 lines
23 .filter(|line| !line.is_empty())
23 .filter(|line| !line.is_empty())
24 .map(|line| {
24 .map(|line| {
25 // Python uses Unicode `str.isalnum` but feature names are all
25 // Python uses Unicode `str.isalnum` but feature names are all
26 // ASCII
26 // ASCII
27 if line[0].is_ascii_alphanumeric() && line.is_ascii() {
27 if line[0].is_ascii_alphanumeric() && line.is_ascii() {
28 Ok(String::from_utf8(line.into()).unwrap())
28 Ok(String::from_utf8(line.into()).unwrap())
29 } else {
29 } else {
30 Err(())
30 Err(())
31 }
31 }
32 })
32 })
33 .collect()
33 .collect()
34 }
34 }
35
35
36 pub fn load(repo_root: &Path) -> Result<Vec<String>, RequirementsError> {
36 pub fn load(repo_root: &Path) -> Result<Vec<String>, RequirementsError> {
37 match std::fs::read(repo_root.join(".hg").join("requires")) {
37 match std::fs::read(repo_root.join(".hg").join("requires")) {
38 Ok(bytes) => parse(&bytes).map_err(|()| RequirementsError::Corrupted),
38 Ok(bytes) => parse(&bytes).map_err(|()| RequirementsError::Corrupted),
39
39
40 // Treat a missing file the same as an empty file.
40 // Treat a missing file the same as an empty file.
41 // From `mercurial/localrepo.py`:
41 // From `mercurial/localrepo.py`:
42 // > requires file contains a newline-delimited list of
42 // > requires file contains a newline-delimited list of
43 // > features/capabilities the opener (us) must have in order to use
43 // > features/capabilities the opener (us) must have in order to use
44 // > the repository. This file was introduced in Mercurial 0.9.2,
44 // > the repository. This file was introduced in Mercurial 0.9.2,
45 // > which means very old repositories may not have one. We assume
45 // > which means very old repositories may not have one. We assume
46 // > a missing file translates to no requirements.
46 // > a missing file translates to no requirements.
47 Err(error) if error.kind() == std::io::ErrorKind::NotFound => {
47 Err(error) if error.kind() == std::io::ErrorKind::NotFound => {
48 Ok(Vec::new())
48 Ok(Vec::new())
49 }
49 }
50
50
51 Err(error) => Err(RequirementsError::Io(error))?,
51 Err(error) => Err(RequirementsError::Io(error))?,
52 }
52 }
53 }
53 }
54
54
55 pub fn check(repo_root: &Path) -> Result<(), RequirementsError> {
55 pub fn check(repo_root: &Path) -> Result<(), RequirementsError> {
56 for feature in load(repo_root)? {
56 for feature in load(repo_root)? {
57 if !SUPPORTED.contains(&&*feature) {
57 if !SUPPORTED.contains(&&*feature) {
58 return Err(RequirementsError::Unsupported { feature })
58 return Err(RequirementsError::Unsupported { feature });
59 }
59 }
60 }
60 }
61 Ok(())
61 Ok(())
62 }
62 }
63
63
64 // TODO: set this to actually-supported features
64 // TODO: set this to actually-supported features
65 const SUPPORTED: &[&str] = &[
65 const SUPPORTED: &[&str] = &[
66 "dotencode",
66 "dotencode",
67 "fncache",
67 "fncache",
68 "generaldelta",
68 "generaldelta",
69 "revlogv1",
69 "revlogv1",
70 "sparserevlog",
70 "sparserevlog",
71 "store",
71 "store",
72 ];
72 ];
General Comments 0
You need to be logged in to leave comments. Login now