Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add nix flake support #73

Closed
wants to merge 32 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
fa2f110
added nix flakes
nonono697 Mar 27, 2024
d807518
working flake probably
beh-10257 Mar 27, 2024
92dcf05
fixed version numbers
beh-10257 Mar 27, 2024
1c3fdd7
yeah removed git dependency since its not needed
beh-10257 Mar 28, 2024
76814ee
moved contrib to packaging since I didn't notice that was used
beh-10257 Mar 28, 2024
0f83d7a
docs: fix typo after project rename
R1kaB3rN Mar 28, 2024
2fe8732
docs: update comment after implementation change
R1kaB3rN Mar 28, 2024
7371829
umu_run: be smarter when handling exceptions or exiting
R1kaB3rN Mar 28, 2024
cc901ce
umu_run: enforce not running the script as root
R1kaB3rN Mar 28, 2024
d749cfe
umu_run: update error message for _v2-entry-point
R1kaB3rN Mar 28, 2024
e71198a
Support copying files for immutable distributions
R1kaB3rN Mar 29, 2024
9678521
umu_test: add test when copying read-only files
R1kaB3rN Mar 29, 2024
218fed9
Merge pull request #75 from R1kaB3rN/immutable-distros
R1kaB3rN Mar 29, 2024
449f6fa
fixed UMU_LOG variable name in man pages
beh-10257 Mar 29, 2024
af39f7b
include NixOS in README
beh-10257 Mar 29, 2024
175d2e8
added nix flakes
nonono697 Mar 27, 2024
666a9aa
working flake probably
beh-10257 Mar 27, 2024
6444c01
fixed version numbers
beh-10257 Mar 27, 2024
6d35659
yeah removed git dependency since its not needed
beh-10257 Mar 28, 2024
5897844
moved contrib to packaging since I didn't notice that was used
beh-10257 Mar 28, 2024
e85a921
fixed UMU_LOG variable name in man pages
beh-10257 Mar 29, 2024
ab3625f
include NixOS in README
beh-10257 Mar 29, 2024
922bfac
added nix flakes
nonono697 Mar 27, 2024
fca4144
working flake probably
beh-10257 Mar 27, 2024
52c2fba
fixed version numbers
beh-10257 Mar 27, 2024
597e0b3
yeah removed git dependency since its not needed
beh-10257 Mar 28, 2024
8f9d714
moved contrib to packaging since I didn't notice that was used
beh-10257 Mar 28, 2024
5a995e3
fixed a typo in NixOS
beh-10257 Mar 29, 2024
af18f06
Merge branch 'main' of https://github.com/beh-10257/umu-launcher-nix …
beh-10257 Mar 29, 2024
d79a158
made nixos instreuctions more Formal (I still need to make it more
beh-10257 Mar 29, 2024
12438e5
remove capital
beh-10257 Mar 29, 2024
c6be922
I will just remove the obvious section
beh-10257 Mar 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,26 @@ You will need to add `$HOME/.local/bin` in your `$PATH` to be able to run umu th
export PATH="$HOME/.local/bin:$PATH"
```

# Packages:
## NixOS
if you want to add umu-launcher as a flake add this to your inputs in flake.nix
```nix
inputs = {
umu= {
url = "git+https://github.com/Open-Wine-Components/umu-launcher/?dir=packaging\/nix&submodules=1";
inputs.nixpkgs.follows = "nixpkgs";
};
}
```
and in your configuration.nix
```nix
{inputs, pkgs, ... }:
{
environment.systemPackages = [ inputs.umu.packages.${pkgs.system}.umu ];
}
```
if there is any problem with the flake feel free to open a bug report and tag any of the maintainers
> maintainers: @beh-10257

# Usage notes:

Expand Down
11 changes: 6 additions & 5 deletions docs/umu.1.scd
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,10 @@ $ WINEPREFIX=~/foo GAMEID=0 PROTONPATH= umu-run ""
*Example 5. Run a game and automatically set Proton*

```
# First checks for a recent Proton at ~/.local/share/Steam/compatibilitytools.d
# When Proton cannot be found, the latest umu-Proton will be downloaded
# The cache ~/.cache/umu will be checked if the download fails or interrupted
# Always checks for the latest release of UMU-Proton, and will download then
# use it when available
# NOTE: Previous stable versions of UMU-Proton will be auto removed in
# compatibilitytools.d after the latest has been downloaded
$ WINEPREFIX= GAMEID=0 umu-run foo.exe
```

Expand All @@ -98,8 +99,8 @@ $ WINEPREFIX= GAMEID=0 PROTONPATH= PROTON_VERB=waitforexitandrun umu-run ~/foo.e

```
# Shows environment variables and command at this level
# Valid values for umu_LOG include: 1, warn, debug
$ umu_LOG=1 WINEPREFIX= GAMEID=0 PROTONPATH= umu-run ~/foo.exe
# Valid values for UMU_LOG include: 1, warn, debug
$ UMU_LOG=1 WINEPREFIX= GAMEID=0 PROTONPATH= umu-run ~/foo.exe
```

*Example 9. Run a game and set a Proton by its version name*
Expand Down
11 changes: 11 additions & 0 deletions packaging/nix/combine.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{ env, package, symlinkJoin }:
symlinkJoin {
name = "umu-combine";
paths = [
env
package
];
postBuild = ''
rm $out/bin/umu-run
'';
}
27 changes: 27 additions & 0 deletions packaging/nix/flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions packaging/nix/flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
description = "umu universal game launcher";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
};
outputs = { self, nixpkgs }:
let
umu-package = nixpkgs.legacyPackages.x86_64-linux.callPackage ./umu-launcher.nix { umu-launcher=( builtins.toPath "${self}/../../"); };
umu-run = nixpkgs.legacyPackages.x86_64-linux.callPackage ./umu-run.nix { package=umu-package; };
in{
packages.x86_64-linux.umu = nixpkgs.legacyPackages.x86_64-linux.callPackage ./combine.nix { env=umu-run; package=umu-package; };
};
}
16 changes: 16 additions & 0 deletions packaging/nix/umu-launcher.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{stdenv , umu-launcher, pkgs, ...}:
stdenv.mkDerivation {
pname = "umu-launcher";
version = "0.1";
src = umu-launcher;
depsBuildBuild = [
pkgs.meson
pkgs.ninja
pkgs.scdoc
];
dontUseMesonConfigure = true;
dontUseNinjaBuild = true;
dontUseNinjaInstall = true;
dontUseNinjaCheck = true;
configureScript = "./configure.sh";
}
14 changes: 14 additions & 0 deletions packaging/nix/umu-run.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{ package, lib,stdenv, buildFHSEnv, writeShellScript, ...}:
let
ldPath = lib.optionals stdenv.is64bit [ "/lib64" ] ++ [ "/lib32" ];
exportLDPath = ''
export LD_LIBRARY_PATH=${lib.concatStringsSep ":" ldPath}''${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH
'';
in
buildFHSEnv {
name = "umu";
runScript = writeShellScript "umu-env" ''
${exportLDPath}
${package}/bin/umu-run "$@"
'';
}
7 changes: 7 additions & 0 deletions umu/umu_consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,10 @@ class Color(Enum):
"getcompatpath",
"getnativepath",
}


class MODE(Enum):
"""Represent the permission to apply to a file."""

USER_RW = 0o0644
USER_RWX = 0o0755
34 changes: 18 additions & 16 deletions umu/umu_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,17 @@ def parse_args() -> Union[Namespace, Tuple[str, List[str]]]: # noqa: D103
opt_args: Set[str] = {"--help", "-h", "--config"}
parser: ArgumentParser = ArgumentParser(
description="Unified Linux Wine Game Launcher",
epilog="See umu(1) for more info and examples.",
epilog=(
"See umu(1) for more info and examples, or visit\n"
"https://github.com/Open-Wine-Components/umu-launcher"
),
formatter_class=RawTextHelpFormatter,
)
parser.add_argument("--config", help="path to TOML file (requires Python 3.11+)")

if not sys.argv[1:]:
err: str = (
"Please see project README.md for more info and examples.\n"
"https://github.com/Open-Wine-Components/umu-launcher"
)
parser.print_help(sys.stderr)
raise SystemExit(err)
sys.exit(1)

if sys.argv[1:][0] in opt_args:
return parser.parse_args(sys.argv[1:])
Expand Down Expand Up @@ -229,11 +228,9 @@ def build_command(

# Raise an error if the _v2-entry-point cannot be found
if not local.joinpath("umu").is_file():
home: str = Path.home().as_posix()
dir: str = Path(__file__).parent.as_posix()
msg: str = (
"Path to _v2-entry-point cannot be found in: "
f"{home}/.local/share or {dir}\n"
f"{local}\n"
"Please install a Steam Runtime platform"
)
raise FileNotFoundError(msg)
Expand Down Expand Up @@ -292,9 +289,15 @@ def main() -> int: # noqa: D103
thread: Thread = None
args: Union[Namespace, Tuple[str, List[str]]] = parse_args()

if os.geteuid() == 0:
err: str = "This script should never be run as the root user"
log.error(err)
sys.exit(1)

if "musl" in os.environ.get("LD_LIBRARY_PATH", ""):
err: str = "This script is not designed to run on musl-based systems"
raise SystemExit(err)
log.error(err)
sys.exit(1)

if "UMU_LOG" in os.environ:
set_log()
Expand Down Expand Up @@ -366,13 +369,12 @@ def main() -> int: # noqa: D103
sys.exit(main())
except KeyboardInterrupt:
log.warning("Keyboard Interrupt")
sys.exit(1)
except SystemExit as e:
if e.code != 0:
raise Exception(e)
except Exception:
log.exception("Exception")
sys.exit(1)
if e.code:
log.debug("subprocess exited the status code: %s", e.code)
sys.exit(e.code)
except BaseException:
log.exception("BaseException")
finally:
UMU_LOCAL.joinpath(".ref").unlink(
missing_ok=True
Expand Down
101 changes: 101 additions & 0 deletions umu/umu_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from pathlib import Path
from shutil import rmtree, copytree, copy
from pwd import getpwuid
from umu_consts import MODE


class TestGameLauncher(unittest.TestCase):
Expand Down Expand Up @@ -163,6 +164,106 @@ def tearDown(self):
if self.test_local_share.exists():
rmtree(self.test_local_share.as_posix())

def test_copy(self):
"""Test _copy when copying a subset of core files from a system path."""
# Make files read-only
self.test_user_share.joinpath("reaper").chmod(0o0444)
self.test_user_share.joinpath("umu_run.py").chmod(0o0444)
self.test_user_share.joinpath("umu_consts.py").chmod(0o0444)
# Make umu-launcher files read-only
Path(self.test_user_share, "umu-launcher", "compatibilitytool.vdf").chmod(
0o0444
)
Path(self.test_user_share, "umu-launcher", "toolmanifest.vdf").chmod(0o0444)
# Verify read-only before copying to ~/.local/share/umu
self.assertTrue(
self.test_user_share.joinpath("reaper").stat().st_mode == 33060,
"Expected reaper to be read only",
)
self.assertTrue(
self.test_user_share.joinpath("umu_run.py").stat().st_mode == 33060,
"Expected umu_run to be read only",
)
self.assertTrue(
self.test_user_share.joinpath("umu_consts.py").stat().st_mode == 33060,
"Expected umu_consts to be read only",
)
self.assertTrue(
self.test_user_share.joinpath("umu-launcher", "compatibilitytool.vdf")
.stat()
.st_mode
== 33060,
"Expected compat vdf to be read only",
)
self.assertTrue(
self.test_user_share.joinpath("umu-launcher", "toolmanifest.vdf")
.stat()
.st_mode
== 33060,
"Expected manifest vdf to be read only",
)
# Copy from source dir
umu_util._copy(
self.test_user_share.joinpath("reaper"),
self.test_local_share.joinpath("reaper"),
MODE.USER_RWX,
)
umu_util._copy(
self.test_user_share.joinpath("umu_run.py"),
self.test_local_share.joinpath("umu_run.py"),
MODE.USER_RWX,
)
umu_util._copy(
self.test_user_share.joinpath("umu_consts.py"),
self.test_local_share.joinpath("umu_consts.py"),
)
umu_util._copytree(
self.test_user_share.joinpath("umu-launcher"),
self.test_local_share.joinpath("umu-launcher"),
)
# Test reaper for user rwx
# In particular, it's important umu_run and reaper are executable
# otherwise, the launcher will not work
self.assertTrue(
os.access(self.test_local_share.joinpath("reaper"), os.X_OK),
"Expected execute perm for reaper",
)
self.assertTrue(
os.access(self.test_local_share.joinpath("reaper"), os.W_OK),
"Expected write perm for reaper",
)
# Test umu_run.py for user rwx
self.assertTrue(
os.access(self.test_local_share.joinpath("umu_run.py"), os.X_OK),
"Expected execute perm for umu_run",
)
self.assertTrue(
os.access(self.test_local_share.joinpath("umu_run.py"), os.W_OK),
"Expected write perm for umu_run",
)
# Test launcher files for user rw
# Just test one of them since the default is rw and if one of them
# fails then that signals the rest will too
self.assertTrue(
os.access(self.test_local_share.joinpath("umu_consts.py"), os.W_OK),
"Expected write perm for launcher file",
)
# Test umu-launcher
self.assertTrue(
os.access(
self.test_local_share.joinpath("umu-launcher", "compatibilitytool.vdf"),
os.W_OK,
),
"Expected write perm for launcher file",
)
self.assertTrue(
os.access(
self.test_local_share.joinpath("umu-launcher", "toolmanifest.vdf"),
os.W_OK,
),
"Expected write perm for launcher file",
)

def test_ge_proton(self):
"""Test check_env when the code name GE-Proton is set for PROTONPATH.

Expand Down
Loading