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, devshell, package, and wrapper script #18

Open
wants to merge 18 commits into
base: main
Choose a base branch
from
Open
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: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
__pycache__/
/.venv/
*.egg-info/
build/
build/

# Nix
/result
26 changes: 16 additions & 10 deletions factorio_sat/assets/fetch.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,21 @@
import json
import shutil
import sys
import os

from os import path

ASSETS_DIR = path.join(os.getenv("XDG_DATA_HOME"), "factorio-sat/assets")

try:
from luaparser import ast
except ModuleNotFoundError:
print('"luaparser" not installed: recipe fetching will be disabled')
ast = None


def fetch_tilemaps(base_directory: str):
graphics_directory = path.join(base_directory, 'graphics', 'entity')
def copy_game_tilemaps(base_dir: str, assets_dir: str):
graphics_dir = path.join(base_dir, 'graphics', 'entity')

files = [
('assembling-machine-1', 'hr-assembling-machine-1.png'),
Expand Down Expand Up @@ -46,8 +50,9 @@ def fetch_tilemaps(base_directory: str):
]

for file in files:
source = path.join(graphics_directory, *file)
destination = path.join(path.dirname(__file__), file[-1])
source = path.join(graphics_dir, *file)

destination = path.join(assets_dir, file[-1])

print('Copying: {} -> {}'.format(source, destination))
shutil.copyfile(source, destination)
Expand Down Expand Up @@ -130,9 +135,9 @@ def get_recipes_for_variant(data, variant):
return recipes


def fetch_recipes(base_directory):
def copy_game_recipes(base_dir, assets_dir):
data = []
for file in glob.glob(path.join(base_directory, 'prototypes', 'recipe', '*.lua')):
for file in glob.glob(path.join(base_dir, 'prototypes', 'recipe', '*.lua')):
with open(file) as f:
text = f.read()

Expand All @@ -142,7 +147,7 @@ def fetch_recipes(base_directory):
data += entry

for variant in ('normal', 'expensive'):
with open(path.join(path.dirname(__file__), f'{variant}-recipes.json'), 'w') as f:
with open(path.join(assets_dir, f'{variant}-recipes.json'), 'w') as f:
json.dump(get_recipes_for_variant(data, variant), f)


Expand Down Expand Up @@ -170,11 +175,12 @@ def main():
if not path.exists(game_directory):
raise RuntimeError('Factorio not found at: {}'.format(game_directory))

base_directory = path.join(game_directory, 'data', 'base')
game_base_dir = path.join(game_directory, 'data', 'base')

fetch_tilemaps(base_directory)
os.makedirs(ASSETS_DIR, exist_ok=True)
copy_game_tilemaps(game_base_dir, ASSETS_DIR)
if ast is not None:
fetch_recipes(base_directory)
copy_game_recipes(game_base_dir, ASSETS_DIR)


if __name__ == '__main__':
Expand Down
32 changes: 17 additions & 15 deletions factorio_sat/tilemaps.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import os

from typing import *
from os import path

from OpenGL.GL import *
from PIL import Image

ASSETS_DIR = os.path.join(os.getenv("XDG_DATA_HOME"), "factorio-sat/assets")

def get_texture_size(texture: int) -> Tuple[int, int]:
glBindTexture(GL_TEXTURE_2D, texture)
Expand Down Expand Up @@ -88,29 +91,28 @@ def render(self, x, y, lower=(0, 0), upper=(1, 1)):

def init():
global BELT, UNDERGROUND, SPLITTER_EAST, SPLITTER_WEST, SPLITTER_NORTH, SPLITTER_SOUTH, INSERTER_PLATFORM, INSERTER_HAND_BASE, INSERTER_HAND_OPEN, INSERTER_HAND_CLOSED, ASSEMBLING_MACHINE
base_path = path.join(path.dirname(__file__), 'assets')

BELT = Tilemap(load_image(path.join(base_path, 'hr-transport-belt.png')), (128, 128), PIXELS_PER_UNIT)
UNDERGROUND = Tilemap(load_image(path.join(base_path, 'hr-underground-belt-structure.png')), (192, 192), PIXELS_PER_UNIT)
BELT = Tilemap(load_image(path.join(ASSETS_DIR, 'hr-transport-belt.png')), (128, 128), PIXELS_PER_UNIT)
UNDERGROUND = Tilemap(load_image(path.join(ASSETS_DIR, 'hr-underground-belt-structure.png')), (192, 192), PIXELS_PER_UNIT)
SPLITTER_EAST = [
Tilemap(load_image(path.join(base_path, 'hr-splitter-east.png')), (90, 84), PIXELS_PER_UNIT),
Tilemap(load_image(path.join(base_path, 'hr-splitter-east-top_patch.png')), (90, 104), PIXELS_PER_UNIT),
Tilemap(load_image(path.join(ASSETS_DIR, 'hr-splitter-east.png')), (90, 84), PIXELS_PER_UNIT),
Tilemap(load_image(path.join(ASSETS_DIR, 'hr-splitter-east-top_patch.png')), (90, 104), PIXELS_PER_UNIT),
]
SPLITTER_WEST = [
Tilemap(load_image(path.join(base_path, 'hr-splitter-west.png')), (90, 86), PIXELS_PER_UNIT),
Tilemap(load_image(path.join(base_path, 'hr-splitter-west-top_patch.png')), (90, 96), PIXELS_PER_UNIT),
Tilemap(load_image(path.join(ASSETS_DIR, 'hr-splitter-west.png')), (90, 86), PIXELS_PER_UNIT),
Tilemap(load_image(path.join(ASSETS_DIR, 'hr-splitter-west-top_patch.png')), (90, 96), PIXELS_PER_UNIT),
]
SPLITTER_SOUTH = Tilemap(load_image(path.join(base_path, 'hr-splitter-south.png')), (164, 64), PIXELS_PER_UNIT)
SPLITTER_NORTH = Tilemap(load_image(path.join(base_path, 'hr-splitter-north.png')), (160, 70), PIXELS_PER_UNIT)
SPLITTER_SOUTH = Tilemap(load_image(path.join(ASSETS_DIR, 'hr-splitter-south.png')), (164, 64), PIXELS_PER_UNIT)
SPLITTER_NORTH = Tilemap(load_image(path.join(ASSETS_DIR, 'hr-splitter-north.png')), (160, 70), PIXELS_PER_UNIT)

INSERTER_PLATFORM = Tilemap(load_image(path.join(base_path, 'hr-inserter-platform.png')), (105, 79),
PIXELS_PER_UNIT), Tilemap(load_image(path.join(base_path, 'hr-long-handed-inserter-platform.png')), (105, 79), PIXELS_PER_UNIT)
INSERTER_PLATFORM = Tilemap(load_image(path.join(ASSETS_DIR, 'hr-inserter-platform.png')), (105, 79),
PIXELS_PER_UNIT), Tilemap(load_image(path.join(ASSETS_DIR, 'hr-long-handed-inserter-platform.png')), (105, 79), PIXELS_PER_UNIT)

INSERTER_HAND_BASE = load_image(path.join(base_path, 'hr-inserter-hand-base.png')), load_image(path.join(base_path, 'hr-long-handed-inserter-hand-base.png'))
INSERTER_HAND_OPEN = load_image(path.join(base_path, 'hr-inserter-hand-open.png')), load_image(path.join(base_path, 'hr-long-handed-inserter-hand-open.png'))
INSERTER_HAND_CLOSED = load_image(path.join(base_path, 'hr-inserter-hand-closed.png')), load_image(path.join(base_path, 'hr-long-handed-inserter-hand-closed.png'))
INSERTER_HAND_BASE = load_image(path.join(ASSETS_DIR, 'hr-inserter-hand-base.png')), load_image(path.join(ASSETS_DIR, 'hr-long-handed-inserter-hand-base.png'))
INSERTER_HAND_OPEN = load_image(path.join(ASSETS_DIR, 'hr-inserter-hand-open.png')), load_image(path.join(ASSETS_DIR, 'hr-long-handed-inserter-hand-open.png'))
INSERTER_HAND_CLOSED = load_image(path.join(ASSETS_DIR, 'hr-inserter-hand-closed.png')), load_image(path.join(ASSETS_DIR, 'hr-long-handed-inserter-hand-closed.png'))

ASSEMBLING_MACHINE = Tilemap(load_image(path.join(base_path, 'hr-assembling-machine-1.png')), (214, 226), PIXELS_PER_UNIT)
ASSEMBLING_MACHINE = Tilemap(load_image(path.join(ASSETS_DIR, 'hr-assembling-machine-1.png')), (214, 226), PIXELS_PER_UNIT)


PIXELS_PER_UNIT = 64
Expand Down
42 changes: 42 additions & 0 deletions flake.lock

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

43 changes: 43 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
inputs = {
nixpkgs.url = "github:nixos/nixpkgs";
systems.url = "github:nix-systems/default-linux";
};

outputs = { self, nixpkgs, systems }:
let
inherit (nixpkgs) lib;

eachSystem = lib.genAttrs (import systems);
pkgsFor = eachSystem (system:
import nixpkgs {
localSystem.system = system;
overlays = [ self.overlays.default ];
});
in {
apps = lib.mapAttrs (system: pkgs: {
default = self.apps.${system}.cli;
cli = {
type = "app";
program = lib.getExe pkgs.factorio-sat-cli;
};
}) pkgsFor;

devShells = lib.mapAttrs (system: pkgs: {
default = pkgs.mkShell {
inputsFrom = with pkgs; [ factorio-sat ];
packages = with pkgs; [ factorio-sat factorio-sat-cli ];
};
}) pkgsFor;

overlays = { default = import ./nix/overlay.nix { inherit self; }; };

packages = lib.mapAttrs (system: pkgs: {
inherit (pkgs) factorio-sat factorio-sat-cli;
default = self.packages.${system}.factorio-sat;
}) pkgsFor;

formatter =
eachSystem (system: nixpkgs.legacyPackages.${system}.nixfmt-classic);
};
}
27 changes: 27 additions & 0 deletions nix/antlr/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{ lib, stdenv, callPackage, python3, libuuid }:
let
# This import is a builder extracted from Nixpkgs.
mkAntlr = callPackage ./mk-antlr.nix { };

versions."4.7.2" = {

antlr = (mkAntlr {
version = "4.7.2";
sourceSha256 = "sha256-kta+K/c6cUdOuW6jWMpX4tA22GXsaDBwtalzw4z+gN4=";
jarSha256 = "sha256-aFI4bXl17/KRcdrgAswiMlFRDTXyka4neUjzgaezgLQ=";
extraCppBuildInputs = lib.optional stdenv.isLinux libuuid;
extraCppCmakeFlags = [ "-DANTLR4_INSTALL=ON" ];
}).antlr;

pythonOverrides = pypkgs: pypkgs0: {
antlr4-python3-runtime = pypkgs.toPythonModule
((pypkgs0.antlr4-python3-runtime.override {
antlr4 = versions."4.7.2".antlr;
}).overridePythonAttrs {
postPatch = "";
doCheck = false;
});
};

};
in versions
98 changes: 98 additions & 0 deletions nix/antlr/mk-antlr.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# Copied from Nixpkgs
# <https://github.com/NixOS/nixpkgs/blob/df41961bd4b7e838cb997543ea1297f4cbd7da15/pkgs/development/tools/parsing/antlr/4.nix>

{ lib, stdenv, fetchurl, jre, fetchFromGitHub, cmake, ninja, pkg-config

# darwin only
, CoreFoundation ? null

# ANTLR 4.8 & 4.9
, libuuid

# ANTLR 4.9
, utf8cpp }:
{ version, sourceSha256, jarSha256, extraCppBuildInputs ? [ ]
, extraCppCmakeFlags ? [ ] }: rec {
source = fetchFromGitHub {
owner = "antlr";
repo = "antlr4";
rev = version;
sha256 = sourceSha256;
};

antlr = stdenv.mkDerivation {
pname = "antlr";
inherit version;

src = fetchurl {
url = "https://www.antlr.org/download/antlr-${version}-complete.jar";
sha256 = jarSha256;
};

dontUnpack = true;

installPhase = ''
mkdir -p "$out"/{share/java,bin}
cp "$src" "$out/share/java/antlr-${version}-complete.jar"

echo "#! ${stdenv.shell}" >> "$out/bin/antlr"
echo "'${jre}/bin/java' -cp '$out/share/java/antlr-${version}-complete.jar:$CLASSPATH' -Xmx500M org.antlr.v4.Tool \"\$@\"" >> "$out/bin/antlr"

echo "#! ${stdenv.shell}" >> "$out/bin/antlr-parse"
echo "'${jre}/bin/java' -cp '$out/share/java/antlr-${version}-complete.jar:$CLASSPATH' -Xmx500M org.antlr.v4.gui.Interpreter \"\$@\"" >> "$out/bin/antlr-parse"

echo "#! ${stdenv.shell}" >> "$out/bin/grun"
echo "'${jre}/bin/java' -cp '$out/share/java/antlr-${version}-complete.jar:$CLASSPATH' org.antlr.v4.gui.TestRig \"\$@\"" >> "$out/bin/grun"

chmod a+x "$out/bin/antlr" "$out/bin/antlr-parse" "$out/bin/grun"
ln -s "$out/bin/antlr"{,4}
ln -s "$out/bin/antlr"{,4}-parse
'';

inherit jre;

passthru = {
inherit runtime;
jarLocation = "${antlr}/share/java/antlr-${version}-complete.jar";
};

meta = with lib; {
description = "Powerful parser generator";
longDescription = ''
ANTLR (ANother Tool for Language Recognition) is a powerful parser
generator for reading, processing, executing, or translating structured
text or binary files. It's widely used to build languages, tools, and
frameworks. From a grammar, ANTLR generates a parser that can build and
walk parse trees.
'';
homepage = "https://www.antlr.org/";
sourceProvenance = with sourceTypes; [ binaryBytecode ];
license = licenses.bsd3;
platforms = platforms.unix;
};
};

runtime = {
cpp = stdenv.mkDerivation {
pname = "antlr-runtime-cpp";
inherit version;
src = source;
sourceRoot = "${source.name}/runtime/Cpp";

outputs = [ "out" "dev" "doc" ];

nativeBuildInputs = [ cmake ninja pkg-config ];
buildInputs = lib.optional stdenv.isDarwin CoreFoundation
++ extraCppBuildInputs;

cmakeFlags = extraCppCmakeFlags;

meta = with lib; {
description = "C++ target for ANTLR 4";
homepage = "https://www.antlr.org/";
license = licenses.bsd3;
platforms = platforms.unix;
};
};
};
}
39 changes: 39 additions & 0 deletions nix/cli.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{ lib, writeShellApplication, factorio-sat, }:
let
exes = lib.pipe (builtins.readDir "${factorio-sat}/bin") [
(lib.filterAttrs
(name: kind: kind == "regular" && !(lib.hasPrefix "." name)))
(lib.mapAttrsToList (name: _: name))
];
in writeShellApplication {
name = "factorio-sat";
text = ''
show_cmds() {
echo '${lib.concatStringsSep ", " exes}'
}

if [[ $# -eq 0 ]]; then
echo 'Need subcommand.'
echo
show_cmds
exit 1
fi

exe="$1"
shift 1
case "$exe" in
${
lib.concatMapStrings (exe: ''
${exe})
'${lib.getExe' factorio-sat exe}' "$@"
;;
'') exes
}
*)
echo "No such subcommand: $exe"
echo
show_cmds
exit 1
esac
'';
}
Loading
Loading