Mercurial > public > mercurial-scm > hg
annotate rust/hgcli/build.rs @ 37291:b0041036214e
wireproto: define frame to represent progress updates
Today, a long-running operation on a server may run without any sign
of progress on the client. This can lead to the conclusion that the
server has hung or the connection has dropped. In fact, connections
can and do time out due to inactivity. And a long-running server
operation can result in the connection dropping prematurely because
no data is being sent!
While we're inventing the new wire protocol, let's provide a mechanism
for communicating progress on potentially expensive server-side events.
We introduce a new frame type that conveys "progress" updates. This
frame type essentially holds the data required to formulate a
``ui.progress()`` call.
We only define the frame right now. Implementing it will be a bit of
work since there is no analog to progress frames in the existing
wire protocol. We'll need to teach the ui object to write to the
wire protocol, etc.
The use of a CBOR map may seem wasteful, as this will encode key
names in every frame. This *is* wasteful. However, maps are
extensible. And the intent is to always use compression via
streams. Compression will make the overhead negligible since repeated
strings will be mostly eliminated over the wire.
Differential Revision: https://phab.mercurial-scm.org/D2902
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Mon, 26 Mar 2018 10:50:36 -0700 |
parents | 24b5106e3e1e |
children | ce088b38f92b |
rev | line source |
---|---|
35569
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
1 // build.rs -- Configure build environment for `hgcli` Rust package. |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
2 // |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
3 // Copyright 2017 Gregory Szorc <gregory.szorc@gmail.com> |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
4 // |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
5 // This software may be used and distributed according to the terms of the |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
6 // GNU General Public License version 2 or any later version. |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
7 |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
8 use std::collections::HashMap; |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
9 use std::env; |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
10 use std::path::Path; |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
11 use std::process::Command; |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
12 |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
13 struct PythonConfig { |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
14 python: String, |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
15 config: HashMap<String, String>, |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
16 } |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
17 |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
18 fn get_python_config() -> PythonConfig { |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
19 // The python27-sys crate exports a Cargo variable defining the full |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
20 // path to the interpreter being used. |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
21 let python = env::var("DEP_PYTHON27_PYTHON_INTERPRETER").expect( |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
22 "Missing DEP_PYTHON27_PYTHON_INTERPRETER; bad python27-sys crate?", |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
23 ); |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
24 |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
25 if !Path::new(&python).exists() { |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
26 panic!( |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
27 "Python interpreter {} does not exist; this should never happen", |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
28 python |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
29 ); |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
30 } |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
31 |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
32 // This is a bit hacky but it gets the job done. |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
33 let separator = "SEPARATOR STRING"; |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
34 |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
35 let script = "import sysconfig; \ |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
36 c = sysconfig.get_config_vars(); \ |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
37 print('SEPARATOR STRING'.join('%s=%s' % i for i in c.items()))"; |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
38 |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
39 let mut command = Command::new(&python); |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
40 command.arg("-c").arg(script); |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
41 |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
42 let out = command.output().unwrap(); |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
43 |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
44 if !out.status.success() { |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
45 panic!( |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
46 "python script failed: {}", |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
47 String::from_utf8_lossy(&out.stderr) |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
48 ); |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
49 } |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
50 |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
51 let stdout = String::from_utf8_lossy(&out.stdout); |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
52 let mut m = HashMap::new(); |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
53 |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
54 for entry in stdout.split(separator) { |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
55 let mut parts = entry.splitn(2, "="); |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
56 let key = parts.next().unwrap(); |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
57 let value = parts.next().unwrap(); |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
58 m.insert(String::from(key), String::from(value)); |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
59 } |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
60 |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
61 PythonConfig { |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
62 python: python, |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
63 config: m, |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
64 } |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
65 } |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
66 |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
67 #[cfg(not(target_os = "windows"))] |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
68 fn have_shared(config: &PythonConfig) -> bool { |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
69 match config.config.get("Py_ENABLE_SHARED") { |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
70 Some(value) => value == "1", |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
71 None => false, |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
72 } |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
73 } |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
74 |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
75 #[cfg(target_os = "windows")] |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
76 fn have_shared(config: &PythonConfig) -> bool { |
35603
11c86ab69e67
rust: move import of PathBuf
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35569
diff
changeset
|
77 use std::path::PathBuf; |
11c86ab69e67
rust: move import of PathBuf
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35569
diff
changeset
|
78 |
35569
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
79 // python27.dll should exist next to python2.7.exe. |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
80 let mut dll = PathBuf::from(&config.python); |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
81 dll.pop(); |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
82 dll.push("python27.dll"); |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
83 |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
84 return dll.exists(); |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
85 } |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
86 |
35607
24b5106e3e1e
rust: avoid redundant 'static lifetime
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35603
diff
changeset
|
87 const REQUIRED_CONFIG_FLAGS: [&str; 2] = ["Py_USING_UNICODE", "WITH_THREAD"]; |
35569
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
88 |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
89 fn main() { |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
90 let config = get_python_config(); |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
91 |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
92 println!("Using Python: {}", config.python); |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
93 println!("cargo:rustc-env=PYTHON_INTERPRETER={}", config.python); |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
94 |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
95 let prefix = config.config.get("prefix").unwrap(); |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
96 |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
97 println!("Prefix: {}", prefix); |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
98 |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
99 // TODO Windows builds don't expose these config flags. Figure out another |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
100 // way. |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
101 #[cfg(not(target_os = "windows"))] |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
102 for key in REQUIRED_CONFIG_FLAGS.iter() { |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
103 let result = match config.config.get(*key) { |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
104 Some(value) => value == "1", |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
105 None => false, |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
106 }; |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
107 |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
108 if !result { |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
109 panic!("Detected Python requires feature {}", key); |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
110 } |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
111 } |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
112 |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
113 // We need a Python shared library. |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
114 if !have_shared(&config) { |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
115 panic!("Detected Python lacks a shared library, which is required"); |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
116 } |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
117 |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
118 let ucs4 = match config.config.get("Py_UNICODE_SIZE") { |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
119 Some(value) => value == "4", |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
120 None => false, |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
121 }; |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
122 |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
123 if !ucs4 { |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
124 #[cfg(not(target_os = "windows"))] |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
125 panic!("Detected Python doesn't support UCS-4 code points"); |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
126 } |
964212780daf
rust: implementation of `hg`
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
127 } |