diff --git a/APKBUILD b/APKBUILD index caafceda..1c511d9f 100644 --- a/APKBUILD +++ b/APKBUILD @@ -41,13 +41,14 @@ prepare() { build() { cargo auditable build --release --frozen + cargo xtask dist-data greetd-config.toml --greetd-vt 7 --greetd-user greetd } package() { install -Dm644 data/mobi.phosh.phrog.gschema.xml -t "$pkgdir"/usr/share/glib-2.0/schemas/ install -Dm644 data/phrog.session -t "$pkgdir"/usr/share/gnome-session/sessions/ install -Dm644 data/mobi.phosh.Phrog.desktop -t "$pkgdir"/usr/share/applications/ - install -Dm644 dist/alpine/greetd-config.toml -t "$pkgdir"/etc/phrog/ + install -Dm644 target/dist-data/greetd-config.toml -t "$pkgdir"/etc/phrog/ install -d "$pkgdir"/usr/share/phrog/autostart install -d "$pkgdir"/etc/phrog/autostart install -Dm755 target/release/phrog -t "$pkgdir"/usr/bin/ diff --git a/data/phrog.toml b/data/greetd-config.toml.in similarity index 71% rename from data/phrog.toml rename to data/greetd-config.toml.in index 68bd96f4..649fc12b 100644 --- a/data/phrog.toml +++ b/data/greetd-config.toml.in @@ -1,10 +1,9 @@ [terminal] -vt = 7 +vt = @VT@ -# The default session, also known as the greeter. [default_session] command = "/usr/libexec/phrog-greetd-session" -user = "_greetd" +user = "@USER@" # The session to be used on boot #[initial_session] diff --git a/debian/phrog.install b/debian/phrog.install index 60025eef..b1e47b61 100644 --- a/debian/phrog.install +++ b/debian/phrog.install @@ -7,6 +7,6 @@ data/mobi.phosh.Phrog.target /usr/lib/systemd/user/ data/systemd-session.conf usr/lib/systemd/user/gnome-session@phrog.target.d # Debian-specific config -data/phrog.toml etc/greetd +target/dist-data/phrog.toml etc/greetd debian/config/phoc.ini usr/share/phrog debian/config/systemd/phrog.conf usr/lib/systemd/system/greetd.service.d diff --git a/debian/rules b/debian/rules index 49f66e54..a7555d6e 100755 --- a/debian/rules +++ b/debian/rules @@ -13,6 +13,7 @@ export INSTALL_DIR=$(CURDIR)/debian/phrog # during build and delete it afterwards override_dh_auto_build: HOME=$(CURDIR)/debian/tmp_home cargo build + HOME=$(CURDIR)/debian/tmp_home cargo xtask dist-data phrog.toml --greetd-vt 7 --greetd-user _greetd override_dh_auto_install: install -D -m0755 target/$(DEB_HOST_RUST_TYPE)/debug/phrog \ diff --git a/dist/alpine/greetd-config.toml b/dist/alpine/greetd-config.toml deleted file mode 100644 index 9643bc3b..00000000 --- a/dist/alpine/greetd-config.toml +++ /dev/null @@ -1,10 +0,0 @@ -# This is a greetd config.toml preconfigured to run phrog. -# You can use it by adding the following line to /etc/conf.d/greetd: -# cfgfile="/etc/phrog/greetd-config.toml" - -[terminal] -vt = 7 - -[default_session] -command = "/usr/libexec/phrog-greetd-session" -user = "greetd" diff --git a/dist/fedora/greetd-config.toml b/dist/fedora/greetd-config.toml deleted file mode 100644 index 363150f1..00000000 --- a/dist/fedora/greetd-config.toml +++ /dev/null @@ -1,10 +0,0 @@ -# This is a greetd config.toml preconfigured to run phrog. -# It's intended to be used with phrog.service -# But you can also use it directly by running greetd --config=/etc/phrog/greetd-config.toml - -[terminal] -vt = 1 - -[default_session] -command = "/usr/libexec/phrog-greetd-session" -user = "greetd" diff --git a/phrog.spec b/phrog.spec index 516e4852..c69ccfab 100644 --- a/phrog.spec +++ b/phrog.spec @@ -61,6 +61,7 @@ chmod 0700 /tmp/runtime-dir %build %cargo_build +%{__cargo} run --frozen --quiet --package xtask -- dist-data greetd-config.toml --greetd-vt 1 --greetd-user greetd %cargo_vendor_manifest %{cargo_license_summary} %{cargo_license} > LICENSE.dependencies @@ -71,7 +72,7 @@ chmod 0700 /tmp/runtime-dir %{__install} -Dpm 0644 data/mobi.phosh.phrog.gschema.xml -t %{buildroot}%{_datadir}/glib-2.0/schemas/ %{__install} -Dpm 0644 data/phrog.session -t %{buildroot}%{_datadir}/gnome-session/sessions/ %{__install} -Dpm 0644 data/mobi.phosh.Phrog.desktop -t %{buildroot}%{_datadir}/applications/ -%{__install} -Dpm 0644 dist/fedora/greetd-config.toml -t %{buildroot}%{_sysconfdir}/phrog/ +%{__install} -Dpm 0644 target/dist-data/greetd-config.toml -t %{buildroot}%{_sysconfdir}/phrog/ %{__install} -Dpm 0644 dist/fedora/phrog.service -t %{buildroot}%{_unitdir}/ %{__install} -Dpm 0644 data/systemd-session.conf -T %{buildroot}%{_userunitdir}/gnome-session@phrog.target.d/session.conf %{__install} -Dpm 0755 data/phrog-greetd-session -t %{buildroot}%{_libexecdir}/ diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 61f011b1..58d06b9f 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -1,6 +1,6 @@ use std::error::Error; use std::fs; -use std::path::{Path, PathBuf}; +use std::path::{Component, Path, PathBuf}; use std::process::{self, Command}; use clap::{Parser, Subcommand}; @@ -9,6 +9,7 @@ use toml_edit::{value, DocumentMut}; type Result = std::result::Result>; +const GREETD_CONFIG_TEMPLATE: &str = include_str!("../../data/greetd-config.toml.in"); const VERSION_USAGE: &str = "Use X.Y.Z or X.Y.Z-rc.N."; #[derive(Debug, PartialEq, Eq)] @@ -33,6 +34,17 @@ enum Commands { /// Version to bump to (X.Y.Z or X.Y.Z-rc.N). version: String, }, + /// Generate packaging data. + DistData { + /// File name for the generated greetd config under target/dist-data. + file_name: String, + /// VT to run greetd on. + #[arg(long)] + greetd_vt: u8, + /// User greetd should use for phrog. + #[arg(long)] + greetd_user: String, + }, } fn main() { @@ -45,6 +57,11 @@ fn main() { fn run() -> Result<()> { match Cli::parse().command { Commands::Bump { version } => bump(&version), + Commands::DistData { + file_name, + greetd_vt, + greetd_user, + } => dist_data(&file_name, greetd_vt, &greetd_user), } } @@ -101,6 +118,21 @@ fn bump(version: &str) -> Result<()> { Ok(()) } +fn dist_data(file_name: &str, greetd_vt: u8, greetd_user: &str) -> Result<()> { + let root = project_root()?; + let out_path = dist_data_path(&root, file_name)?; + let out_dir = out_path + .parent() + .ok_or_else(|| format!("output path '{}' has no parent", out_path.display()))?; + + fs::create_dir_all(&out_dir)?; + fs::write(&out_path, render_greetd_config(greetd_vt, greetd_user))?; + + println!("Generated {}", out_path.display()); + + Ok(()) +} + fn parse_version(version: &str) -> Result { let parsed = Version::parse(version) .map_err(|error| format!("unsupported version '{version}': {error}. {VERSION_USAGE}"))?; @@ -134,6 +166,24 @@ fn parse_version(version: &str) -> Result { }) } +fn render_greetd_config(greetd_vt: u8, greetd_user: &str) -> String { + GREETD_CONFIG_TEMPLATE + .replace("@VT@", &greetd_vt.to_string()) + .replace("@USER@", greetd_user) +} + +fn dist_data_path(root: &Path, file_name: &str) -> Result { + let path = Path::new(file_name); + let mut components = path.components(); + + match (components.next(), components.next()) { + (Some(Component::Normal(_)), None) => Ok(root.join("target/dist-data").join(path)), + _ => { + Err(format!("dist-data file name must not contain path separators: {file_name}").into()) + } + } +} + fn project_root() -> Result { Path::new(env!("CARGO_MANIFEST_DIR")) .parent() @@ -143,6 +193,13 @@ fn project_root() -> Result { fn update_cargo_toml(path: &Path, cargo_version: &str) -> Result<()> { let text = fs::read_to_string(path)?; + let updated = update_cargo_toml_text(&text, cargo_version)?; + + fs::write(path, updated)?; + Ok(()) +} + +fn update_cargo_toml_text(text: &str, cargo_version: &str) -> Result { let mut document = text.parse::()?; let package = document["package"] .as_table_mut() @@ -154,8 +211,7 @@ fn update_cargo_toml(path: &Path, cargo_version: &str) -> Result<()> { package["version"] = value(cargo_version); - fs::write(path, document.to_string())?; - Ok(()) + Ok(document.to_string()) } fn replace_line(path: &Path, predicate: impl Fn(&str) -> bool, replacement: &str) -> Result<()> { @@ -285,6 +341,54 @@ mod tests { assert!(error.contains(VERSION_USAGE)); } + #[test] + fn renders_greetd_config() { + assert_eq!( + render_greetd_config(7, "_greetd"), + "[terminal]\nvt = 7\n\n[default_session]\ncommand = \"/usr/libexec/phrog-greetd-session\"\nuser = \"_greetd\"\n\n# The session to be used on boot\n#[initial_session]\n#command = \"systemd-cat phosh-session\"\n#user = \"username\"\n" + ); + } + + #[test] + fn builds_dist_data_path() { + assert_eq!( + dist_data_path(Path::new("/tmp/phrog"), "phrog.toml").unwrap(), + PathBuf::from("/tmp/phrog/target/dist-data/phrog.toml") + ); + } + + #[test] + fn rejects_nested_dist_data_path() { + assert_eq!( + dist_data_path(Path::new("/tmp/phrog"), "debian/phrog.toml") + .unwrap_err() + .to_string(), + "dist-data file name must not contain path separators: debian/phrog.toml" + ); + } + + #[test] + fn updates_cargo_toml_package_version_only() { + let text = concat!( + "[package]\n", + "name = \"phrog\"\n", + "version = \"1.2.3\"\n\n", + "[dependencies]\n", + "clap = { version = \"4\" }\n" + ); + + assert_eq!( + update_cargo_toml_text(text, "2.0.0").unwrap(), + concat!( + "[package]\n", + "name = \"phrog\"\n", + "version = \"2.0.0\"\n\n", + "[dependencies]\n", + "clap = { version = \"4\" }\n" + ) + ); + } + #[test] fn updates_readme_demo_download_url() { let text =