Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 0 additions & 5 deletions pkgs/by-name/ne/nexusmods-app/deps.json

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

23 changes: 23 additions & 0 deletions pkgs/by-name/ne/nexusmods-app/game-hashes/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{ fetchurl }:
let
release = "ved4b249e2c35952c";
owner = "Nexus-Mods";
repo = "game-hashes";
repoURL = "https://github.com/${owner}/${repo}";

# Define a binding so that `update-source-version` can find it
src = fetchurl {
url = "${repoURL}/releases/download/${release}/game_hashes_db.zip";
hash = "sha256-9xJ8yfLRkIV0o++NHK2igd2l83/tsgWc5cuwZO2zseY=";
passthru = {
inherit
src # Also for `update-source-version` support
release
owner
repo
repoURL
;
};
};
in
src
56 changes: 56 additions & 0 deletions pkgs/by-name/ne/nexusmods-app/game-hashes/update.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#!/usr/bin/env nix-shell
#! nix-shell -i bash -p bash common-updater-scripts gh

set -eu -o pipefail

# Set a default attrpath to allow running this update script directly
export UPDATE_NIX_ATTR_PATH="${UPDATE_NIX_ATTR_PATH:-"nexusmods-app.gameHashes"}"

self=$(realpath "$0")
dir=$(dirname "$self")
cd "$dir"/../../../../../

old_release=$(
nix-instantiate --eval --raw \
--attr "$UPDATE_NIX_ATTR_PATH.release"
)

echo "Looking up latest game_hashes_db" >&2
new_release=$(
gh --repo Nexus-Mods/game-hashes \
release list \
--limit 1 \
--exclude-drafts \
--exclude-pre-releases \
--json tagName \
--jq .[].tagName
)

echo "Latest release is $new_release" >&2

if [ "$old_release" = "$new_release" ]; then
echo "Already up to date"
exit
fi

old_release_escaped=$(echo "$old_release" | sed 's#[$^*\\.[|]#\\&#g')
new_release_escaped=$(echo "$new_release" | sed 's#[$^*\\.[|]#\\&#g')
url=$(
nix-instantiate --eval --raw --attr "$UPDATE_NIX_ATTR_PATH.url" |
sed "s|$old_release_escaped|$new_release_escaped|"
)

echo "Downloading and hashing game_hashes_db" >&2
hash=$(
nix --extra-experimental-features nix-command \
hash convert --hash-algo sha256 --to sri \
"$(nix-prefetch-url "$url" --type sha256)"
)

echo "Updating source" >&2
update-source-version \
"$UPDATE_NIX_ATTR_PATH" \
"$new_release" \
"$hash" \
--version-key=release \
--file="$dir"/default.nix
38 changes: 20 additions & 18 deletions pkgs/by-name/ne/nexusmods-app/package.nix
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
_7zz,
avalonia,
buildDotnetModule,
callPackage,
desktop-file-utils,
dotnetCorePackages,
fetchgit,
imagemagick,
lib,
xdg-utils,
nix-update-script,
pname ? "nexusmods-app",
}:
let
Expand All @@ -23,15 +23,17 @@ let
in
buildDotnetModule (finalAttrs: {
inherit pname;
version = "0.14.3";
version = "0.15.2";

src = fetchgit {
url = "https://github.com/Nexus-Mods/NexusMods.App.git";
rev = "refs/tags/v${finalAttrs.version}";
hash = "sha256-B2gIRVeaTwYEnESMovwEJgdmLwRNA7/nJs7opNhiyyA=";
hash = "sha256-WI6ulYDPOBGGt3snimCHswuIaII1aWNT/TZqvJxrQRQ=";
fetchSubmodules = true;
};

gameHashes = callPackage ./game-hashes { };

enableParallelBuilding = false;

# If the whole solution is published, there seems to be a race condition where
Expand Down Expand Up @@ -63,9 +65,18 @@ buildDotnetModule (finalAttrs: {
# for some reason these tests fail (intermittently?) with a zero timestamp
touch tests/NexusMods.UI.Tests/WorkspaceSystem/*.verified.png

# Assertion assumes version is set to 0.0.1
substituteInPlace tests/NexusMods.Telemetry.Tests/TrackingDataSenderTests.cs \
--replace-fail 'cra_ct=v0.0.1' 'cra_ct=v${finalAttrs.version}'
# Specify a fixed date to improve build reproducibility
echo "1970-01-01T00:00:00Z" >buildDate.txt
substituteInPlace src/NexusMods.Sdk/NexusMods.Sdk.csproj \
--replace-fail '$(BaseIntermediateOutputPath)buildDate.txt' "$(realpath buildDate.txt)"

# Use a pinned version of the game hashes db
substituteInPlace src/NexusMods.Games.FileHashes/NexusMods.Games.FileHashes.csproj \
--replace-fail '$(BaseIntermediateOutputPath)games_hashes_db.zip' "$gameHashes"

# Use a vendored version of the nexus API's games.json data
substituteInPlace src/NexusMods.Networking.NexusWebApi/NexusMods.Networking.NexusWebApi.csproj \
--replace-fail '$(BaseIntermediateOutputPath)games.json' ${./vendored/games.json}
'';

makeWrapperArgs = [
Expand Down Expand Up @@ -127,6 +138,7 @@ buildDotnetModule (finalAttrs: {

dotnetTestFlags = [
"--environment=USER=nobody"
"--property:Version=${finalAttrs.version}"
"--property:DefineConstants=${lib.strings.concatStringsSep "%3B" constants}"
];

Expand All @@ -137,19 +149,9 @@ buildDotnetModule (finalAttrs: {
];

disabledTests = [
# Fails attempting to download game hashes DB from github:
# HttpRequestException : Resource temporarily unavailable (github.com:443)
"NexusMods.DataModel.SchemaVersions.Tests.LegacyDatabaseSupportTests.TestDatabase"
"NexusMods.DataModel.SchemaVersions.Tests.MigrationSpecificTests.TestsFor_0001_ConvertTimestamps.OldTimestampsAreInRange"
"NexusMods.DataModel.SchemaVersions.Tests.MigrationSpecificTests.TestsFor_0003_FixDuplicates.No_Duplicates"
"NexusMods.DataModel.SchemaVersions.Tests.MigrationSpecificTests.TestsFor_0004_RemoveGameFiles.Test"

# Fails attempting to fetch SMAPI version data from github:
# https://github.com/erri120/smapi-versions/raw/main/data/game-smapi-versions.json
"NexusMods.Games.StardewValley.Tests.SMAPIGameVersionDiagnosticEmitterTests.Test_TryGetLastSupportedSMAPIVersion"

# Fails attempting to fetch game info from NexusMods API
"NexusMods.Networking.NexusWebApi.Tests.LocalMappingCacheTests.Test_Parse"
]
++ lib.optionals (!_7zz.meta.unfree) [
"NexusMods.Games.FOMOD.Tests.FomodXmlInstallerTests.InstallsFilesSimple_UsingRar"
Expand Down Expand Up @@ -189,12 +191,12 @@ buildDotnetModule (finalAttrs: {
};
};

passthru.updateScript = nix-update-script { };
passthru.updateScript = ./update.sh;

meta = {
mainProgram = "NexusMods.App";
homepage = "https://github.com/Nexus-Mods/NexusMods.App";
changelog = "https://github.com/Nexus-Mods/NexusMods.App/releases/tag/${finalAttrs.src.rev}";
changelog = "https://github.com/Nexus-Mods/NexusMods.App/releases/tag/v${finalAttrs.version}";
license = [ lib.licenses.gpl3Plus ];
maintainers = with lib.maintainers; [
l0b0
Expand Down
24 changes: 24 additions & 0 deletions pkgs/by-name/ne/nexusmods-app/update.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/usr/bin/env nix-shell
#! nix-shell -i bash -p bash nix-update

set -eu -o pipefail

# Set a default attrpath to allow running this update script directly
export UPDATE_NIX_ATTR_PATH="${UPDATE_NIX_ATTR_PATH:-"nexusmods-app"}"

self=$(realpath "$0")
dir=$(dirname "$self")
cd "$dir"/../../../../

# Update vendored files
"$dir"/vendored/update.sh

# Update game_hashes_db
UPDATE_NIX_ATTR_PATH="$UPDATE_NIX_ATTR_PATH.gameHashes" \
"$dir"/game-hashes/update.sh

url=$(
nix-instantiate --eval --raw \
--attr "$UPDATE_NIX_ATTR_PATH.meta.homepage"
)
nix-update --url "$url"
31 changes: 31 additions & 0 deletions pkgs/by-name/ne/nexusmods-app/vendored/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
This directory contains a vendored copy of `games.json`, along with tooling to generate it.

## Purpose

The games data is fetched at runtime by NexusMods.App, however it is also included at build time for two reasons:

1. It allows tests to run against real data.
2. It is used as cached data, speeding up the app's initial run.

It is not vital for the file to contain all games, however ideally it should contain all games _supported_ by this version of NexusMods.App.
That way the initial run's cached data is more useful.

If this file grows too large, because we are including too many games, we can patch the `csproj` build spec so that `games.json` is not used at build time.
We would also need to patch or disable any tests that rely on it.

## Generating

`games.json` is generated automatically by `update.sh`, using data from [nexusmods' API][url] and the games listed in `game-ids.nix`.

To add a new game to `games.json`:
- Inspect the [nexusmods endpoint][url] to find the game's name and ID
- Add the name and ID to `game-ids.nix`
- Run `update.sh`
- Commit the result

> [!Note]
> Running `update.sh` may also update the existing games, so you may wish to create two separate commits using `git add --patch`.
> One for updating the existing data and another for adding the new game.

[url]: https://data.nexusmods.com/file/nexus-data/games.json

11 changes: 11 additions & 0 deletions pkgs/by-name/ne/nexusmods-app/vendored/game-ids.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# This file lists games to be included in the vendored games.json file.
# It is not critical to include all games, other than those referenced by the test suite.
# Ideally, all games supported by the app will be included, as this can improve first-run performance.
{
# keep-sorted start case=no numeric=yes
"Baldur's Gate 3" = 3474;
"Cyberpunk 2077" = 3333;
"Mount & Blade II: Bannerlord" = 3174;
"Stardew Valley" = 1303;
# keep-sorted end
}
58 changes: 58 additions & 0 deletions pkgs/by-name/ne/nexusmods-app/vendored/games.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
[
{
"id": 1303,
"name": "Stardew Valley",
"name_lower": "stardew valley",
"forum_url": "https://forums.nexusmods.com/games/19-stardew-valley/",
"nexusmods_url": "https://www.nexusmods.com/stardewvalley",
"genre": "Simulation",
"file_count": 137612,
"downloads": 592183501,
"domain_name": "stardewvalley",
"approved_date": 1457432329,
"mods": 24655,
"collections": 3570
},
{
"id": 3174,
"name": "Mount & Blade II: Bannerlord",
"name_lower": "mount & blade ii: bannerlord",
"forum_url": "https://forums.nexusmods.com/games/9-mount-blade-ii-bannerlord/",
"nexusmods_url": "https://www.nexusmods.com/mountandblade2bannerlord",
"genre": "Strategy",
"file_count": 49182,
"downloads": 111421397,
"domain_name": "mountandblade2bannerlord",
"approved_date": 1582898627,
"mods": 6136,
"collections": 321
},
{
"id": 3333,
"name": "Cyberpunk 2077",
"name_lower": "cyberpunk 2077",
"forum_url": "https://forums.nexusmods.com/games/1-cyberpunk-2077/",
"nexusmods_url": "https://www.nexusmods.com/cyberpunk2077",
"genre": "Action",
"file_count": 118327,
"downloads": 825382927,
"domain_name": "cyberpunk2077",
"approved_date": 1607433331,
"mods": 16707,
"collections": 1910
},
{
"id": 3474,
"name": "Baldur's Gate 3",
"name_lower": "baldur's gate 3",
"forum_url": "https://forums.nexusmods.com/games/2-baldurs-gate-3/",
"nexusmods_url": "https://www.nexusmods.com/baldursgate3",
"genre": "RPG",
"file_count": 100954,
"downloads": 325304689,
"domain_name": "baldursgate3",
"approved_date": 1602863114,
"mods": 14186,
"collections": 3703
}
]
53 changes: 53 additions & 0 deletions pkgs/by-name/ne/nexusmods-app/vendored/update.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/usr/bin/env nix-shell
#! nix-shell -i bash -p bash curl jq

set -eu -o pipefail

url='https://data.nexusmods.com/file/nexus-data/games.json'
self=$(realpath "$0")
dir=$(dirname "$self")
tmp=$(mktemp)

cd "$dir"/../../../../../

ids=$(
nix-instantiate --eval --json \
--argstr file "$dir"/game-ids.nix \
--expr '{file}: builtins.attrValues (import file)'
)

echo "Fetching games data" >&2
curl "$url" \
--silent \
--show-error \
--location |
jq --argjson ids "$ids" \
'map(select( .id | IN($ids[]) )) | sort_by(.id)' \
>"$tmp"

echo "Validating result" >&2
nix-instantiate --eval --strict \
--argstr idsNix "$dir"/game-ids.nix \
--argstr gamesJson "$tmp" \
--expr '
{
idsNix,
gamesJson,
lib ? import <nixpkgs/lib>,
}:
let
ids = import idsNix;
games = lib.importJSON gamesJson;
in
lib.forEach games (
{ id, name, ... }:
lib.throwIfNot
(id == ids.${name})
"${name}: id ${toString id} does not match ${toString ids.${name}}"
null
)
' \
>/dev/null

echo "Installing games.json to $dir" >&2
mv --force "$tmp" "$dir"/games.json
Loading