Initial commit.
This commit is contained in:
commit
768d190b4b
10 changed files with 6739 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
result*
|
56
README.md
Normal file
56
README.md
Normal file
|
@ -0,0 +1,56 @@
|
|||
# CryptPad for NixOS with Deuxfleurs flavour
|
||||
|
||||
## Building
|
||||
|
||||
The `default.nix` file follows the nixpkgs `callPackage` convention for fetching dependencies, so you need to either:
|
||||
|
||||
- Run `nix-build --expr '{ ... }@args: (import <nixpkgs> {}).callPackage ./default.nix args'`
|
||||
- Do the `callPackage from a higher-level directory importing your package`
|
||||
|
||||
### Docker
|
||||
|
||||
The `docker.nix` derives into a Docker image you can load simply by running:
|
||||
|
||||
```shell
|
||||
$ docker load -i $(nix-build docker.nix)
|
||||
```
|
||||
|
||||
You can then test the built Docker image using the provided `docker-compose.yml` and `config.js` files, which are
|
||||
configured to render the instance accessible at `http://localhost:3000` with data stored into the `_data` folder.
|
||||
|
||||
|
||||
### Deuxfleurs flavour
|
||||
The `deuxfleurs.nix` file derives into two derivations: The CryptPad derivation itself and a Docker image,
|
||||
which can be choose by passing the `-A [name]` flags to `nix-build`
|
||||
|
||||
For example, to build and load the Deuxfleurs-flavoured CryptPad Docker image, you run:
|
||||
|
||||
```shell
|
||||
$ docker load -i $(nix-build deuxfleurs.nix -A docker)
|
||||
```
|
||||
|
||||
## OnlyOffice integration
|
||||
Apart for `deuxfleurs.nix`, both `default.nix` and `docker.nix` files build CryptPad with a copy of OnlyOffice pre-built and
|
||||
used by CryptPad, which can result to large Docker image (~2.6GiB)
|
||||
|
||||
This behaviour is configurable by passing the `--arg withOnlyOffice false` flag to `nix-build` when building them.
|
||||
|
||||
## Updating the Deuxfleurs pinned nixpkgs
|
||||
The pinned sources files are generated with the [niv](https://github.com/nmattia/niv) tool.
|
||||
|
||||
To update the pinned nixpkgs, you simply run the following command:
|
||||
|
||||
```shell
|
||||
$ niv update
|
||||
```
|
||||
|
||||
To modify the pinned nixpkgs, you can use the `niv modify` command, for example, to move to nixpkgs-unstable:
|
||||
|
||||
```shell
|
||||
$ niv modify nixpkgs -b nixos-unstable
|
||||
```
|
||||
|
||||
## Quirks
|
||||
|
||||
- The CryptPad `package-lock.json` is included here because the upstream-provided one appeared to be desync'ed, so a
|
||||
manual lockfile generation was needed
|
325
config.js
Normal file
325
config.js
Normal file
|
@ -0,0 +1,325 @@
|
|||
// SPDX-FileCopyrightText: 2023 XWiki CryptPad Team <contact@cryptpad.org> and contributors
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
/* globals module */
|
||||
|
||||
/* DISCLAIMER:
|
||||
|
||||
There are two recommended methods of running a CryptPad instance:
|
||||
|
||||
1. Using a standalone nodejs server without HTTPS (suitable for local development)
|
||||
2. Using NGINX to serve static assets and to handle HTTPS for API server's websocket traffic
|
||||
|
||||
We do not officially recommend or support Apache, Docker, Kubernetes, Traefik, or any other configuration.
|
||||
Support requests for such setups should be directed to their authors.
|
||||
|
||||
If you're having difficulty difficulty configuring your instance
|
||||
we suggest that you join the project's Matrix channel.
|
||||
|
||||
If you don't have any difficulty configuring your instance and you'd like to
|
||||
support us for the work that went into making it pain-free we are quite happy
|
||||
to accept donations via our opencollective page: https://opencollective.com/cryptpad
|
||||
|
||||
*/
|
||||
module.exports = {
|
||||
/* CryptPad is designed to serve its content over two domains.
|
||||
* Account passwords and cryptographic content is handled on the 'main' domain,
|
||||
* while the user interface is loaded on a 'sandbox' domain
|
||||
* which can only access information which the main domain willingly shares.
|
||||
*
|
||||
* In the event of an XSS vulnerability in the UI (that's bad)
|
||||
* this system prevents attackers from gaining access to your account (that's good).
|
||||
*
|
||||
* Most problems with new instances are related to this system blocking access
|
||||
* because of incorrectly configured sandboxes. If you only see a white screen
|
||||
* when you try to load CryptPad, this is probably the cause.
|
||||
*
|
||||
* PLEASE READ THE FOLLOWING COMMENTS CAREFULLY.
|
||||
*
|
||||
*/
|
||||
|
||||
/* httpUnsafeOrigin is the URL that clients will enter to load your instance.
|
||||
* Any other URL that somehow points to your instance is supposed to be blocked.
|
||||
* The default provided below assumes you are loading CryptPad from a server
|
||||
* which is running on the same machine, using port 3000.
|
||||
*
|
||||
* In a production instance this should be available ONLY over HTTPS
|
||||
* using the default port for HTTPS (443) ie. https://cryptpad.fr
|
||||
* In such a case this should be also handled by NGINX, as documented in
|
||||
* cryptpad/docs/example.nginx.conf (see the $main_domain variable)
|
||||
*
|
||||
*/
|
||||
httpUnsafeOrigin: 'http://localhost:3000',
|
||||
|
||||
/* httpSafeOrigin is the URL that is used for the 'sandbox' described above.
|
||||
* If you're testing or developing with CryptPad on your local machine then
|
||||
* it is appropriate to leave this blank. The default behaviour is to serve
|
||||
* the main domain over port 3000 and to serve the sandbox content over port 3001.
|
||||
*
|
||||
* This is not appropriate in a production environment where invasive networks
|
||||
* may filter traffic going over abnormal ports.
|
||||
* To correctly configure your production instance you must provide a URL
|
||||
* with a different domain (a subdomain is sufficient).
|
||||
* It will be used to load the UI in our 'sandbox' system.
|
||||
*
|
||||
* This value corresponds to the $sandbox_domain variable
|
||||
* in the example nginx file.
|
||||
*
|
||||
* Note that in order for the sandboxing system to be effective
|
||||
* httpSafeOrigin must be different from httpUnsafeOrigin.
|
||||
*
|
||||
* CUSTOMIZE AND UNCOMMENT THIS FOR PRODUCTION INSTALLATIONS.
|
||||
*/
|
||||
// httpSafeOrigin: "https://some-other-domain.xyz",
|
||||
|
||||
/* httpAddress specifies the address on which the nodejs server
|
||||
* should be accessible. By default it will listen on localhost
|
||||
* (IPv4 & IPv6 if enabled). If you want it to listen on
|
||||
* a specific address, specify it here. e.g '192.168.0.1'
|
||||
*
|
||||
*/
|
||||
httpAddress: '0.0.0.0',
|
||||
|
||||
/* httpPort specifies on which port the nodejs server should listen.
|
||||
* By default it will serve content over port 3000, which is suitable
|
||||
* for both local development and for use with the provided nginx example,
|
||||
* which will proxy websocket traffic to your node server.
|
||||
*
|
||||
*/
|
||||
//httpPort: 3000,
|
||||
|
||||
/* httpSafePort allows you to specify an alternative port from which
|
||||
* the node process should serve sandboxed assets. The default value is
|
||||
* that of your httpPort + 1. You probably don't need to change this.
|
||||
*
|
||||
*/
|
||||
//httpSafePort: 3001,
|
||||
|
||||
/* Websockets need to be exposed on a separate port from the rest of
|
||||
* the platform's HTTP traffic. Port 3003 is used by default.
|
||||
* You can change this to a different port if it is in use by a
|
||||
* different service, but under most circumstances you can leave this
|
||||
* commented and it will work.
|
||||
*
|
||||
* In production environments, your reverse proxy (usually NGINX)
|
||||
* will need to forward websocket traffic (/cryptpad_websocket)
|
||||
* to this port.
|
||||
*
|
||||
*/
|
||||
// websocketPort: 3003,
|
||||
|
||||
/* CryptPad will launch a child process for every core available
|
||||
* in order to perform CPU-intensive tasks in parallel.
|
||||
* Some host environments may have a very large number of cores available
|
||||
* or you may want to limit how much computing power CryptPad can take.
|
||||
* If so, set 'maxWorkers' to a positive integer.
|
||||
*/
|
||||
// maxWorkers: 4,
|
||||
|
||||
/* =====================
|
||||
* Sessions
|
||||
* ===================== */
|
||||
|
||||
/* Accounts can be protected with an OTP (One Time Password) system
|
||||
* to add a second authentication layer. Such accounts use a session
|
||||
* with a given lifetime after which they are logged out and need
|
||||
* to be re-authenticated. You can configure the lifetime of these
|
||||
* sessions here.
|
||||
*
|
||||
* defaults to 7 days
|
||||
*/
|
||||
//otpSessionExpiration: 7*24, // hours
|
||||
|
||||
/* Registered users can be forced to protect their account
|
||||
* with a Multi-factor Authentication (MFA) tool like a TOTP
|
||||
* authenticator application.
|
||||
*
|
||||
* defaults to false
|
||||
*/
|
||||
//enforceMFA: false,
|
||||
|
||||
/* =====================
|
||||
* Admin
|
||||
* ===================== */
|
||||
|
||||
/*
|
||||
* CryptPad contains an administration panel. Its access is restricted to specific
|
||||
* users using the following list.
|
||||
* To give access to the admin panel to a user account, just add their public signing
|
||||
* key, which can be found on the settings page for registered users.
|
||||
* Entries should be strings separated by a comma.
|
||||
* adminKeys: [
|
||||
* "[cryptpad-user1@my.awesome.website/YZgXQxKR0Rcb6r6CmxHPdAGLVludrAF2lEnkbx1vVOo=]",
|
||||
* "[cryptpad-user2@my.awesome.website/jA-9c5iNuG7SyxzGCjwJXVnk5NPfAOO8fQuQ0dC83RE=]",
|
||||
* ]
|
||||
*
|
||||
*/
|
||||
adminKeys: [
|
||||
|
||||
],
|
||||
|
||||
/* =====================
|
||||
* STORAGE
|
||||
* ===================== */
|
||||
|
||||
/* Pads that are not 'pinned' by any registered user can be set to expire
|
||||
* after a configurable number of days of inactivity (default 90 days).
|
||||
* The value can be changed or set to false to remove expiration.
|
||||
* Expired pads can then be removed using a cron job calling the
|
||||
* `evict-inactive.js` script with node
|
||||
*
|
||||
* defaults to 90 days if nothing is provided
|
||||
*/
|
||||
//inactiveTime: 90, // days
|
||||
|
||||
/* CryptPad archives some data instead of deleting it outright.
|
||||
* This archived data still takes up space and so you'll probably still want to
|
||||
* remove these files after a brief period.
|
||||
*
|
||||
* cryptpad/scripts/evict-inactive.js is intended to be run daily
|
||||
* from a crontab or similar scheduling service.
|
||||
*
|
||||
* The intent with this feature is to provide a safety net in case of accidental
|
||||
* deletion. Set this value to the number of days you'd like to retain
|
||||
* archived data before it's removed permanently.
|
||||
*
|
||||
* defaults to 15 days if nothing is provided
|
||||
*/
|
||||
//archiveRetentionTime: 15,
|
||||
|
||||
/* It's possible to configure your instance to remove data
|
||||
* stored on behalf of inactive accounts. Set 'accountRetentionTime'
|
||||
* to the number of days an account can remain idle before its
|
||||
* documents and other account data is removed.
|
||||
*
|
||||
* Leave this value commented out to preserve all data stored
|
||||
* by user accounts regardless of inactivity.
|
||||
*/
|
||||
//accountRetentionTime: 365,
|
||||
|
||||
/* Starting with CryptPad 3.23.0, the server automatically runs
|
||||
* the script responsible for removing inactive data according to
|
||||
* your configured definition of inactivity. Set this value to `true`
|
||||
* if you prefer not to remove inactive data, or if you prefer to
|
||||
* do so manually using `scripts/evict-inactive.js`.
|
||||
*/
|
||||
//disableIntegratedEviction: true,
|
||||
|
||||
|
||||
/* Max Upload Size (bytes)
|
||||
* this sets the maximum size of any one file uploaded to the server.
|
||||
* anything larger than this size will be rejected
|
||||
* defaults to 20MB if no value is provided
|
||||
*/
|
||||
//maxUploadSize: 20 * 1024 * 1024,
|
||||
|
||||
/* Users with premium accounts (those with a plan included in their customLimit)
|
||||
* can benefit from an increased upload size limit. By default they are restricted to the same
|
||||
* upload size as any other registered user.
|
||||
*
|
||||
*/
|
||||
//premiumUploadSize: 100 * 1024 * 1024,
|
||||
|
||||
/* =====================
|
||||
* DATABASE VOLUMES
|
||||
* ===================== */
|
||||
|
||||
/*
|
||||
* CryptPad stores each document in an individual file on your hard drive.
|
||||
* Specify a directory where files should be stored.
|
||||
* It will be created automatically if it does not already exist.
|
||||
*/
|
||||
filePath: '/data/files',
|
||||
|
||||
/* CryptPad offers the ability to archive data for a configurable period
|
||||
* before deleting it, allowing a means of recovering data in the event
|
||||
* that it was deleted accidentally.
|
||||
*
|
||||
* To set the location of this archive directory to a custom value, change
|
||||
* the path below:
|
||||
*/
|
||||
archivePath: '/data/archive',
|
||||
|
||||
/* CryptPad allows logged in users to request that particular documents be
|
||||
* stored by the server indefinitely. This is called 'pinning'.
|
||||
* Pin requests are stored in a pin-store. The location of this store is
|
||||
* defined here.
|
||||
*/
|
||||
pinPath: '/data/pins',
|
||||
|
||||
/* if you would like the list of scheduled tasks to be stored in
|
||||
a custom location, change the path below:
|
||||
*/
|
||||
taskPath: '/data/tasks',
|
||||
|
||||
/* if you would like users' authenticated blocks to be stored in
|
||||
a custom location, change the path below:
|
||||
*/
|
||||
blockPath: '/data/block',
|
||||
|
||||
/* CryptPad allows logged in users to upload encrypted files. Files/blobs
|
||||
* are stored in a 'blob-store'. Set its location here.
|
||||
*/
|
||||
blobPath: '/data/blob',
|
||||
|
||||
/* CryptPad stores incomplete blobs in a 'staging' area until they are
|
||||
* fully uploaded. Set its location here.
|
||||
*/
|
||||
blobStagingPath: '/data/blobstage',
|
||||
|
||||
decreePath: '/data/decrees',
|
||||
|
||||
/* CryptPad supports logging events directly to the disk in a 'logs' directory
|
||||
* Set its location here, or set it to false (or nothing) if you'd rather not log
|
||||
*/
|
||||
logPath: '/data/logs',
|
||||
|
||||
/* =====================
|
||||
* Debugging
|
||||
* ===================== */
|
||||
|
||||
/* CryptPad can log activity to stdout
|
||||
* This may be useful for debugging
|
||||
*/
|
||||
logToStdout: true,
|
||||
|
||||
/* CryptPad can be configured to log more or less
|
||||
* the various settings are listed below by order of importance
|
||||
*
|
||||
* silly, verbose, debug, feedback, info, warn, error
|
||||
*
|
||||
* Choose the least important level of logging you wish to see.
|
||||
* For example, a 'silly' logLevel will display everything,
|
||||
* while 'info' will display 'info', 'warn', and 'error' logs
|
||||
*
|
||||
* This will affect both logging to the console and the disk.
|
||||
*/
|
||||
logLevel: 'info',
|
||||
|
||||
/* clients can use the /settings/ app to opt out of usage feedback
|
||||
* which informs the server of things like how much each app is being
|
||||
* used, and whether certain clientside features are supported by
|
||||
* the client's browser. The intent is to provide feedback to the admin
|
||||
* such that the service can be improved. Enable this with `true`
|
||||
* and ignore feedback with `false` or by commenting the attribute
|
||||
*
|
||||
* You will need to set your logLevel to include 'feedback'. Set this
|
||||
* to false if you'd like to exclude feedback from your logs.
|
||||
*/
|
||||
logFeedback: false,
|
||||
|
||||
/* CryptPad supports verbose logging
|
||||
* (false by default)
|
||||
*/
|
||||
verbose: false,
|
||||
|
||||
/* Surplus information:
|
||||
*
|
||||
* 'installMethod' is included in server telemetry to voluntarily
|
||||
* indicate how many instances are using unofficial installation methods
|
||||
* such as Docker.
|
||||
*
|
||||
*/
|
||||
installMethod: 'unspecified',
|
||||
};
|
105
default.nix
Normal file
105
default.nix
Normal file
|
@ -0,0 +1,105 @@
|
|||
{ lib
|
||||
, stdenvNoCC
|
||||
|
||||
, buildNpmPackage
|
||||
, fetchFromGitHub
|
||||
|
||||
, nodejs
|
||||
|
||||
, withOnlyOffice ? true
|
||||
}: let
|
||||
onlyOfficeVersions = {
|
||||
v1 = {
|
||||
rev = "4f370bebe96e3a0d4054df87412ee5b2c6ed8aaa";
|
||||
hash = "sha256-TE/99qOx4wT2s0op9wi+SHwqTPYq/H+a9Uus9Zj4iSY=";
|
||||
};
|
||||
v2b = {
|
||||
rev = "d9da72fda95daf93b90ffa345757c47eb5b919dd";
|
||||
hash = "sha256-SiRDRc2vnLwCVnvtk+C8PKw7IeuSzHBaJmZHogRe3hQ=";
|
||||
};
|
||||
v4 = {
|
||||
rev = "6ebc6938b6841440ffad2efc1e23f1dc1ceda964";
|
||||
hash = "sha256-eto1+8Tk/s3kbUCpbUh8qCS8EOq700FYG1/KiHyynaA=";
|
||||
};
|
||||
v5 = {
|
||||
rev = "88a356f08ded2f0f4620bda66951caf1d7f02c21";
|
||||
hash = "sha256-8j1rlAyHlKx6oAs2pIhjPKcGhJFj6ZzahOcgenyeOCc=";
|
||||
};
|
||||
v6 = {
|
||||
rev = "abd8a309f6dd37289f950cd8cea40df4492d8a15";
|
||||
hash = "sha256-BZdExj2q/bqUD3k9uluOot2dlrWKA+vpad49EdgXKww=";
|
||||
};
|
||||
v7 = {
|
||||
rev = "9d8b914a81f0f9e5d0bc3f0fc631adf4b6d480e7";
|
||||
hash = "sha256-M+rPJ/Xo2olhqB5ViynGRaesMLLfG/1ltUoLnepMPnM=";
|
||||
};
|
||||
};
|
||||
in buildNpmPackage rec {
|
||||
pname = "cryptpad";
|
||||
version = "2024.3.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "cryptpad";
|
||||
repo = "cryptpad";
|
||||
rev = version;
|
||||
hash = "sha256-VUW6KvoSatk1/hlzklMQYlSNVH/tdbH+yU4ONUQ0JSQ=";
|
||||
};
|
||||
|
||||
npmDepsHash = "sha256-tvTkoxxioPuNoe8KIuXSP7QQbvcpxMnygsMmzKBQIY0=";
|
||||
|
||||
inherit nodejs;
|
||||
|
||||
onlyOffice = if withOnlyOffice then stdenvNoCC.mkDerivation (final: {
|
||||
pname = "${pname}-onlyoffice";
|
||||
inherit version;
|
||||
|
||||
srcs = lib.mapAttrsToList (version: { rev, hash ? lib.fakeHash }: fetchFromGitHub {
|
||||
name = "${final.pname}-${version}-source";
|
||||
owner = "cryptpad";
|
||||
repo = "onlyoffice-builds";
|
||||
inherit rev hash;
|
||||
}) onlyOfficeVersions;
|
||||
|
||||
dontBuild = true;
|
||||
|
||||
sourceRoot = ".";
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out
|
||||
${lib.concatLines (map
|
||||
(version: "cp -Tr ${final.pname}-${version}-source $out/${version}")
|
||||
(builtins.attrNames onlyOfficeVersions)
|
||||
)}
|
||||
'';
|
||||
}) else null;
|
||||
|
||||
makeCacheWritable = true;
|
||||
dontFixup = true;
|
||||
|
||||
postPatch = ''
|
||||
cp -T ${./package-lock.json} package-lock.json
|
||||
'';
|
||||
|
||||
preBuild = ''
|
||||
npm run install:components
|
||||
'' + lib.optionalString withOnlyOffice ''
|
||||
ln -s $onlyOffice www/common/onlyoffice/dist
|
||||
'';
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out
|
||||
cp -R . $out/
|
||||
|
||||
substituteInPlace $out/lib/workers/index.js \
|
||||
--replace-warn "lib/workers/db-worker" "$out/lib/workers/db-worker"
|
||||
|
||||
makeWrapper ${lib.getExe nodejs} $out/bin/cryptpad-server \
|
||||
--chdir $out \
|
||||
--add-flags server.js
|
||||
'';
|
||||
|
||||
meta = {
|
||||
homepage = "https://cryptpad.org";
|
||||
mainProgram = "cryptpad-server";
|
||||
};
|
||||
}
|
11
deuxfleurs.nix
Normal file
11
deuxfleurs.nix
Normal file
|
@ -0,0 +1,11 @@
|
|||
let
|
||||
sources = import ./nix/sources.nix;
|
||||
pkgs = import sources.nixpkgs {};
|
||||
in rec {
|
||||
cryptpad = pkgs.callPackage ./default.nix {
|
||||
withOnlyOffice = false;
|
||||
};
|
||||
docker = pkgs.callPackage ./docker.nix {
|
||||
inherit cryptpad;
|
||||
};
|
||||
}
|
12
docker-compose.yml
Normal file
12
docker-compose.yml
Normal file
|
@ -0,0 +1,12 @@
|
|||
services:
|
||||
app:
|
||||
image: cryptpad:nix-latest
|
||||
environment:
|
||||
CRYPTPAD_CONFIG: '/config.js'
|
||||
ports:
|
||||
- '3000:3000'
|
||||
- '3001:3001'
|
||||
- '3003:3003'
|
||||
volumes:
|
||||
- ./config.js:/config.js:ro
|
||||
- ./_data:/data
|
17
docker.nix
Normal file
17
docker.nix
Normal file
|
@ -0,0 +1,17 @@
|
|||
{ pkgs ? import <nixpkgs> {}
|
||||
, name ? "cryptpad"
|
||||
, tag ? "nix-latest"
|
||||
, withOnlyOffice ? true
|
||||
, cryptpad ? pkgs.callPackage ./default.nix {
|
||||
inherit withOnlyOffice;
|
||||
}
|
||||
}:
|
||||
pkgs.dockerTools.buildImage {
|
||||
inherit name tag;
|
||||
|
||||
config = {
|
||||
Cmd = [
|
||||
(pkgs.lib.getExe cryptpad)
|
||||
];
|
||||
};
|
||||
}
|
14
nix/sources.json
Normal file
14
nix/sources.json
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"nixpkgs": {
|
||||
"branch": "nixos-23.11",
|
||||
"description": "Nix Packages collection",
|
||||
"homepage": null,
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "53a2c32bc66f5ae41a28d7a9a49d321172af621e",
|
||||
"sha256": "0yqbwqbripb1bbhlwjfbqmg9qb0lai2fc0k1vfh674d6rrc8igwv",
|
||||
"type": "tarball",
|
||||
"url": "https://github.com/NixOS/nixpkgs/archive/53a2c32bc66f5ae41a28d7a9a49d321172af621e.tar.gz",
|
||||
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
|
||||
}
|
||||
}
|
198
nix/sources.nix
Normal file
198
nix/sources.nix
Normal file
|
@ -0,0 +1,198 @@
|
|||
# This file has been generated by Niv.
|
||||
|
||||
let
|
||||
|
||||
#
|
||||
# The fetchers. fetch_<type> fetches specs of type <type>.
|
||||
#
|
||||
|
||||
fetch_file = pkgs: name: spec:
|
||||
let
|
||||
name' = sanitizeName name + "-src";
|
||||
in
|
||||
if spec.builtin or true then
|
||||
builtins_fetchurl { inherit (spec) url sha256; name = name'; }
|
||||
else
|
||||
pkgs.fetchurl { inherit (spec) url sha256; name = name'; };
|
||||
|
||||
fetch_tarball = pkgs: name: spec:
|
||||
let
|
||||
name' = sanitizeName name + "-src";
|
||||
in
|
||||
if spec.builtin or true then
|
||||
builtins_fetchTarball { name = name'; inherit (spec) url sha256; }
|
||||
else
|
||||
pkgs.fetchzip { name = name'; inherit (spec) url sha256; };
|
||||
|
||||
fetch_git = name: spec:
|
||||
let
|
||||
ref =
|
||||
spec.ref or (
|
||||
if spec ? branch then "refs/heads/${spec.branch}" else
|
||||
if spec ? tag then "refs/tags/${spec.tag}" else
|
||||
abort "In git source '${name}': Please specify `ref`, `tag` or `branch`!"
|
||||
);
|
||||
submodules = spec.submodules or false;
|
||||
submoduleArg =
|
||||
let
|
||||
nixSupportsSubmodules = builtins.compareVersions builtins.nixVersion "2.4" >= 0;
|
||||
emptyArgWithWarning =
|
||||
if submodules
|
||||
then
|
||||
builtins.trace
|
||||
(
|
||||
"The niv input \"${name}\" uses submodules "
|
||||
+ "but your nix's (${builtins.nixVersion}) builtins.fetchGit "
|
||||
+ "does not support them"
|
||||
)
|
||||
{ }
|
||||
else { };
|
||||
in
|
||||
if nixSupportsSubmodules
|
||||
then { inherit submodules; }
|
||||
else emptyArgWithWarning;
|
||||
in
|
||||
builtins.fetchGit
|
||||
({ url = spec.repo; inherit (spec) rev; inherit ref; } // submoduleArg);
|
||||
|
||||
fetch_local = spec: spec.path;
|
||||
|
||||
fetch_builtin-tarball = name: throw
|
||||
''[${name}] The niv type "builtin-tarball" is deprecated. You should instead use `builtin = true`.
|
||||
$ niv modify ${name} -a type=tarball -a builtin=true'';
|
||||
|
||||
fetch_builtin-url = name: throw
|
||||
''[${name}] The niv type "builtin-url" will soon be deprecated. You should instead use `builtin = true`.
|
||||
$ niv modify ${name} -a type=file -a builtin=true'';
|
||||
|
||||
#
|
||||
# Various helpers
|
||||
#
|
||||
|
||||
# https://github.com/NixOS/nixpkgs/pull/83241/files#diff-c6f540a4f3bfa4b0e8b6bafd4cd54e8bR695
|
||||
sanitizeName = name:
|
||||
(
|
||||
concatMapStrings (s: if builtins.isList s then "-" else s)
|
||||
(
|
||||
builtins.split "[^[:alnum:]+._?=-]+"
|
||||
((x: builtins.elemAt (builtins.match "\\.*(.*)" x) 0) name)
|
||||
)
|
||||
);
|
||||
|
||||
# The set of packages used when specs are fetched using non-builtins.
|
||||
mkPkgs = sources: system:
|
||||
let
|
||||
sourcesNixpkgs =
|
||||
import (builtins_fetchTarball { inherit (sources.nixpkgs) url sha256; }) { inherit system; };
|
||||
hasNixpkgsPath = builtins.any (x: x.prefix == "nixpkgs") builtins.nixPath;
|
||||
hasThisAsNixpkgsPath = <nixpkgs> == ./.;
|
||||
in
|
||||
if builtins.hasAttr "nixpkgs" sources
|
||||
then sourcesNixpkgs
|
||||
else if hasNixpkgsPath && ! hasThisAsNixpkgsPath then
|
||||
import <nixpkgs> { }
|
||||
else
|
||||
abort
|
||||
''
|
||||
Please specify either <nixpkgs> (through -I or NIX_PATH=nixpkgs=...) or
|
||||
add a package called "nixpkgs" to your sources.json.
|
||||
'';
|
||||
|
||||
# The actual fetching function.
|
||||
fetch = pkgs: name: spec:
|
||||
|
||||
if ! builtins.hasAttr "type" spec then
|
||||
abort "ERROR: niv spec ${name} does not have a 'type' attribute"
|
||||
else if spec.type == "file" then fetch_file pkgs name spec
|
||||
else if spec.type == "tarball" then fetch_tarball pkgs name spec
|
||||
else if spec.type == "git" then fetch_git name spec
|
||||
else if spec.type == "local" then fetch_local spec
|
||||
else if spec.type == "builtin-tarball" then fetch_builtin-tarball name
|
||||
else if spec.type == "builtin-url" then fetch_builtin-url name
|
||||
else
|
||||
abort "ERROR: niv spec ${name} has unknown type ${builtins.toJSON spec.type}";
|
||||
|
||||
# If the environment variable NIV_OVERRIDE_${name} is set, then use
|
||||
# the path directly as opposed to the fetched source.
|
||||
replace = name: drv:
|
||||
let
|
||||
saneName = stringAsChars (c: if (builtins.match "[a-zA-Z0-9]" c) == null then "_" else c) name;
|
||||
ersatz = builtins.getEnv "NIV_OVERRIDE_${saneName}";
|
||||
in
|
||||
if ersatz == "" then drv else
|
||||
# this turns the string into an actual Nix path (for both absolute and
|
||||
# relative paths)
|
||||
if builtins.substring 0 1 ersatz == "/" then /. + ersatz else /. + builtins.getEnv "PWD" + "/${ersatz}";
|
||||
|
||||
# Ports of functions for older nix versions
|
||||
|
||||
# a Nix version of mapAttrs if the built-in doesn't exist
|
||||
mapAttrs = builtins.mapAttrs or (
|
||||
f: set: with builtins;
|
||||
listToAttrs (map (attr: { name = attr; value = f attr set.${attr}; }) (attrNames set))
|
||||
);
|
||||
|
||||
# https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/lists.nix#L295
|
||||
range = first: last: if first > last then [ ] else builtins.genList (n: first + n) (last - first + 1);
|
||||
|
||||
# https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L257
|
||||
stringToCharacters = s: map (p: builtins.substring p 1 s) (range 0 (builtins.stringLength s - 1));
|
||||
|
||||
# https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L269
|
||||
stringAsChars = f: s: concatStrings (map f (stringToCharacters s));
|
||||
concatMapStrings = f: list: concatStrings (map f list);
|
||||
concatStrings = builtins.concatStringsSep "";
|
||||
|
||||
# https://github.com/NixOS/nixpkgs/blob/8a9f58a375c401b96da862d969f66429def1d118/lib/attrsets.nix#L331
|
||||
optionalAttrs = cond: as: if cond then as else { };
|
||||
|
||||
# fetchTarball version that is compatible between all the versions of Nix
|
||||
builtins_fetchTarball = { url, name ? null, sha256 }@attrs:
|
||||
let
|
||||
inherit (builtins) lessThan nixVersion fetchTarball;
|
||||
in
|
||||
if lessThan nixVersion "1.12" then
|
||||
fetchTarball ({ inherit url; } // (optionalAttrs (name != null) { inherit name; }))
|
||||
else
|
||||
fetchTarball attrs;
|
||||
|
||||
# fetchurl version that is compatible between all the versions of Nix
|
||||
builtins_fetchurl = { url, name ? null, sha256 }@attrs:
|
||||
let
|
||||
inherit (builtins) lessThan nixVersion fetchurl;
|
||||
in
|
||||
if lessThan nixVersion "1.12" then
|
||||
fetchurl ({ inherit url; } // (optionalAttrs (name != null) { inherit name; }))
|
||||
else
|
||||
fetchurl attrs;
|
||||
|
||||
# Create the final "sources" from the config
|
||||
mkSources = config:
|
||||
mapAttrs
|
||||
(
|
||||
name: spec:
|
||||
if builtins.hasAttr "outPath" spec
|
||||
then
|
||||
abort
|
||||
"The values in sources.json should not have an 'outPath' attribute"
|
||||
else
|
||||
spec // { outPath = replace name (fetch config.pkgs name spec); }
|
||||
)
|
||||
config.sources;
|
||||
|
||||
# The "config" used by the fetchers
|
||||
mkConfig =
|
||||
{ sourcesFile ? if builtins.pathExists ./sources.json then ./sources.json else null
|
||||
, sources ? if sourcesFile == null then { } else builtins.fromJSON (builtins.readFile sourcesFile)
|
||||
, system ? builtins.currentSystem
|
||||
, pkgs ? mkPkgs sources system
|
||||
}: rec {
|
||||
# The sources, i.e. the attribute set of spec name to spec
|
||||
inherit sources;
|
||||
|
||||
# The "pkgs" (evaluated nixpkgs) to use for e.g. non-builtin fetchers
|
||||
inherit pkgs;
|
||||
};
|
||||
|
||||
in
|
||||
mkSources (mkConfig { }) // { __functor = _: settings: mkSources (mkConfig settings); }
|
6000
package-lock.json
generated
Normal file
6000
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue