From 53b2f5511b60b05e2ac347d571112897567d2af5 Mon Sep 17 00:00:00 2001 From: Fabian Boehm Date: Fri, 28 Mar 2025 16:36:48 +0100 Subject: [PATCH] Rename the "installable" feature to "embed-data" This reflects better what it is - fish doesn't need to "install" itself anymore, it just includes the data in the binary. This also means we could include a separate "embed-man" feature that can be turned off if you want the man pages to be shipped separately. Also explain that in the README. --- Cargo.toml | 4 ++-- README.rst | 10 +++++----- build.rs | 8 ++++---- src/autoload.rs | 16 ++++++++-------- src/bin/fish.rs | 8 ++++---- src/builtins/status.rs | 16 ++++++++-------- src/env/config_paths.rs | 12 ++++++------ src/env/environment.rs | 2 +- src/function.rs | 2 +- 9 files changed, 39 insertions(+), 39 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 16a7e288e..438808e52 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -91,9 +91,9 @@ name = "fish_key_reader" path = "src/bin/fish_key_reader.rs" [features] -default = ["installable"] +default = ["embed-data"] benchmark = [] -installable = ["dep:rust-embed"] +embed-data = ["dep:rust-embed"] # The following features are auto-detected by the build-script and should not be enabled manually. asan = [] diff --git a/README.rst b/README.rst index 84b95c7d7..b75341fea 100644 --- a/README.rst +++ b/README.rst @@ -167,16 +167,16 @@ In addition to the normal CMake build options (like ``CMAKE_INSTALL_PREFIX``), f - WITH_GETTEXT=ON|OFF - whether to build with gettext support for translations. - extra_functionsdir, extra_completionsdir and extra_confdir - to compile in an additional directory to be searched for functions, completions and configuration snippets -Building fish as self-installable (experimental) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Building fish with embedded data (experimental) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -You can also build fish as a self-installing binary. +You can also build fish with the data files embedded. This will include all the datafiles like the included functions or web configuration tool in the main ``fish`` binary. -On the first interactive run, and whenever it notices they are out of date, it will extract the datafiles to ~/.local/share/fish/install/ (currently, subject to change). You can do this manually by running ``fish --install``. +Fish will then read these right from its own binary, and print them out when needed. Some files, like the webconfig tool and the manpage completion generator, will be extracted to a temporary directory on-demand. You can list the files with ``status list-files`` and print one with ``status get-file path/to/file`` (e.g. ``status get-file functions/fish_prompt.fish`` to get the default prompt). -To install fish as self-installable, just use ``cargo``, like:: +To install fish with embedded files, just use ``cargo``, like:: cargo install --path /path/to/fish # if you have a git clone cargo install --git https://github.com/fish-shell/fish-shell --tag 4.0.0 # to build from git with a specific version diff --git a/build.rs b/build.rs index d59389164..f86dab569 100644 --- a/build.rs +++ b/build.rs @@ -44,12 +44,12 @@ fn main() { let cman = std::fs::canonicalize(env!("CARGO_MANIFEST_DIR")).unwrap(); let targetman = cman.as_path().join("target").join("man"); - #[cfg(feature = "installable")] + #[cfg(feature = "embed-data")] #[cfg(not(clippy))] { build_man(&targetman); } - #[cfg(any(not(feature = "installable"), clippy))] + #[cfg(any(not(feature = "embed-data"), clippy))] { let sec1dir = targetman.join("man1"); let _ = std::fs::create_dir_all(sec1dir.to_str().unwrap()); @@ -59,7 +59,7 @@ fn main() { // These are necessary if built with embedded functions, // but only in release builds (because rust-embed in debug builds reads from the filesystem). - #[cfg(feature = "installable")] + #[cfg(feature = "embed-data")] #[cfg(not(debug_assertions))] rsconf::rebuild_if_paths_changed(&["doc_src", "share"]); @@ -390,7 +390,7 @@ fn get_git_hash() -> Result> { get_git_hash().expect("Could not get a version. Either set $FISH_BUILD_VERSION or install git.") } -#[cfg(feature = "installable")] +#[cfg(feature = "embed-data")] // disable clippy because otherwise it would panic without sphinx #[cfg(not(clippy))] fn build_man(build_dir: &Path) { diff --git a/src/autoload.rs b/src/autoload.rs index 2a90ca568..03d9b60c4 100644 --- a/src/autoload.rs +++ b/src/autoload.rs @@ -1,6 +1,6 @@ //! The classes responsible for autoloading functions and completions. -#[cfg(feature = "installable")] +#[cfg(feature = "embed-data")] use crate::common::wcs2string; use crate::common::{escape, ScopeGuard}; use crate::env::Environment; @@ -11,7 +11,7 @@ use crate::wchar::{wstr, WString, L}; use crate::wutil::{file_id_for_path, FileId, INVALID_FILE_ID}; use lru::LruCache; -#[cfg(feature = "installable")] +#[cfg(feature = "embed-data")] use rust_embed::RustEmbed; use std::collections::{HashMap, HashSet}; use std::num::NonZeroUsize; @@ -41,23 +41,23 @@ pub struct Autoload { cache: Box, } -#[cfg(feature = "installable")] +#[cfg(feature = "embed-data")] #[derive(RustEmbed)] #[folder = "share/"] pub struct Asset; -#[cfg(feature = "installable")] +#[cfg(feature = "embed-data")] pub fn has_asset(cmd: &str) -> bool { Asset::get(cmd).is_some() } -#[cfg(not(feature = "installable"))] +#[cfg(not(feature = "embed-data"))] pub fn has_asset(_cmd: &str) -> bool { false } pub enum AutoloadPath { - #[cfg(feature = "installable")] + #[cfg(feature = "embed-data")] Embedded(String), Path(WString), } @@ -135,7 +135,7 @@ pub fn resolve_command(&mut self, cmd: &wstr, env: &dyn Environment) -> Option { use crate::common::str2wcstring; use std::sync::Arc; diff --git a/src/bin/fish.rs b/src/bin/fish.rs index 08a86c6bd..19bf7be4d 100644 --- a/src/bin/fish.rs +++ b/src/bin/fish.rs @@ -63,7 +63,7 @@ wchar::prelude::*, wutil::waccess, }; -#[cfg(feature = "installable")] +#[cfg(feature = "embed-data")] use rust_embed::RustEmbed; use std::ffi::{CString, OsStr, OsString}; use std::fs::File; @@ -74,7 +74,7 @@ use std::sync::Arc; use std::{env, ops::ControlFlow}; -#[cfg(feature = "installable")] +#[cfg(feature = "embed-data")] #[derive(RustEmbed)] #[folder = "share/"] struct Asset; @@ -172,7 +172,7 @@ fn source_config_in_directory(parser: &Parser, dir: &wstr) -> bool { /// Parse init files. exec_path is the path of fish executable as determined by argv[0]. fn read_init(parser: &Parser, paths: &ConfigPaths) { - #[cfg(feature = "installable")] + #[cfg(feature = "embed-data")] { let emfile = Asset::get("config.fish").expect("Embedded file not found"); let src = str2wcstring(&emfile.data); @@ -184,7 +184,7 @@ fn read_init(parser: &Parser, paths: &ConfigPaths) { eprintf!("%ls", msg); } } - #[cfg(not(feature = "installable"))] + #[cfg(not(feature = "embed-data"))] { let datapath = str2wcstring(paths.data.as_os_str().as_bytes()); if !source_config_in_directory(parser, &datapath) { diff --git a/src/builtins/status.rs b/src/builtins/status.rs index 4dc02e62c..9e8ea19f2 100644 --- a/src/builtins/status.rs +++ b/src/builtins/status.rs @@ -317,10 +317,10 @@ fn parse_cmd_opts( return Ok(SUCCESS); } -#[cfg(feature = "installable")] +#[cfg(feature = "embed-data")] use rust_embed::RustEmbed; -#[cfg(feature = "installable")] +#[cfg(feature = "embed-data")] #[derive(RustEmbed)] #[folder = "target/man/man1"] #[prefix = "man/man1/"] @@ -456,7 +456,7 @@ pub fn status(parser: &Parser, streams: &mut IoStreams, args: &mut [&wstr]) -> B )); return Err(STATUS_INVALID_ARGS); } - #[cfg(feature = "installable")] + #[cfg(feature = "embed-data")] { let arg = crate::common::wcs2string(args[0]); let arg = std::str::from_utf8(&arg).unwrap(); @@ -472,7 +472,7 @@ pub fn status(parser: &Parser, streams: &mut IoStreams, args: &mut [&wstr]) -> B return Err(STATUS_CMD_ERROR); } } - #[cfg(not(feature = "installable"))] + #[cfg(not(feature = "embed-data"))] { streams.err.append(wgettext_fmt!( "%ls: fish was not built with embedded files", @@ -492,7 +492,7 @@ pub fn status(parser: &Parser, streams: &mut IoStreams, args: &mut [&wstr]) -> B )); return Err(STATUS_INVALID_ARGS); } - #[cfg(feature = "installable")] + #[cfg(feature = "embed-data")] { let mut have_file = false; let arg = crate::common::wcs2string(args.get(0).unwrap_or(&L!(""))); @@ -518,7 +518,7 @@ pub fn status(parser: &Parser, streams: &mut IoStreams, args: &mut [&wstr]) -> B return Err(STATUS_CMD_ERROR); } } - #[cfg(not(feature = "installable"))] + #[cfg(not(feature = "embed-data"))] { streams.err.append(wgettext_fmt!( "%ls: fish was not built with embedded files", @@ -567,8 +567,8 @@ pub fn status(parser: &Parser, streams: &mut IoStreams, args: &mut [&wstr]) -> B let features: &[&str] = &[ #[cfg(gettext)] "gettext", - #[cfg(feature = "installable")] - "installable", + #[cfg(feature = "embed-data")] + "embed-data", #[cfg(target_feature = "crt-static")] "crt-static", ]; diff --git a/src/env/config_paths.rs b/src/env/config_paths.rs index 86688a6dc..6b0f4ddc3 100644 --- a/src/env/config_paths.rs +++ b/src/env/config_paths.rs @@ -64,9 +64,9 @@ fn determine_config_directory_paths(argv0: impl AsRef) -> ConfigPaths { // The next check is that we are in a relocatable directory tree if exec_path.ends_with("bin/fish") { let base_path = exec_path.parent().unwrap().parent().unwrap(); - #[cfg(feature = "installable")] + #[cfg(feature = "embed-data")] let data_dir = base_path.join("share/fish/install"); - #[cfg(not(feature = "installable"))] + #[cfg(not(feature = "embed-data"))] let data_dir = base_path.join("share/fish"); paths = ConfigPaths { // One obvious path is ~/.local (with fish in ~/.local/bin/). @@ -85,9 +85,9 @@ fn determine_config_directory_paths(argv0: impl AsRef) -> ConfigPaths { "'fish' not in a 'bin/', trying paths relative to source tree" ); let base_path = exec_path.parent().unwrap(); - #[cfg(feature = "installable")] + #[cfg(feature = "embed-data")] let data_dir = base_path.join("share/install"); - #[cfg(not(feature = "installable"))] + #[cfg(not(feature = "embed-data"))] let data_dir = base_path.join("share"); paths = ConfigPaths { data: data_dir.clone(), @@ -110,7 +110,7 @@ fn determine_config_directory_paths(argv0: impl AsRef) -> ConfigPaths { if !done { // Fall back to what got compiled in. - let data = if cfg!(feature = "installable") { + let data = if cfg!(feature = "embed-data") { let Some(home) = crate::env::get_home() else { FLOG!( error, @@ -124,7 +124,7 @@ fn determine_config_directory_paths(argv0: impl AsRef) -> ConfigPaths { } else { PathBuf::from(DATA_DIR).join(DATA_DIR_SUBDIR) }; - let bin = if cfg!(feature = "installable") { + let bin = if cfg!(feature = "embed-data") { exec_path.parent().map(|x| x.to_path_buf()) } else { Some(PathBuf::from(BIN_DIR)) diff --git a/src/env/environment.rs b/src/env/environment.rs index 7b9a7ddd9..5faf7d2aa 100644 --- a/src/env/environment.rs +++ b/src/env/environment.rs @@ -644,7 +644,7 @@ pub fn env_init(paths: Option<&ConfigPaths>, do_uvars: bool, default_paths: bool str2wcstring(paths.sysconf.as_os_str().as_bytes()), ); - if !cfg!(feature = "installable") { + if !cfg!(feature = "embed-data") { vars.set_one( FISH_HELPDIR_VAR, EnvMode::GLOBAL, diff --git a/src/function.rs b/src/function.rs index 4431973cd..e89a1a294 100644 --- a/src/function.rs +++ b/src/function.rs @@ -338,7 +338,7 @@ pub fn get_names(get_hidden: bool, vars: &dyn Environment) -> Vec { names.insert(name.clone()); } - #[cfg(feature = "installable")] + #[cfg(feature = "embed-data")] for name in crate::autoload::Asset::iter() { let Some(bname) = name.strip_prefix("functions/") else { continue;