Provide a feature flag to be able to embed the runtime folder.

These changes provide a new feature flag "embed_runtime" that when
enabled and built in release mode will embed the runtime folder into the
resulting binary.
This commit is contained in:
Brian Dawn 2021-06-03 15:46:56 -05:00 committed by Blaž Hrastnik
parent 8c2fa12ffc
commit 62d181de78
7 changed files with 86 additions and 11 deletions

34
Cargo.lock generated
View File

@ -266,6 +266,7 @@ dependencies = [
"once_cell", "once_cell",
"regex", "regex",
"ropey", "ropey",
"rust-embed",
"serde", "serde",
"smallvec", "smallvec",
"tendril", "tendril",
@ -692,6 +693,39 @@ dependencies = [
"smallvec", "smallvec",
] ]
[[package]]
name = "rust-embed"
version = "5.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fe1fe6aac5d6bb9e1ffd81002340363272a7648234ec7bdfac5ee202cb65523"
dependencies = [
"rust-embed-impl",
"rust-embed-utils",
"walkdir",
]
[[package]]
name = "rust-embed-impl"
version = "5.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ed91c41c42ef7bf687384439c312e75e0da9c149b0390889b94de3c7d9d9e66"
dependencies = [
"proc-macro2",
"quote",
"rust-embed-utils",
"syn",
"walkdir",
]
[[package]]
name = "rust-embed-utils"
version = "5.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a512219132473ab0a77b52077059f1c47ce4af7fbdc94503e9862a34422876d"
dependencies = [
"walkdir",
]
[[package]] [[package]]
name = "ryu" name = "ryu"
version = "1.0.5" version = "1.0.5"

View File

@ -45,6 +45,13 @@ # Installation
> NOTE: You should set this to <path to repository>/runtime in development (if > NOTE: You should set this to <path to repository>/runtime in development (if
> running via cargo). > running via cargo).
If you want to bake the `runtime/` directory into the Helix binary you can build
it with:
```
cargo install --path helix-term --features "embed_runtime"
```
## Arch Linux ## Arch Linux
There are two packages available from AUR: There are two packages available from AUR:
- `helix-bin`: contains prebuilt binary from GitHub releases - `helix-bin`: contains prebuilt binary from GitHub releases

View File

@ -35,3 +35,10 @@ ## Build from source
Now copy the `runtime/` directory somewhere. Helix will by default look for the Now copy the `runtime/` directory somewhere. Helix will by default look for the
runtime inside the same folder as the executable, but that can be overriden via runtime inside the same folder as the executable, but that can be overriden via
the `HELIX_RUNTIME` environment variable. the `HELIX_RUNTIME` environment variable.
If you want to bake the `runtime/` directory into the Helix binary you can build
it with:
```
cargo install --path helix-term --features "embed_runtime"
```

View File

@ -7,6 +7,10 @@ license = "MPL-2.0"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[features]
embed_runtime = []
[dependencies] [dependencies]
helix-syntax = { path = "../helix-syntax" } helix-syntax = { path = "../helix-syntax" }
@ -24,3 +28,4 @@ serde = { version = "1.0", features = ["derive"] }
toml = "0.5" toml = "0.5"
etcetera = "0.3" etcetera = "0.3"
rust-embed="5.9.0"

View File

@ -44,6 +44,7 @@ pub(crate) fn find_first_non_whitespace_char(text: RopeSlice, line_num: usize) -
None None
} }
#[cfg(not(embed_runtime))]
pub fn runtime_dir() -> std::path::PathBuf { pub fn runtime_dir() -> std::path::PathBuf {
// runtime env var || dir where binary is located // runtime env var || dir where binary is located
std::env::var("HELIX_RUNTIME") std::env::var("HELIX_RUNTIME")

View File

@ -73,16 +73,37 @@ pub struct IndentQuery {
pub outdent: HashSet<String>, pub outdent: HashSet<String>,
} }
#[cfg(not(feature = "embed_runtime"))]
fn load_runtime_file(language: &str, filename: &str) -> Result<String, std::io::Error> {
let root = crate::runtime_dir();
let path = root.join("queries").join(language).join(filename);
std::fs::read_to_string(&path)
}
#[cfg(feature = "embed_runtime")]
use rust_embed::RustEmbed;
#[cfg(feature = "embed_runtime")]
#[derive(RustEmbed)]
#[folder = "../runtime/"]
struct Runtime;
#[cfg(feature = "embed_runtime")]
fn load_runtime_file(language: &str, filename: &str) -> Result<String, Box<dyn std::error::Error>> {
let root = PathBuf::new();
let path = root.join("queries").join(language).join(filename);
let query_bytes = Runtime::get(&path.as_path().display().to_string()).unwrap_or_default();
std::str::from_utf8(query_bytes.as_ref())
.map(|s| s.to_string())
.map_err(|err| err.into())
}
fn read_query(language: &str, filename: &str) -> String { fn read_query(language: &str, filename: &str) -> String {
static INHERITS_REGEX: Lazy<Regex> = static INHERITS_REGEX: Lazy<Regex> =
Lazy::new(|| Regex::new(r";+\s*inherits\s*:?\s*([a-z_,()]+)\s*").unwrap()); Lazy::new(|| Regex::new(r";+\s*inherits\s*:?\s*([a-z_,()]+)\s*").unwrap());
let root = crate::runtime_dir(); let query = load_runtime_file(language, filename).unwrap_or_default();
// let root = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
let path = root.join("queries").join(language).join(filename);
let query = std::fs::read_to_string(&path).unwrap_or_default();
// TODO: the collect() is not ideal // TODO: the collect() is not ideal
let inherits = INHERITS_REGEX let inherits = INHERITS_REGEX
@ -146,11 +167,8 @@ pub fn indent_query(&self) -> Option<&IndentQuery> {
.get_or_init(|| { .get_or_init(|| {
let language = get_language_name(self.language_id).to_ascii_lowercase(); let language = get_language_name(self.language_id).to_ascii_lowercase();
let root = crate::runtime_dir(); let toml = load_runtime_file(&language, "indents.toml").ok()?;
let path = root.join("queries").join(language).join("indents.toml"); toml::from_slice(&toml.as_bytes()).ok()
let toml = std::fs::read(&path).ok()?;
toml::from_slice(&toml).ok()
}) })
.as_ref() .as_ref()
} }

View File

@ -8,6 +8,9 @@ license = "MPL-2.0"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[features]
embed_runtime = ["helix-core/embed_runtime"]
[[bin]] [[bin]]
name = "hx" name = "hx"
path = "src/main.rs" path = "src/main.rs"