From e99cf9c117d673913331eb37b71f690cad5b1884 Mon Sep 17 00:00:00 2001 From: Chris Moultrie <821688+tebriel@users.noreply.github.com> Date: Sat, 7 Mar 2026 10:56:15 -0500 Subject: [PATCH 1/2] grocy: 4.5.0 -> 4.6.0 changelog: https://github.com/grocy/grocy/releases/tag/v4.6.0 --- nixos/modules/services/web-apps/grocy.nix | 5 +- .../0001-Define-configs-with-env-vars.patch | 214 +++++++++--------- ...-config-file-as-it-s-stored-in-etc-g.patch | 48 ++-- pkgs/by-name/gr/grocy/package.nix | 19 +- 4 files changed, 144 insertions(+), 142 deletions(-) diff --git a/nixos/modules/services/web-apps/grocy.nix b/nixos/modules/services/web-apps/grocy.nix index b38f35903b68..be12b854b526 100644 --- a/nixos/modules/services/web-apps/grocy.nix +++ b/nixos/modules/services/web-apps/grocy.nix @@ -149,11 +149,8 @@ in user = "grocy"; group = "nginx"; - # PHP 8.2 and 8.3 are the only version which are supported/tested by upstream: - # https://github.com/grocy/grocy/blob/v4.5.0/README.md#platform-support - phpPackage = pkgs.php83; - inherit (cfg.phpfpm) settings; + inherit (cfg.package.passthru) phpPackage; phpEnv = { GROCY_CONFIG_FILE = "/etc/grocy/config.php"; diff --git a/pkgs/by-name/gr/grocy/0001-Define-configs-with-env-vars.patch b/pkgs/by-name/gr/grocy/0001-Define-configs-with-env-vars.patch index 13efe8613693..c8e5244c038a 100644 --- a/pkgs/by-name/gr/grocy/0001-Define-configs-with-env-vars.patch +++ b/pkgs/by-name/gr/grocy/0001-Define-configs-with-env-vars.patch @@ -1,107 +1,107 @@ -From b1df18da8735ed8c043e5e63753a6524cce620e1 Mon Sep 17 00:00:00 2001 -From: Chris Moultrie -Date: Tue, 4 Mar 2025 08:20:58 -0500 -Subject: [PATCH 1/2] Define configs with env vars - ---- - app.php | 8 ++++---- - controllers/BaseApiController.php | 2 +- - services/DatabaseService.php | 2 +- - services/FilesService.php | 2 +- - services/StockService.php | 2 +- - 5 files changed, 8 insertions(+), 8 deletions(-) - -diff --git a/app.php b/app.php -index 9cdd14e5..c0b30b6e 100644 ---- a/app.php -+++ b/app.php -@@ -12,7 +12,7 @@ use Slim\Views\Blade; - require_once __DIR__ . '/packages/autoload.php'; - - // Load config files --require_once GROCY_DATAPATH . '/config.php'; -+require_once getenv('GROCY_CONFIG_FILE'); - require_once __DIR__ . '/config-dist.php'; // For not in own config defined values we use the default ones - require_once __DIR__ . '/helpers/ConfigurationValidator.php'; - -@@ -52,7 +52,7 @@ catch (EInvalidConfig $ex) - } - - // Create data/viewcache folder if it doesn't exist --$viewcachePath = GROCY_DATAPATH . '/viewcache'; -+$viewcachePath = getenv('GROCY_CACHE_DIR'); - if (!file_exists($viewcachePath)) - { - mkdir($viewcachePath); -@@ -85,7 +85,7 @@ $app = AppFactory::create(); - $container = $app->getContainer(); - $container->set('view', function (Container $container) - { -- return new Blade(__DIR__ . '/views', GROCY_DATAPATH . '/viewcache'); -+ return new Blade(__DIR__ . '/views', getenv('GROCY_CACHE_DIR')); - }); - - $container->set('UrlManager', function (Container $container) -@@ -127,7 +127,7 @@ $errorMiddleware->setDefaultErrorHandler( - - $app->add(new CorsMiddleware($app->getResponseFactory())); - --$app->getRouteCollector()->setCacheFile(GROCY_DATAPATH . '/viewcache/route_cache.php'); -+$app->getRouteCollector()->setCacheFile(getenv('GROCY_CACHE_DIR') . '/route_cache.php'); - - ob_clean(); // No response output before here - $app->run(); -diff --git a/controllers/BaseApiController.php b/controllers/BaseApiController.php -index 5941e348..9283ba93 100644 ---- a/controllers/BaseApiController.php -+++ b/controllers/BaseApiController.php -@@ -162,7 +162,7 @@ class BaseApiController extends BaseController - if (self::$htmlPurifierInstance == null) - { - $htmlPurifierConfig = \HTMLPurifier_Config::createDefault(); -- $htmlPurifierConfig->set('Cache.SerializerPath', GROCY_DATAPATH . '/viewcache'); -+ $htmlPurifierConfig->set('Cache.SerializerPath', getenv('GROCY_CACHE_DIR')); - $htmlPurifierConfig->set('HTML.Allowed', 'div,b,strong,i,em,u,a[href|title|target],iframe[src|width|height|frameborder],ul,ol,li,p[style],br,span[style],img[style|width|height|alt|src],table[border|width|style],tbody,tr,td,th,blockquote,*[style|class|id],h1,h2,h3,h4,h5,h6'); - $htmlPurifierConfig->set('Attr.EnableID', true); - $htmlPurifierConfig->set('HTML.SafeIframe', true); -diff --git a/services/DatabaseService.php b/services/DatabaseService.php -index c5914e49..c249a3bf 100644 ---- a/services/DatabaseService.php -+++ b/services/DatabaseService.php -@@ -145,6 +145,6 @@ class DatabaseService - return GROCY_DATAPATH . '/grocy_' . $dbSuffix . '.db'; - } - -- return GROCY_DATAPATH . '/grocy.db'; -+ return getenv('GROCY_DB_FILE'); - } - } -diff --git a/services/FilesService.php b/services/FilesService.php -index 113a6478..61568bc6 100644 ---- a/services/FilesService.php -+++ b/services/FilesService.php -@@ -10,7 +10,7 @@ class FilesService extends BaseService - - public function __construct() - { -- $this->StoragePath = GROCY_DATAPATH . '/storage'; -+ $this->StoragePath = getenv('GROCY_STORAGE_DIR'); - if (!file_exists($this->StoragePath)) - { - mkdir($this->StoragePath); -diff --git a/services/StockService.php b/services/StockService.php -index 2261db4e..cd438942 100644 ---- a/services/StockService.php -+++ b/services/StockService.php -@@ -1752,7 +1752,7 @@ class StockService extends BaseService - - // User plugins take precedence - $standardPluginPath = __DIR__ . "/../plugins/$pluginName.php"; -- $userPluginPath = GROCY_DATAPATH . "/plugins/$pluginName.php"; -+ $userPluginPath = getenv('GROCY_PLUGIN_DIR') . "/$pluginName.php"; - if (file_exists($userPluginPath)) - { - require_once $userPluginPath; --- -2.47.2 - +From 4c9e6a687162729f96a2de428aa19058c04efe2b Mon Sep 17 00:00:00 2001 +From: Chris Moultrie +Date: Sat, 7 Mar 2026 10:51:40 -0500 +Subject: [PATCH 1/2] Define configs with env vars + +--- + app.php | 8 ++++---- + controllers/BaseApiController.php | 2 +- + services/DatabaseService.php | 2 +- + services/FilesService.php | 2 +- + services/StockService.php | 2 +- + 5 files changed, 8 insertions(+), 8 deletions(-) + +diff --git a/app.php b/app.php +index 9224796a..da5c2357 100644 +--- a/app.php ++++ b/app.php +@@ -12,7 +12,7 @@ use Slim\Factory\AppFactory; + require_once __DIR__ . '/packages/autoload.php'; + + // Load config files +-require_once GROCY_DATAPATH . '/config.php'; ++require_once getenv('GROCY_CONFIG_FILE'); + require_once __DIR__ . '/config-dist.php'; // For not in own config defined values we use the default ones + + // Error reporting definitions +@@ -51,7 +51,7 @@ catch (\Grocy\Helpers\EInvalidConfig $ex) + } + + // Create data/viewcache folder if it doesn't exist +-$viewcachePath = GROCY_DATAPATH . '/viewcache'; ++$viewcachePath = getenv('GROCY_CACHE_DIR'); + if (!file_exists($viewcachePath)) + { + mkdir($viewcachePath); +@@ -84,7 +84,7 @@ $app = AppFactory::create(); + $container = $app->getContainer(); + $container->set('view', function (Container $container) + { +- return new SlimBladeView(__DIR__ . '/views', GROCY_DATAPATH . '/viewcache'); ++ return new SlimBladeView(__DIR__ . '/views', getenv('GROCY_CACHE_DIR')); + }); + + $container->set('UrlManager', function (Container $container) +@@ -126,7 +126,7 @@ $errorMiddleware->setDefaultErrorHandler( + + $app->add(new CorsMiddleware($app->getResponseFactory())); + +-$app->getRouteCollector()->setCacheFile(GROCY_DATAPATH . '/viewcache/route_cache.php'); ++$app->getRouteCollector()->setCacheFile(getenv('GROCY_CACHE_DIR') . '/route_cache.php'); + + ob_clean(); // No response output before here + $app->run(); +diff --git a/controllers/BaseApiController.php b/controllers/BaseApiController.php +index 5941e348..9283ba93 100644 +--- a/controllers/BaseApiController.php ++++ b/controllers/BaseApiController.php +@@ -162,7 +162,7 @@ class BaseApiController extends BaseController + if (self::$htmlPurifierInstance == null) + { + $htmlPurifierConfig = \HTMLPurifier_Config::createDefault(); +- $htmlPurifierConfig->set('Cache.SerializerPath', GROCY_DATAPATH . '/viewcache'); ++ $htmlPurifierConfig->set('Cache.SerializerPath', getenv('GROCY_CACHE_DIR')); + $htmlPurifierConfig->set('HTML.Allowed', 'div,b,strong,i,em,u,a[href|title|target],iframe[src|width|height|frameborder],ul,ol,li,p[style],br,span[style],img[style|width|height|alt|src],table[border|width|style],tbody,tr,td,th,blockquote,*[style|class|id],h1,h2,h3,h4,h5,h6'); + $htmlPurifierConfig->set('Attr.EnableID', true); + $htmlPurifierConfig->set('HTML.SafeIframe', true); +diff --git a/services/DatabaseService.php b/services/DatabaseService.php +index 0b6672fb..94bb9412 100644 +--- a/services/DatabaseService.php ++++ b/services/DatabaseService.php +@@ -145,6 +145,6 @@ class DatabaseService + return GROCY_DATAPATH . '/grocy_' . $dbSuffix . '.db'; + } + +- return GROCY_DATAPATH . '/grocy.db'; ++ return getenv('GROCY_DB_FILE'); + } + } +diff --git a/services/FilesService.php b/services/FilesService.php +index 113a6478..61568bc6 100644 +--- a/services/FilesService.php ++++ b/services/FilesService.php +@@ -10,7 +10,7 @@ class FilesService extends BaseService + + public function __construct() + { +- $this->StoragePath = GROCY_DATAPATH . '/storage'; ++ $this->StoragePath = getenv('GROCY_STORAGE_DIR'); + if (!file_exists($this->StoragePath)) + { + mkdir($this->StoragePath); +diff --git a/services/StockService.php b/services/StockService.php +index da27dacc..ffe714ec 100644 +--- a/services/StockService.php ++++ b/services/StockService.php +@@ -1784,7 +1784,7 @@ class StockService extends BaseService + + // User plugins take precedence + $standardPluginPath = __DIR__ . "/../plugins/$pluginName.php"; +- $userPluginPath = GROCY_DATAPATH . "/plugins/$pluginName.php"; ++ $userPluginPath = getenv('GROCY_PLUGIN_DIR') . "/$pluginName.php"; + if (file_exists($userPluginPath)) + { + require_once $userPluginPath; +-- +2.51.2 + diff --git a/pkgs/by-name/gr/grocy/0002-Remove-check-for-config-file-as-it-s-stored-in-etc-g.patch b/pkgs/by-name/gr/grocy/0002-Remove-check-for-config-file-as-it-s-stored-in-etc-g.patch index fd3139ae936e..44e1d64cf36d 100644 --- a/pkgs/by-name/gr/grocy/0002-Remove-check-for-config-file-as-it-s-stored-in-etc-g.patch +++ b/pkgs/by-name/gr/grocy/0002-Remove-check-for-config-file-as-it-s-stored-in-etc-g.patch @@ -1,24 +1,24 @@ -From f397d6e82d73761358d815a5ba880a05e7e281c3 Mon Sep 17 00:00:00 2001 -From: Chris Moultrie -Date: Tue, 4 Mar 2025 08:21:28 -0500 -Subject: [PATCH 2/2] Remove check for config-file as it's stored in /etc/grocy - ---- - helpers/PrerequisiteChecker.php | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/helpers/PrerequisiteChecker.php b/helpers/PrerequisiteChecker.php -index 8e12a5c5..37b433db 100644 ---- a/helpers/PrerequisiteChecker.php -+++ b/helpers/PrerequisiteChecker.php -@@ -18,7 +18,6 @@ class PrerequisiteChecker - public function checkRequirements() - { - self::checkForPhpVersion(); -- self::checkForConfigFile(); - self::checkForConfigDistFile(); - self::checkForComposer(); - self::checkForPhpExtensions(); --- -2.47.2 - +From ecb28fe2fc0527957c41651cd53e7af4b3cc9047 Mon Sep 17 00:00:00 2001 +From: Chris Moultrie +Date: Sat, 7 Mar 2026 10:52:29 -0500 +Subject: [PATCH 2/2] Remove check for config-file as it's stored in /etc/grocy + +--- + helpers/PrerequisiteChecker.php | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/helpers/PrerequisiteChecker.php b/helpers/PrerequisiteChecker.php +index dbc9c138..cd7d2526 100644 +--- a/helpers/PrerequisiteChecker.php ++++ b/helpers/PrerequisiteChecker.php +@@ -20,7 +20,6 @@ class PrerequisiteChecker + public function checkRequirements() + { + self::checkForPhpVersion(); +- self::checkForConfigFile(); + self::checkForConfigDistFile(); + self::checkForComposer(); + self::checkForPhpExtensions(); +-- +2.51.2 + diff --git a/pkgs/by-name/gr/grocy/package.nix b/pkgs/by-name/gr/grocy/package.nix index 9dcbbad5d67c..ed99074a26b1 100644 --- a/pkgs/by-name/gr/grocy/package.nix +++ b/pkgs/by-name/gr/grocy/package.nix @@ -2,30 +2,32 @@ lib, fetchFromGitHub, fetchYarnDeps, - php, + php85, yarn, fixup-yarn-lock, nixosTests, }: - +let + php = php85; +in php.buildComposerProject2 (finalAttrs: { pname = "grocy"; - version = "4.5.0"; + version = "4.6.0"; src = fetchFromGitHub { owner = "grocy"; repo = "grocy"; tag = "v${finalAttrs.version}"; - hash = "sha256-MnN6TIkNZWT+pAQf0+z5l3hj/7K/d3BfI7VAaUEKG8s="; + hash = "sha256-qdN+stXuwChv6IaFSX2SrSdej7Id/M0UaO2cggAvWdc="; }; # Upstream composer.json file is missing the name, description and license fields composerStrictValidation = false; - vendorHash = "sha256-11+NIZX8i9uwcImwSE0HAeMc/WOCsecpMRqiba1mkrs="; + vendorHash = "sha256-xoPO/LAvMcpvx2sszSj3K9p09izeW1l67KYwpydMdNI="; offlineCache = fetchYarnDeps { yarnLock = finalAttrs.src + "/yarn.lock"; - hash = "sha256-Q+9hUxIfNrfdok39h04rz5I63RxOJ0qk3XlwvD1TcqI="; + hash = "sha256-48+u0NYZZiYvP2ADAkRdL079wmjWMHwPHi8rlDP41Eo="; }; nativeBuildInputs = [ @@ -57,7 +59,10 @@ php.buildComposerProject2 (finalAttrs: { rm -r $out/share ''; - passthru.tests = { inherit (nixosTests) grocy; }; + passthru = { + phpPackage = php; + tests = { inherit (nixosTests) grocy; }; + }; meta = { license = lib.licenses.mit; From 7f5ae56a4bc9da4428ea84cbf4bcaa9f51bf8976 Mon Sep 17 00:00:00 2001 From: Chris Moultrie <821688+tebriel@users.noreply.github.com> Date: Sat, 7 Mar 2026 11:44:30 -0500 Subject: [PATCH 2/2] grocy: Add config abilities to module --- nixos/modules/services/web-apps/grocy.nix | 54 ++++++++++++++++++++++- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/nixos/modules/services/web-apps/grocy.nix b/nixos/modules/services/web-apps/grocy.nix index be12b854b526..d6095b50fa8a 100644 --- a/nixos/modules/services/web-apps/grocy.nix +++ b/nixos/modules/services/web-apps/grocy.nix @@ -79,22 +79,39 @@ in culture = mkOption { type = types.enum [ - "de" - "en" + "bg_BG" + "ca" + "cs" "da" + "de" + "el_GR" + "en" "en_GB" "es" + "et_EE" + "fi" "fr" + "he_IL" "hu" "it" + "ja" + "ko_KR" + "lt" "nl" "no" "pl" "pt_BR" + "pt_PT" + "ro_RO" "ru" "sk_SK" + "sl" "sv_SE" + "ta" "tr" + "uk" + "zh_CN" + "zh_TW" ]; default = "en"; description = '' @@ -119,6 +136,37 @@ in ''; }; }; + + entryPage = mkOption { + # https://github.com/grocy/grocy/blob/v4.6.0/config-dist.php#L75-L78 + type = types.enum [ + "stock" + "shoppinglist" + "recipes" + "chores" + "tasks" + "batteries" + "equipment" + "calendar" + "mealplan" + ]; + default = "stock"; + description = '' + Specify an custom homepage if desired. + ''; + }; + }; + + extraConfig = mkOption { + type = types.lines; + default = ""; + description = '' + These lines go at the end of config.php verbatim. + ''; + example = '' + Setting('FEATURE_FLAG_RECIPES', false); + Setting('FEATURE_FLAG_STOCK_PRODUCT_FREEZING', false); + ''; }; }; @@ -129,6 +177,8 @@ in Setting('CURRENCY', '${cfg.settings.currency}'); Setting('CALENDAR_FIRST_DAY_OF_WEEK', '${toString cfg.settings.calendar.firstDayOfWeek}'); Setting('CALENDAR_SHOW_WEEK_OF_YEAR', ${boolToString cfg.settings.calendar.showWeekNumber}); + Setting('ENTRY_PAGE', '${cfg.settings.entryPage}'); + ${cfg.extraConfig} ''; users.users.grocy = {