mirror of
https://github.com/NixOS/nixpkgs.git
synced 2026-09-29 11:20:10 +00:00
grist-core: init at 1.7.19 (#566754)
This commit is contained in:
@@ -26943,6 +26943,12 @@
|
||||
github = "sinanmohd";
|
||||
githubId = 69694713;
|
||||
};
|
||||
sinavir = {
|
||||
name = "Sinavir";
|
||||
email = "sinavir@sinavir.fr";
|
||||
github = "sinavir";
|
||||
githubId = 36380103;
|
||||
};
|
||||
sinics = {
|
||||
name = "Zhifan";
|
||||
email = "nonno.felice69uwu@gmail.com";
|
||||
|
||||
@@ -58,6 +58,8 @@
|
||||
|
||||
- [snowflake-prometheus-exporter](https://github.com/grafana/snowflake-prometheus-exporter), a Prometheus exporter for Snowflake metrics. Available as [services.prometheus.exporters.snowflake](#opt-services.prometheus.exporters.snowflake.enable).
|
||||
|
||||
- [Grist](https://www.getgrist.com/), a powerful spreadsheet alternative. Available as [services.grist](#opt-services.grist.enable).
|
||||
|
||||
- [Pumpkin](https://pumpkinmc.org/), a Minecraft server implementation written entirely in Rust, focused on performance and configurability. Available as [services.pumpkin](#opt-services.pumpkin.enable).
|
||||
|
||||
- [feishin](https://github.com/jeffvli/feishin), a modern self-hosted music player. Available as [services.feishin](#opt-services.feishin.enable).
|
||||
|
||||
@@ -1731,6 +1731,7 @@
|
||||
./services/web-apps/goupile.nix
|
||||
./services/web-apps/grav.nix
|
||||
./services/web-apps/greenlight.nix
|
||||
./services/web-apps/grist.nix
|
||||
./services/web-apps/grocy.nix
|
||||
./services/web-apps/guacamole-client.nix
|
||||
./services/web-apps/guacamole-server.nix
|
||||
|
||||
247
nixos/modules/services/web-apps/grist.nix
Normal file
247
nixos/modules/services/web-apps/grist.nix
Normal file
@@ -0,0 +1,247 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib)
|
||||
concatMapStringsSep
|
||||
concatStringsSep
|
||||
mkDefault
|
||||
mkEnableOption
|
||||
mkIf
|
||||
mkOption
|
||||
mkPackageOption
|
||||
optional
|
||||
types
|
||||
;
|
||||
|
||||
cfg = config.services.grist;
|
||||
in
|
||||
{
|
||||
options.services.grist = {
|
||||
enable = mkEnableOption "Grist";
|
||||
|
||||
package = mkPackageOption pkgs "grist-core" { };
|
||||
|
||||
enableEnterprise = mkEnableOption "Grist enterprise code";
|
||||
|
||||
enableRedis = mkEnableOption "Grist redis data store";
|
||||
|
||||
environment = mkOption {
|
||||
type = types.submodule {
|
||||
freeformType = types.attrsOf (types.nullOr types.str);
|
||||
|
||||
options = {
|
||||
GRIST_DATA_DIR = mkOption {
|
||||
type = types.path;
|
||||
default = "/var/lib/grist-core/docs";
|
||||
description = ''
|
||||
Directory in which to store documents.
|
||||
'';
|
||||
};
|
||||
|
||||
GRIST_INST_DIR = mkOption {
|
||||
type = types.path;
|
||||
default = "/var/lib/grist-core";
|
||||
description = ''
|
||||
Path to Grist instance configuration files, for Grist server.
|
||||
'';
|
||||
};
|
||||
|
||||
GRIST_USER_ROOT = mkOption {
|
||||
type = types.path;
|
||||
default = "/var/lib/grist-core";
|
||||
description = ''
|
||||
An extra path to look for plugins in - Grist will scan for plugins in $GRIST_USER_ROOT/plugins.
|
||||
'';
|
||||
};
|
||||
|
||||
GRIST_HOST = mkOption {
|
||||
type = types.str;
|
||||
default = "127.0.0.1";
|
||||
description = ''
|
||||
Address to listen on
|
||||
'';
|
||||
};
|
||||
|
||||
GVISOR_FLAGS = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [
|
||||
"-rootless"
|
||||
];
|
||||
apply = concatStringsSep " ";
|
||||
description = ''
|
||||
The flags that are passed on to gVisor when creating a sandbox.
|
||||
'';
|
||||
};
|
||||
|
||||
GRIST_SANDBOX_FLAVOR = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = "gvisor";
|
||||
description = ''
|
||||
Sandbox to use for grist documents. Only "gvisor" is supported.
|
||||
'';
|
||||
};
|
||||
|
||||
GVISOR_AVAILABLE = mkOption {
|
||||
type = types.str;
|
||||
default = "1";
|
||||
readOnly = true;
|
||||
description = ''
|
||||
Whether gvisor is available for Grist.
|
||||
'';
|
||||
};
|
||||
|
||||
TYPEORM_DATABASE = mkOption {
|
||||
type = types.str;
|
||||
default = "/var/lib/grist-core/db.sqlite";
|
||||
description = ''
|
||||
Database filename for sqlite or database name for other db types.
|
||||
'';
|
||||
};
|
||||
|
||||
TYPEORM_TYPE = mkOption {
|
||||
type = types.enum [
|
||||
"sqlite"
|
||||
"postgres"
|
||||
];
|
||||
default = "sqlite";
|
||||
description = ''
|
||||
Which database type to use for storage.
|
||||
'';
|
||||
};
|
||||
GRIST_BOOT_KEY = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Grist password for first time configuration of your instance. You must remove it when your instance is configured.
|
||||
|
||||
If null, this will be unset.
|
||||
'';
|
||||
};
|
||||
GRIST_DEFAULT_EMAIL = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
The user who logs in with the email defined by
|
||||
GRIST_DEFAULT_EMAIL is the administrator of this Grist
|
||||
installation. When Grist runs for the first time, it will create
|
||||
an account set to the value of GRIST_DEFAULT_EMAIL.
|
||||
|
||||
If null, this will be unset.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
default = { };
|
||||
example = {
|
||||
GRIST_DEFAULT_EMAIL = "example@example.com";
|
||||
};
|
||||
description = ''
|
||||
Environment variables used for Grist.
|
||||
|
||||
See [](https://github.com/gristlabs/grist-core/#environment-variables)
|
||||
for available environment variables.
|
||||
'';
|
||||
};
|
||||
|
||||
environmentFiles = mkOption {
|
||||
type = types.listOf types.path;
|
||||
default = [ ];
|
||||
description = ''
|
||||
Environment files for secrets.
|
||||
|
||||
You must at least set GRIST_SESSION_KEY there.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion = cfg.environment.GRIST_SANDBOX_FLAVOR == "gvisor";
|
||||
message = "The current Grist module only supports gVisor sandboxing";
|
||||
}
|
||||
];
|
||||
|
||||
warnings =
|
||||
optional (cfg.environment.GRIST_BOOT_KEY != null)
|
||||
"GRIST_BOOT_KEY is world-readable in the Nix Store, you should remove it when your instance is configured or set it in the environment file as a secret.";
|
||||
|
||||
services.grist = {
|
||||
package = mkDefault (pkgs.grist-core.override { enterpriseEdition = cfg.enableEnterprise; });
|
||||
environment = {
|
||||
REDIS_URL = mkIf cfg.enableRedis "redis://localhost:${builtins.toString config.services.redis.servers.grist.port}";
|
||||
NODE_PATH = concatMapStringsSep ":" (v: "${cfg.package}/grist-core/${v}") [
|
||||
"_build"
|
||||
"_build/ext"
|
||||
"_build/stubs"
|
||||
"ext/node_modules"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.grist-core = {
|
||||
description = "Grist Core";
|
||||
|
||||
after = [
|
||||
"network.target"
|
||||
]
|
||||
++ optional (cfg.environment.TYPEORM_TYPE == "postgres") "postgresql.service";
|
||||
|
||||
wants = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
path = [
|
||||
pkgs.nodejs
|
||||
cfg.package.pythonEnv
|
||||
pkgs.gvisor
|
||||
pkgs.procps
|
||||
pkgs.glibc.bin
|
||||
];
|
||||
|
||||
inherit (cfg) environment;
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = "${pkgs.nodejs}/bin/node ${cfg.package}/grist-core/_build/stubs/app/server/server.js";
|
||||
|
||||
DynamicUser = true;
|
||||
Restart = "always";
|
||||
|
||||
StateDirectory = "grist-core";
|
||||
WorkingDirectory = "/var/lib/grist-core";
|
||||
|
||||
Delegate = "yes";
|
||||
|
||||
ProtectHome = true;
|
||||
ProtectSystem = "strict";
|
||||
PrivateTmp = true;
|
||||
PrivateDevices = true;
|
||||
ProtectHostname = true;
|
||||
ProtectClock = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectKernelModules = true;
|
||||
LockPersonality = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectControlGroups = true;
|
||||
NoNewPrivileges = true;
|
||||
RestrictRealtime = true;
|
||||
RestrictSUIDSGID = true;
|
||||
RemoveIPC = true;
|
||||
PrivateMounts = true;
|
||||
|
||||
EnvironmentFile = cfg.environmentFiles;
|
||||
};
|
||||
};
|
||||
services.redis.servers = mkIf cfg.enableRedis {
|
||||
"grist" = {
|
||||
enable = true;
|
||||
port = 6380;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
meta.maintainers = with lib.maintainers; [ sinavir ];
|
||||
}
|
||||
@@ -808,6 +808,7 @@ in
|
||||
graylog = runTest ./graylog.nix;
|
||||
greenlight = runTest ./greenlight.nix;
|
||||
greetd-no-shadow = runTest ./greetd-no-shadow.nix;
|
||||
grist = runTest ./grist.nix;
|
||||
grocy = runTest ./grocy.nix;
|
||||
grow-partition = runTest ./grow-partition.nix;
|
||||
grub = {
|
||||
|
||||
107
nixos/tests/grist.nix
Normal file
107
nixos/tests/grist.nix
Normal file
@@ -0,0 +1,107 @@
|
||||
{ pkgs, ... }:
|
||||
let
|
||||
forwardedPort = 8484;
|
||||
internalPort = 8484;
|
||||
in
|
||||
{
|
||||
name = "grist smoke test";
|
||||
|
||||
nodes = {
|
||||
machine =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
virtualisation.forwardPorts = [
|
||||
{
|
||||
host.port = forwardedPort;
|
||||
guest.port = internalPort;
|
||||
}
|
||||
];
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ 8484 ];
|
||||
|
||||
services.grist = {
|
||||
enable = true;
|
||||
enableRedis = true;
|
||||
environment = {
|
||||
APP_HOME_URL = "http://127.0.0.1:8484";
|
||||
GRIST_IN_SERVICE = "true";
|
||||
GRIST_BOOT_KEY = "dummy";
|
||||
GRIST_HOST = "0.0.0.0";
|
||||
DEBUG = "1";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
extraPythonPackages = p: [
|
||||
p.requests
|
||||
];
|
||||
|
||||
testScript = ''
|
||||
import requests
|
||||
import sys
|
||||
|
||||
start_all()
|
||||
|
||||
machine.wait_for_unit("grist-core.service")
|
||||
machine.wait_for_open_port(${builtins.toString internalPort})
|
||||
|
||||
url = "http://127.0.0.1:${builtins.toString forwardedPort}/o/docs/api/"
|
||||
|
||||
def check_answer(r):
|
||||
if not r.ok:
|
||||
sys.exit(1)
|
||||
return r.json()
|
||||
|
||||
with subtest("Create document"):
|
||||
r = requests.post(f"{url}docs", json = {"timezone":"Europe/Paris"})
|
||||
doc_id = check_answer(r)
|
||||
|
||||
with subtest("Create table"):
|
||||
r = requests.post(f"{url}docs/{doc_id}/tables", json={
|
||||
"tables": [
|
||||
{
|
||||
"id": "double",
|
||||
"columns": [
|
||||
{
|
||||
"id": "number",
|
||||
"fields": {
|
||||
"type": "Numeric",
|
||||
"label": "Number",
|
||||
},
|
||||
},
|
||||
{
|
||||
"id": "result",
|
||||
"fields": {
|
||||
"type": "Numeric",
|
||||
"label": "Result",
|
||||
"formula": "$number * 2",
|
||||
"isFormula": True,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
})
|
||||
table_id = check_answer(r)["tables"][0]["id"]
|
||||
|
||||
with subtest("Add record"):
|
||||
r = requests.post(f"{url}docs/{doc_id}/tables/{table_id}/records", json={
|
||||
"records": [
|
||||
{
|
||||
"fields": {
|
||||
"number": 5,
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
if len(check_answer(r)) != 1:
|
||||
sys.exit(1)
|
||||
|
||||
with subtest("Read record"):
|
||||
r = requests.get(f"{url}docs/{doc_id}/tables/{table_id}/records")
|
||||
record = check_answer(r)["records"][0]
|
||||
if record["fields"]["result"] != record["fields"]["number"] * 2:
|
||||
sys.exit(1)
|
||||
'';
|
||||
}
|
||||
88
pkgs/by-name/gr/grist-core/0001-nixos.patch
Normal file
88
pkgs/by-name/gr/grist-core/0001-nixos.patch
Normal file
@@ -0,0 +1,88 @@
|
||||
diff --git a/sandbox/gvisor/run.py b/sandbox/gvisor/run.py
|
||||
index db074508..d94b3cc8 100755
|
||||
--- a/sandbox/gvisor/run.py
|
||||
+++ b/sandbox/gvisor/run.py
|
||||
@@ -75,8 +75,8 @@ mounts = [ # These will be filled in more fully programmatically bel
|
||||
binds = []
|
||||
preserved = set()
|
||||
env = [
|
||||
- "PATH=/usr/local/bin:/usr/bin:/bin",
|
||||
- "LD_LIBRARY_PATH=/usr/local/lib" # Assumes python version in /usr/local
|
||||
+ "PATH=@sandboxPath@",
|
||||
+ "LD_LIBRARY_PATH=@sandboxLibPath@",
|
||||
] + (args.env or [])
|
||||
settings = {
|
||||
"ociVersion": "1.0.0",
|
||||
@@ -157,17 +157,13 @@ def preserve(*locations, short_failure=False):
|
||||
})
|
||||
preserved.add(location)
|
||||
|
||||
+
|
||||
# Prepare the file system - blank out everything that need not be shared.
|
||||
-exceptions = ["/lib", "/lib64"] # to be shared (read-only)
|
||||
-exceptions += ["/proc", "/sys"] # already virtualized
|
||||
+exceptions = ["/proc", "/sys"] # already virtualized
|
||||
|
||||
# retain /bin and /usr/bin for utilities
|
||||
start = args.start
|
||||
-if include_bash or start:
|
||||
- exceptions.append("/bin")
|
||||
|
||||
-preserve("/usr/bin")
|
||||
-preserve("/usr/local/lib")
|
||||
|
||||
# Support user-specific extra directories. This is handy if Python is
|
||||
# somewhere weird and there is a maze of soft links to get
|
||||
@@ -176,31 +172,7 @@ extra_dirs = os.environ.get('GVISOR_EXTRA_DIRS')
|
||||
if extra_dirs:
|
||||
preserve(*extra_dirs.split(':'))
|
||||
|
||||
-# Do not attempt to include symlink directories, they are not supported
|
||||
-# and will cause obscure failures. On debian bookworm /lib64 is a
|
||||
-# symlink and we do not appear to need it, relative to debian buster
|
||||
-# where it is a real directory.
|
||||
-if os.path.exists('/lib64') and not os.path.islink('/lib64'):
|
||||
- preserve("/lib64")
|
||||
-if os.path.exists('/usr/lib64'):
|
||||
- preserve("/usr/lib64")
|
||||
-preserve("/usr/lib")
|
||||
-
|
||||
-# include python3 for bash and python3
|
||||
-best_python_executable = None
|
||||
-# We expect python3 in /usr/bin or /usr/local/bin.
|
||||
-candidates = [
|
||||
- path
|
||||
- # Pick the most generic python if not matching python3.11.
|
||||
- # Sorry this is delicate because of restores, mounts, symlinks.
|
||||
- for pattern in ['python3.11', 'python3.10', 'python3.9', 'python3', 'python3*']
|
||||
- for root in ['/usr/local', '/usr']
|
||||
- for path in glob.glob(f'{root}/bin/{pattern}')
|
||||
- if os.path.exists(path)
|
||||
-]
|
||||
-if not candidates:
|
||||
- raise Exception('could not find python3')
|
||||
-best_python_executable = os.path.realpath(candidates[0])
|
||||
+preserve("/nix/store")
|
||||
|
||||
# Set up any specific shares requested.
|
||||
if args.mount:
|
||||
@@ -227,18 +199,15 @@ settings['mounts'] = sorted(tmpfs_mounts, key=lambda mount: mount["destination"]
|
||||
# because gvisor is written in Go and doesn't use the standard library that faketime
|
||||
# tweaks.
|
||||
if args.faketime:
|
||||
- preserve('/usr/lib/x86_64-linux-gnu/faketime')
|
||||
cmd_args.append('faketime')
|
||||
cmd_args.append('-f')
|
||||
cmd_args.append('2020-01-01 00:00:00' if args.faketime == 'default' else args.faketime)
|
||||
- preserve('/usr/bin/faketime')
|
||||
- preserve('/bin/date')
|
||||
|
||||
# Pick and set an initial entry point (bash or python).
|
||||
if start:
|
||||
cmd_args.append(start)
|
||||
else:
|
||||
- cmd_args.append('bash' if include_bash else best_python_executable)
|
||||
+ cmd_args.append('bash' if include_bash else "python3")
|
||||
|
||||
# Add any requested arguments for the program that will be run.
|
||||
cmd_args += more_args
|
||||
54
pkgs/by-name/gr/grist-core/fetch-grist-enterprise.nix
Normal file
54
pkgs/by-name/gr/grist-core/fetch-grist-enterprise.nix
Normal file
@@ -0,0 +1,54 @@
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
cacert,
|
||||
curl,
|
||||
|
||||
fetchYarnDeps,
|
||||
}:
|
||||
{
|
||||
gristSrc,
|
||||
version,
|
||||
hash,
|
||||
offlineCacheHash,
|
||||
}:
|
||||
rec {
|
||||
src = stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "grist-enterprise-src";
|
||||
inherit version;
|
||||
|
||||
src = gristSrc;
|
||||
|
||||
phases = [
|
||||
"buildPhase"
|
||||
"installPhase"
|
||||
];
|
||||
|
||||
nativeBuildInputs = [
|
||||
curl
|
||||
cacert
|
||||
];
|
||||
|
||||
buildPhase = ''
|
||||
ref=$(cat $src/buildtools/.grist-ee-version)
|
||||
|
||||
echo "Found grist-ee version: $ref"
|
||||
|
||||
curl "https://grist-static.com/ext/ext-built-''${ref}.tar.gz" -o ./tarball.tar.gz
|
||||
|
||||
'';
|
||||
installPhase = ''
|
||||
mkdir -p $out
|
||||
|
||||
tar -xvf ./tarball.tar.gz -C $out
|
||||
'';
|
||||
|
||||
outputHash = hash;
|
||||
outputHashAlgo = if finalAttrs.outputHash == "" then "sha256" else null;
|
||||
outputHashMode = "recursive";
|
||||
});
|
||||
offlineCache = fetchYarnDeps {
|
||||
yarnLock = "${src}/ext/yarn.lock";
|
||||
hash = offlineCacheHash;
|
||||
};
|
||||
}
|
||||
244
pkgs/by-name/gr/grist-core/package.nix
Normal file
244
pkgs/by-name/gr/grist-core/package.nix
Normal file
@@ -0,0 +1,244 @@
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
callPackage,
|
||||
|
||||
fetchFromGitHub,
|
||||
fetchYarnDeps,
|
||||
writeScriptBin,
|
||||
|
||||
python3,
|
||||
yarn,
|
||||
nodejs,
|
||||
node-gyp-build,
|
||||
node-gyp,
|
||||
node-pre-gyp,
|
||||
fixup-yarn-lock,
|
||||
|
||||
yarnConfigHook,
|
||||
|
||||
sandboxEnv ? [ ],
|
||||
extraPythonPackages ? p: [ ],
|
||||
|
||||
nixosTests,
|
||||
|
||||
enterpriseEdition ? false,
|
||||
|
||||
nix-update-script,
|
||||
}:
|
||||
stdenv.mkDerivation (
|
||||
finalAttrs:
|
||||
let
|
||||
fetchGristEnterprise = callPackage ./fetch-grist-enterprise.nix { };
|
||||
|
||||
enterprise = fetchGristEnterprise {
|
||||
gristSrc = finalAttrs.src;
|
||||
inherit (finalAttrs) version;
|
||||
hash = "sha256-7lqt+L/Qmx/3kl2zJnRsbmCSmu+iAyzpNnqI/yJD9Q8=";
|
||||
offlineCacheHash = "sha256-oMLNZZolY9Wg4DwJyYPDL6K28aEyWcXS9ivnzCuYcS0=";
|
||||
};
|
||||
|
||||
pythonEnv = python3.withPackages (
|
||||
p:
|
||||
extraPythonPackages p
|
||||
++ [
|
||||
p.astroid
|
||||
p.asttokens
|
||||
p.chardet
|
||||
p.et-xmlfile
|
||||
p.executing
|
||||
p.friendly-traceback
|
||||
p.iso8601
|
||||
p.lazy-object-proxy
|
||||
p.openpyxl
|
||||
p.phonenumbers
|
||||
p.pure-eval
|
||||
p.python-dateutil
|
||||
p.roman
|
||||
p.six
|
||||
p.sortedcontainers
|
||||
p.stack-data
|
||||
p.typing-extensions
|
||||
p.unittest-xml-reporting
|
||||
p.wrapt
|
||||
]
|
||||
);
|
||||
in
|
||||
{
|
||||
pname = "grist-core";
|
||||
version = "1.7.19";
|
||||
__structuredAttrs = true;
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "gristlabs";
|
||||
repo = "grist-core";
|
||||
tag = "v${finalAttrs.version}";
|
||||
hash = "sha256-IKnSluSQnPHO+qAwWF7KR/ukIDHVVulmJqIqaMI88Lg=";
|
||||
};
|
||||
|
||||
offlineCache = fetchYarnDeps {
|
||||
yarnLock = "${finalAttrs.src}/yarn.lock";
|
||||
hash = "sha256-E8LDY7GF9d7+iXxr4BLYRUkwQxcpVihMU6HrXJ80pic=";
|
||||
};
|
||||
|
||||
env = {
|
||||
# We have our own way to fetch enterprise code because of nix
|
||||
GRIST_SKIP_EXT_AUTOSETUP = "1";
|
||||
|
||||
sandboxPath = lib.makeSearchPath "bin" ([ pythonEnv ] ++ sandboxEnv);
|
||||
sandboxLibPath = lib.makeLibraryPath ([ pythonEnv ] ++ sandboxEnv);
|
||||
};
|
||||
|
||||
strictDeps = true;
|
||||
|
||||
patches = [
|
||||
# Currently, gVisor sandboxing assumes the system is following the FHS.
|
||||
# We thus adapt the sandboxing for nixos by removing all useless mounts
|
||||
# and adding a readonly /nix/store. In particular this implies that all
|
||||
# grist users will be able to browse the nix-store.
|
||||
#
|
||||
# See https://github.com/gristlabs/grist-core/issues/2022 for more details
|
||||
./0001-nixos.patch
|
||||
];
|
||||
|
||||
nativeBuildInputs = [
|
||||
yarn
|
||||
nodejs
|
||||
fixup-yarn-lock
|
||||
node-gyp-build
|
||||
node-gyp
|
||||
node-pre-gyp
|
||||
|
||||
yarnConfigHook
|
||||
|
||||
# napi-postinstall is only used for linting dependencies and/or useless checks
|
||||
(writeScriptBin "napi-postinstall" ''
|
||||
#!/bin/sh
|
||||
# noop
|
||||
echo "$@"
|
||||
'')
|
||||
|
||||
pythonEnv
|
||||
];
|
||||
|
||||
buildInputs = [ pythonEnv ];
|
||||
|
||||
yarnInstallFlags = [
|
||||
"--frozen-lockfile"
|
||||
"--force"
|
||||
"--ignore-engines"
|
||||
"--ignore-platform"
|
||||
# "--ignore-scripts"
|
||||
"--no-progress"
|
||||
"--non-interactive"
|
||||
"--offline"
|
||||
];
|
||||
|
||||
postPatch = ''
|
||||
rm .yarnrc
|
||||
'';
|
||||
|
||||
preConfigure = ''
|
||||
export HOME=$(mktemp -d)
|
||||
export npm_config_nodedir=${nodejs}
|
||||
|
||||
# This one is needed during install process:
|
||||
patchShebangs buildtools/install_edition.sh
|
||||
'';
|
||||
|
||||
preBuild = ''
|
||||
patchShebangs buildtools
|
||||
''
|
||||
+ lib.optionalString enterpriseEdition ''
|
||||
|
||||
echo "Copying ext"
|
||||
cp -r --preserve=timestamps --reflink=auto -- "${enterprise.src}/ext" ./ext
|
||||
chmod -R u+w -- "./ext"
|
||||
|
||||
pushd ext
|
||||
|
||||
yarn config --offline set yarn-offline-mirror ${enterprise.offlineCache}
|
||||
fixup-yarn-lock yarn.lock
|
||||
|
||||
yarn install $yarnInstallFlags \
|
||||
--production=false
|
||||
|
||||
patchShebangs node_modules
|
||||
|
||||
popd
|
||||
|
||||
./buildtools/dedupe-ext-types.sh
|
||||
'';
|
||||
|
||||
buildPhase = ''
|
||||
runHook preBuild
|
||||
|
||||
yarn --offline run build:prod
|
||||
|
||||
runHook postBuild
|
||||
'';
|
||||
|
||||
postBuild = ''
|
||||
rm -r ./node_modules
|
||||
yarn install $yarnInstallFlags \
|
||||
--production=true
|
||||
'';
|
||||
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
|
||||
mkdir -p "$out/grist-core"
|
||||
|
||||
cp -r {_build,node_modules,sandbox,static,bower_components} "$out/grist-core"
|
||||
${lib.optionalString enterpriseEdition ''
|
||||
mkdir -p "$out/grist-core/ext"
|
||||
cp -r ext/assets "$out/grist-core/ext/"
|
||||
cp -r ext/node_modules "$out/grist-core/ext/"
|
||||
''}
|
||||
|
||||
runHook postInstall
|
||||
'';
|
||||
|
||||
postInstall = ''
|
||||
unlink $out/grist-core/static/mocha.js
|
||||
unlink $out/grist-core/static/sinon.js
|
||||
unlink $out/grist-core/static/mocha.css
|
||||
|
||||
unlink $out/grist-core/node_modules/msgpackr/node_modules/.bin/download-msgpackr-prebuilds
|
||||
unlink $out/grist-core/node_modules/.bin/download-msgpackr-prebuilds
|
||||
|
||||
unlink $out/grist-core/bower_components/bootstrap
|
||||
|
||||
substituteAllInPlace $out/grist-core/sandbox/gvisor/run.py
|
||||
'';
|
||||
|
||||
passthru = {
|
||||
inherit pythonEnv;
|
||||
enterpriseSrc = enterprise.src;
|
||||
enterpriseOfflineCache = enterprise.offlineCache;
|
||||
tests.grist-core = nixosTests.grist-core;
|
||||
|
||||
updateScript = nix-update-script {
|
||||
extraArgs = [
|
||||
"--custom-dep"
|
||||
"enterpriseSrc"
|
||||
"--custom-dep"
|
||||
"enterpriseOfflineCache"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
meta = {
|
||||
maintainers = with lib.maintainers; [
|
||||
sinavir
|
||||
];
|
||||
description = ''
|
||||
Relational spreadsheet tool that sits between databases and
|
||||
spreadsheets.
|
||||
'';
|
||||
homepage = "https://github.com/gristlabs/grist-core";
|
||||
license = if enterpriseEdition then lib.unfree else lib.licenses.asl20;
|
||||
platforms = lib.platforms.linux;
|
||||
};
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,48 @@
|
||||
{
|
||||
lib,
|
||||
buildPythonPackage,
|
||||
fetchFromGitHub,
|
||||
setuptools,
|
||||
wheel,
|
||||
asttokens,
|
||||
executing,
|
||||
pure-eval,
|
||||
stack-data,
|
||||
}:
|
||||
|
||||
buildPythonPackage {
|
||||
pname = "friendly-traceback";
|
||||
version = "0-unstable-2025-04-13";
|
||||
pyproject = true;
|
||||
__structuredAttrs = true;
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "friendly-traceback";
|
||||
repo = "friendly-traceback";
|
||||
rev = "bba8fc43c4caa4b64e8800e0b1f7ed39e0276170";
|
||||
hash = "sha256-ThYE4JVPzTmot9mYB2LN2NmU/Wqd71Spv9+VAP9/Zp0=";
|
||||
};
|
||||
|
||||
build-system = [
|
||||
setuptools
|
||||
wheel
|
||||
];
|
||||
|
||||
dependencies = [
|
||||
asttokens
|
||||
executing
|
||||
pure-eval
|
||||
stack-data
|
||||
];
|
||||
|
||||
pythonImportsCheck = [
|
||||
"friendly_traceback"
|
||||
];
|
||||
|
||||
meta = {
|
||||
description = "Friendlier Python tracebacks";
|
||||
homepage = "https://github.com/friendly-traceback/friendly-traceback";
|
||||
license = lib.licenses.mit;
|
||||
maintainers = with lib.maintainers; [ sinavir ];
|
||||
};
|
||||
}
|
||||
55
pkgs/development/python-modules/pygrister/default.nix
Normal file
55
pkgs/development/python-modules/pygrister/default.nix
Normal file
@@ -0,0 +1,55 @@
|
||||
{
|
||||
lib,
|
||||
buildPythonPackage,
|
||||
fetchFromGitHub,
|
||||
setuptools,
|
||||
requests,
|
||||
typer,
|
||||
pyinstaller,
|
||||
tox,
|
||||
nix-update-script,
|
||||
}:
|
||||
|
||||
buildPythonPackage (finalAttrs: {
|
||||
pname = "pygrister";
|
||||
version = "0.10.0";
|
||||
pyproject = true;
|
||||
__structuredAttrs = true;
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "ricpol";
|
||||
repo = "pygrister";
|
||||
tag = "v${finalAttrs.version}";
|
||||
hash = "sha256-7NIiHbE9LQimStSpZrCEoWFdfpfrrS7TIctfv4y0Yqc=";
|
||||
};
|
||||
|
||||
build-system = [
|
||||
setuptools
|
||||
];
|
||||
|
||||
dependencies = [
|
||||
requests
|
||||
typer
|
||||
];
|
||||
|
||||
optional-dependencies = {
|
||||
devel = [
|
||||
pyinstaller
|
||||
tox
|
||||
];
|
||||
};
|
||||
|
||||
pythonImportsCheck = [
|
||||
"pygrister"
|
||||
];
|
||||
|
||||
passthru.updateScript = nix-update-script { };
|
||||
|
||||
meta = {
|
||||
description = "Python client for the Grist API";
|
||||
homepage = "https://github.com/ricpol/pygrister";
|
||||
changelog = "https://github.com/ricpol/pygrister/releases/tag/${finalAttrs.src.tag}";
|
||||
license = lib.licenses.mit;
|
||||
maintainers = with lib.maintainers; [ sinavir ];
|
||||
};
|
||||
})
|
||||
@@ -6522,6 +6522,8 @@ self: super: with self; {
|
||||
|
||||
frida-python = callPackage ../development/python-modules/frida-python { };
|
||||
|
||||
friendly-traceback = callPackage ../development/python-modules/friendly-traceback { };
|
||||
|
||||
frigidaire = callPackage ../development/python-modules/frigidaire { };
|
||||
|
||||
frilouz = callPackage ../development/python-modules/frilouz { };
|
||||
@@ -15112,6 +15114,8 @@ self: super: with self; {
|
||||
|
||||
pygrib = callPackage ../development/python-modules/pygrib { };
|
||||
|
||||
pygrister = callPackage ../development/python-modules/pygrister { };
|
||||
|
||||
pygrok = callPackage ../development/python-modules/pygrok { };
|
||||
|
||||
pygsl = callPackage ../development/python-modules/pygsl { inherit (pkgs) gsl swig; };
|
||||
|
||||
Reference in New Issue
Block a user