Merge master into staging-next

This commit is contained in:
github-actions[bot] 2021-09-20 12:01:15 +00:00 committed by GitHub
commit 9e5021eef4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 389 additions and 35 deletions

View file

@ -28,12 +28,12 @@ The recommended way of defining a derivation for a Coq library, is to use the `c
* `domain` (optional, defaults to `"github.com"`), domains including the strings `"github"` or `"gitlab"` in their names are automatically supported, otherwise, one must change the `fetcher` argument to support them (cf `pkgs/development/coq-modules/heq/default.nix` for an example),
* `releaseRev` (optional, defaults to `(v: v)`), provides a default mapping from release names to revision hashes/branch names/tags,
* `displayVersion` (optional), provides a way to alter the computation of `name` from `pname`, by explaining how to display version numbers,
* `namePrefix` (optional), provides a way to alter the computation of `name` from `pname`, by explaining which dependencies must occur in `name`,
* `namePrefix` (optional, defaults to `[ "coq" ]`), provides a way to alter the computation of `name` from `pname`, by explaining which dependencies must occur in `name`,
* `extraBuildInputs` (optional), by default `buildInputs` just contains `coq`, this allows to add more build inputs,
* `mlPlugin` (optional, defaults to `false`). Some extensions (plugins) might require OCaml and sometimes other OCaml packages. Standard dependencies can be added by setting the current option to `true`. For a finer grain control, the `coq.ocamlPackages` attribute can be used in `extraBuildInputs` to depend on the same package set Coq was built against.
* `useDune2ifVersion` (optional, default to `(x: false)` uses Dune2 to build the package if the provided predicate evaluates to true on the version, e.g. `useDune2if = versions.isGe "1.1"` will use dune if the version of the package is greater or equal to `"1.1"`,
* `useDune2` (optional, defaults to `false`) uses Dune2 to build the package if set to true, the presence of this attribute overrides the behavior of the previous one.
* `opam-name` (optional, defaults to `coq-` followed by the value of `pname`), name of the Dune package to build.
* `opam-name` (optional, defaults to concatenating with a dash separator the components of `namePrefix` and `pname`), name of the Dune package to build.
* `enableParallelBuilding` (optional, defaults to `true`), since it is activated by default, we provide a way to disable it.
* `extraInstallFlags` (optional), allows to extend `installFlags` which initializes the variable `COQMF_COQLIB` so as to install in the proper subdirectory. Indeed Coq libraries should be installed in `$(out)/lib/coq/${coq.coq-version}/user-contrib/`. Such directories are automatically added to the `$COQPATH` environment variable by the hook defined in the Coq derivation.
* `setCOQBIN` (optional, defaults to `true`), by default, the environment variable `$COQBIN` is set to the current Coq's binary, but one can disable this behavior by setting it to `false`,

View file

@ -24,6 +24,7 @@
<xi:include href="lua.section.xml" />
<xi:include href="maven.section.xml" />
<xi:include href="ocaml.section.xml" />
<xi:include href="octave.section.xml" />
<xi:include href="perl.section.xml" />
<xi:include href="php.section.xml" />
<xi:include href="python.section.xml" />

View file

@ -0,0 +1,100 @@
# Octave {#sec-octave}
## Introduction {#ssec-octave-introduction}
Octave is a modular scientific programming language and environment.
A majority of the packages supported by Octave from their [website](https://octave.sourceforge.io/packages.php) are packaged in nixpkgs.
## Structure {#ssec-octave-structure}
All Octave add-on packages are available in two ways:
1. Under the top-level `Octave` attribute, `octave.pkgs`.
2. As a top-level attribute, `octavePackages`.
## Packaging Octave Packages {#ssec-octave-packaging}
Nixpkgs provides a function `buildOctavePackage`, a generic package builder function for any Octave package that complies with the Octave's current packaging format.
All Octave packages are defined in [pkgs/top-level/octave-packages.nix](https://github.com/NixOS/nixpkgs/blob/master/pkgs/top-level/octave-packages.nix) rather than `pkgs/all-packages.nix`.
Each package is defined in their own file in the [pkgs/development/octave-modules](https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/octave-modules) directory.
Octave packages are made available through `all-packages.nix` through both the attribute `octavePackages` and `octave.pkgs`.
You can test building an Octave package as follows:
```ShellSession
$ nix-build -A octavePackages.symbolic
```
When building Octave packages with `nix-build`, the `buildOctavePackage` function adds `octave-octaveVersion` to; the start of the package's name attribute.
This can be required when installing the package using `nix-env`:
```ShellSession
$ nix-env -i octave-6.2.0-symbolic
```
Although, you can also install it using the attribute name:
```ShellSession
$ nix-env -i -A octavePackages.symbolic
```
You can build Octave with packages by using the `withPackages` passed-through function.
```ShellSession
$ nix-shell -p 'octave.withPackages (ps: with ps; [ symbolic ])'
```
This will also work in a `shell.nix` file.
```nix
{ pkgs ? import <nixpkgs> { }}:
pkgs.mkShell {
nativeBuildInputs = with pkgs; [
(octave.withPackages (opkgs: with opkgs; [ symbolic ]))
];
}
```
### `buildOctavePackage` Steps {#sssec-buildOctavePackage-steps}
The `buildOctavePackage` does several things to make sure things work properly.
1. Sets the environment variable `OCTAVE_HISTFILE` to `/dev/null` during package compilation so that the commands run through the Octave interpreter directly are not logged.
2. Skips the configuration step, because the packages are stored as gzipped tarballs, which Octave itself handles directly.
3. Change the hierarchy of the tarball so that only a single directory is at the top-most level of the tarball.
4. Use Octave itself to run the `pkg build` command, which unzips the tarball, extracts the necessary files written in Octave, and compiles any code written in C++ or Fortran, and places the fully compiled artifact in `$out`.
`buildOctavePackage` is built on top of `stdenv` in a standard way, allowing most things to be customized.
### Handling Dependencies {#sssec-octave-handling-dependencies}
In Octave packages, there are four sets of dependencies that can be specified:
`nativeBuildInputs`
: Just like other packages, `nativeBuildInputs` is intended for architecture-dependent build-time-only dependencies.
`buildInputs`
: Like other packages, `buildInputs` is intended for architecture-independent build-time-only dependencies.
`propagatedBuildInputs`
: Similar to other packages, `propagatedBuildInputs` is intended for packages that are required for both building and running of the package.
See [Symbolic](https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/octave-modules/symbolic/default.nix) for how this works and why it is needed.
`requiredOctavePackages`
: This is a special dependency that ensures the specified Octave packages are dependent on others, and are made available simultaneously when loading them in Octave.
### Installing Octave Packages {#sssec-installing-octave-packages}
By default, the `buildOctavePackage` function does _not_ install the requested package into Octave for use.
The function will only build the requested package.
This is due to Octave maintaining an text-based database about which packages are installed where.
To this end, when all the requested packages have been built, the Octave package and all its add-on packages are put together into an environment, similar to Python.
1. First, all the Octave binaries are wrapped with the environment variable `OCTAVE_SITE_INITFILE` set to a file in `$out`, which is required for Octave to be able to find the non-standard package database location.
2. Because of the way `buildEnv` works, all tarballs that are present (which should be all Octave packages to install) should be removed.
3. The path down to the default install location of Octave packages is recreated so that Nix-operated Octave can install the packages.
4. Install the packages into the `$out` environment while writing package entries to the database file.
This database file is unique for each different (according to Nix) environment invocation.
5. Rewrite the Octave-wide startup file to read from the list of packages installed in that particular environment.
6. Wrap any programs that are required by the Octave packages so that they work with all the paths defined within the environment.

View file

@ -899,6 +899,7 @@
./services/search/elasticsearch-curator.nix
./services/search/hound.nix
./services/search/kibana.nix
./services/search/meilisearch.nix
./services/search/solr.nix
./services/security/certmgr.nix
./services/security/cfssl.nix

View file

@ -0,0 +1,129 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.meilisearch;
in
{
meta.maintainers = with maintainers; [ filalex77 ];
###### interface
options.services.meilisearch = {
enable = mkEnableOption "MeiliSearch - a RESTful search API";
package = mkOption {
description = "The package to use for meilisearch. Use this if you require specific features to be enabled. The default package has no features.";
default = pkgs.meilisearch;
defaultText = "pkgs.meilisearch";
type = types.package;
};
listenAddress = mkOption {
description = "MeiliSearch listen address.";
default = "127.0.0.1";
type = types.str;
};
listenPort = mkOption {
description = "MeiliSearch port to listen on.";
default = 7700;
type = types.port;
};
environment = mkOption {
description = "Defines the running environment of MeiliSearch.";
default = "development";
type = types.enum [ "development" "production" ];
};
# TODO change this to LoadCredentials once possible
masterKeyEnvironmentFile = mkOption {
description = ''
Path to file which contains the master key.
By doing so, all routes will be protected and will require a key to be accessed.
If no master key is provided, all routes can be accessed without requiring any key.
The format is the following:
MEILI_MASTER_KEY=my_secret_key
'';
default = null;
type = with types; nullOr path;
};
noAnalytics = mkOption {
description = ''
Deactivates analytics.
Analytics allow MeiliSearch to know how many users are using MeiliSearch,
which versions and which platforms are used.
This process is entirely anonymous.
'';
default = true;
type = types.bool;
};
logLevel = mkOption {
description = ''
Defines how much detail should be present in MeiliSearch's logs.
MeiliSearch currently supports four log levels, listed in order of increasing verbosity:
- 'ERROR': only log unexpected events indicating MeiliSearch is not functioning as expected
- 'WARN:' log all unexpected events, regardless of their severity
- 'INFO:' log all events. This is the default value
- 'DEBUG': log all events and including detailed information on MeiliSearch's internal processes.
Useful when diagnosing issues and debugging
'';
default = "INFO";
type = types.str;
};
maxIndexSize = mkOption {
description = ''
Sets the maximum size of the index.
Value must be given in bytes or explicitly stating a base unit.
For example, the default value can be written as 107374182400, '107.7Gb', or '107374 Mb'.
Default is 100 GiB
'';
default = "107374182400";
type = types.str;
};
payloadSizeLimit = mkOption {
description = ''
Sets the maximum size of accepted JSON payloads.
Value must be given in bytes or explicitly stating a base unit.
For example, the default value can be written as 107374182400, '107.7Gb', or '107374 Mb'.
Default is ~ 100 MB
'';
default = "104857600";
type = types.str;
};
};
###### implementation
config = mkIf cfg.enable {
systemd.services.meilisearch = {
description = "MeiliSearch daemon";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
environment = {
MEILI_DB_PATH = "/var/lib/meilisearch";
MEILI_HTTP_ADDR = "${cfg.listenAddress}:${toString cfg.listenPort}";
MEILI_NO_ANALYTICS = toString cfg.noAnalytics;
MEILI_ENV = cfg.environment;
MEILI_DUMPS_DIR = "/var/lib/meilisearch/dumps";
MEILI_LOG_LEVEL = cfg.logLevel;
MEILI_MAX_INDEX_SIZE = cfg.maxIndexSize;
};
serviceConfig = {
ExecStart = "${cfg.package}/bin/meilisearch";
DynamicUser = true;
StateDirectory = "meilisearch";
EnvironmentFile = mkIf (cfg.masterKeyEnvironmentFile != null) cfg.masterKeyEnvironmentFile;
};
};
};
}

View file

@ -250,6 +250,7 @@ in
matrix-appservice-irc = handleTest ./matrix-appservice-irc.nix {};
matrix-synapse = handleTest ./matrix-synapse.nix {};
mediawiki = handleTest ./mediawiki.nix {};
meilisearch = handleTest ./meilisearch.nix {};
memcached = handleTest ./memcached.nix {};
metabase = handleTest ./metabase.nix {};
minecraft = handleTest ./minecraft.nix {};

View file

@ -0,0 +1,60 @@
import ./make-test-python.nix ({ pkgs, lib, ... }:
let
listenAddress = "127.0.0.1";
listenPort = 7700;
apiUrl = "http://${listenAddress}:${toString listenPort}";
uid = "movies";
indexJSON = pkgs.writeText "index.json" (builtins.toJSON { inherit uid; });
moviesJSON = pkgs.runCommand "movies.json" {} ''
sed -n '1,5p;$p' ${pkgs.meilisearch.src}/datasets/movies/movies.json > $out
'';
in {
name = "meilisearch";
meta.maintainers = with lib.maintainers; [ filalex77 ];
machine = { ... }: {
environment.systemPackages = with pkgs; [ curl jq ];
services.meilisearch = {
enable = true;
inherit listenAddress listenPort;
};
};
testScript = ''
import json
start_all()
machine.wait_for_unit("meilisearch")
machine.wait_for_open_port("7700")
with subtest("check version"):
version = json.loads(machine.succeed("curl ${apiUrl}/version"))
assert version["pkgVersion"] == "${pkgs.meilisearch.version}"
with subtest("create index"):
machine.succeed(
"curl -XPOST ${apiUrl}/indexes --data @${indexJSON}"
)
indexes = json.loads(machine.succeed("curl ${apiUrl}/indexes"))
assert len(indexes) == 1, "index wasn't created"
with subtest("add documents"):
response = json.loads(
machine.succeed(
"curl -XPOST ${apiUrl}/indexes/${uid}/documents --data @${moviesJSON}"
)
)
update_id = response["updateId"]
machine.wait_until_succeeds(
f"curl ${apiUrl}/indexes/${uid}/updates/{update_id} | jq -e '.status == \"processed\"'"
)
with subtest("search"):
response = json.loads(
machine.succeed("curl ${apiUrl}/indexes/movies/search?q=hero")
)
print(response)
assert len(response["hits"]) >= 1, "no results found"
'';
})

View file

@ -64,8 +64,8 @@ in
};
edge = generic {
channel = "edge";
version = "21.8.2";
sha256 = "sha256-jMYJ/mLWvuje4ZRuRbzMaqhz8kyn1bYGITJxkyw5Fyg=";
vendorSha256 = "sha256-18QB2GOxHfnP4GQaF0aohY5kEOg0xN/c+Sp33Ww/1uQ=";
version = "21.9.3";
sha256 = "0swqx4myvr24visj39icg8g90kj325pvf22bq447rnm0whq3cnyz";
vendorSha256 = "sha256-fMtAR66TwMNR/HCVQ9Jg3sJ0XBx2jUKDG7/ts0lEZM4=";
};
}

View file

@ -20,6 +20,6 @@ stdenv.mkDerivation rec {
description = "Packet sniffer for 802.15.4 wireless networks";
maintainers = with maintainers; [ snicket2100 ];
platforms = platforms.linux;
license = licenses.gpl2;
license = licenses.gpl2Only;
};
}

View file

@ -16,7 +16,7 @@ in
displayVersion ? {},
release ? {},
extraBuildInputs ? [],
namePrefix ? [],
namePrefix ? [ "coq" ],
enableParallelBuilding ? true,
extraInstallFlags ? [],
setCOQBIN ? true,
@ -27,7 +27,7 @@ in
dropDerivationAttrs ? [],
useDune2ifVersion ? (x: false),
useDune2 ? false,
opam-name ? "coq-${pname}",
opam-name ? (concatStringsSep "-" (namePrefix ++ [ pname ])),
...
}@args:
let
@ -44,7 +44,6 @@ let
location = { inherit domain owner repo; };
} // optionalAttrs (args?fetcher) {inherit fetcher;});
fetched = fetch (if !isNull version then version else defaultVersion);
namePrefix = args.namePrefix or [ "coq" ];
display-pkg = n: sep: v:
let d = displayVersion.${n} or (if sep == "" then ".." else true); in
n + optionalString (v != "" && v != null) (switch d [

View file

@ -636,7 +636,7 @@ rec {
<(sort -n layerFiles|uniq|grep -v ${layer}) -1 -3 > newFiles
# Append the new files to the layer.
tar -rpf temp/layer.tar --hard-dereference --sort=name --mtime="@$SOURCE_DATE_EPOCH" \
--owner=0 --group=0 --no-recursion --files-from newFiles
--owner=0 --group=0 --no-recursion --verbatim-files-from --files-from newFiles
echo "Adding meta..."

View file

@ -4,7 +4,6 @@ with lib; mkCoqDerivation {
namePrefix = [ "coq" "mathcomp" ];
pname = "multinomials";
opam-name = "coq-mathcomp-multinomials";
owner = "math-comp";

View file

@ -10,14 +10,14 @@ stdenv.mkDerivation rec {
};
meta = with lib; {
homepage = "http://kentonv.github.io/capnproto";
homepage = "https://capnproto.org/";
description = "Cap'n Proto cerealization protocol";
longDescription = ''
Capn Proto is an insanely fast data interchange format and
capability-based RPC system. Think JSON, except binary. Or think Protocol
Buffers, except faster.
'';
license = licenses.bsd2;
license = licenses.mit;
platforms = platforms.all;
maintainers = with maintainers; [ cstrahan ];
};

View file

@ -1,30 +1,56 @@
{lib, stdenv, fetchFromGitHub}:
{ lib
, stdenv
, fetchFromGitHub
, meson
, ninja
, libbsd
, gdk-pixbuf
, gd
, libjpeg
, pkg-config
, fetchpatch
}:
stdenv.mkDerivation rec {
version = "1.8.6";
pname = "libsixel";
version = "1.10.1";
src = fetchFromGitHub {
owner = "libsixel";
repo = "libsixel";
rev = "v${version}";
owner = "saitoha";
sha256 = "1saxdj6sldv01g6w6yk8vr7px4bl31xca3a82j6v1j3fw5rbfphy";
sha256 = "sha256-ACypJTFjXSzBjo4hQzUiJOqnaRaZnYX+/NublN9sbBo=";
};
configureFlags = [
"--enable-tests"
patches = [
(fetchpatch {
url = "https://github.com/libsixel/libsixel/commit/4d3e53ee007f3b71f638875f9fabbba658b2ca8a.patch";
sha256 = "sha256-iDfsTyUczjtzV3pt1ZErbhVO2rMm2ZYKWSBl+ru+5HA=";
})
];
buildInputs = [
libbsd gdk-pixbuf gd
];
nativeBuildInputs = [
meson ninja pkg-config
];
doCheck = true;
mesonFlags = [
"-Dtests=enabled"
# build system seems to be broken here, it still seems to handle jpeg
# through some other ways.
"-Djpeg=disabled"
"-Dpng=disabled"
];
meta = with lib; {
description = "The SIXEL library for console graphics, and converter programs";
homepage = "http://saitoha.github.com/libsixel";
homepage = "https://github.com/libsixel/libsixel";
maintainers = with maintainers; [ vrthra ];
license = licenses.mit;
platforms = with platforms; unix;
knownVulnerabilities = [
"CVE-2020-11721" # https://github.com/saitoha/libsixel/issues/134
"CVE-2020-19668" # https://github.com/saitoha/libsixel/issues/136
];
platforms = platforms.unix;
};
}

View file

@ -4,6 +4,7 @@
, pandoc
, libunistring
, ncurses
, zlib
, ffmpeg
, readline
, fetchFromGitHub
@ -13,20 +14,20 @@
stdenv.mkDerivation rec {
pname = "notcurses";
version = "2.3.8";
version = "2.4.1";
src = fetchFromGitHub {
owner = "dankamongmen";
repo = "notcurses";
rev = "v${version}";
sha256 = "sha256-CTMFXTmOnBUCm0KdVNBoDT08arr01XTHdELFiTayk3E=";
sha256 = "sha256-Oyjdmmb+rqPgkwVJw3y4NKGPABmCZFyGFBzBJn6IEHk=";
};
outputs = [ "out" "dev" ];
nativeBuildInputs = [ cmake pkg-config pandoc ];
buildInputs = [ libunistring ncurses readline ]
buildInputs = [ libunistring ncurses readline zlib ]
++ lib.optional multimediaSupport ffmpeg;
cmakeFlags = [ "-DUSE_QRCODEGEN=OFF" ]

View file

@ -1,5 +1,6 @@
source 'https://rubygems.org' do
gem 'addressable'
gem 'ansi'
gem 'atk'
gem 'awesome_print'
gem 'bacon'

View file

@ -1,19 +1,19 @@
{ lib, stdenv, graalvm11-ce, babashka, fetchurl, fetchFromGitHub, clojure }:
{ lib, stdenv, graalvm11-ce, babashka, fetchurl, fetchFromGitHub, clojure, writeScript }:
stdenv.mkDerivation rec {
pname = "clojure-lsp";
version = "2021.09.04-17.11.44";
version = "2021.09.13-22.25.35";
src = fetchFromGitHub {
owner = pname;
repo = pname;
rev = version;
sha256 = "1i12vxg3yb1051q7j6yqlsdy4lc4xl7n4lqssp8w634fpx1p0rgv";
sha256 = "0ypn0m81lbhx45y0ajpgk7id9g47l1gnihvqdjxw5m1j2hdwjdzr";
};
jar = fetchurl {
url = "https://github.com/clojure-lsp/clojure-lsp/releases/download/${version}/clojure-lsp.jar";
sha256 = "0ahrlqzyz3mgfx8w9w49172pb3dipq0hwwzk2yasqzcp1fi6jm80";
sha256 = "e93e334a4ada04a28e0b148b8364b9433b8d83f6417249d7bded7cc86d1fe081";
};
GRAALVM_HOME = graalvm11-ce;
@ -49,6 +49,27 @@ stdenv.mkDerivation rec {
runHook postCheck
'';
passthru.updateScript = writeScript "update-clojure-lsp" ''
#!/usr/bin/env nix-shell
#!nix-shell -i bash -p curl common-updater-scripts gnused jq nix
set -eu -o pipefail
latest_version=$(curl -s https://api.github.com/repos/clojure-lsp/clojure-lsp/releases/latest | jq --raw-output .tag_name)
old_jar_hash=$(nix-instantiate --eval --strict -A "clojure-lsp.jar.drvAttrs.outputHash" | tr -d '"' | sed -re 's|[+]|\\&|g')
curl -o clojure-lsp.jar -sL https://github.com/clojure-lsp/clojure-lsp/releases/download/$latest_version/clojure-lsp.jar
new_jar_hash=$(nix-hash --flat --type sha256 clojure-lsp.jar | sed -re 's|[+]|\\&|g')
rm -f clojure-lsp.jar
nixFile=$(nix-instantiate --eval --strict -A "clojure-lsp.meta.position" | sed -re 's/^"(.*):[0-9]+"$/\1/')
sed -i "$nixFile" -re "s|\"$old_jar_hash\"|\"$new_jar_hash\"|"
update-source-version clojure-lsp "$latest_version"
'';
meta = with lib; {
description = "Language Server Protocol (LSP) for Clojure";
homepage = "https://github.com/clojure-lsp/clojure-lsp";

View file

@ -12,6 +12,7 @@
, rtmpSupport ? true
, phantomjsSupport ? false
, hlsEncryptedSupport ? true
, withAlias ? false # Provides bin/youtube-dl for backcompat
}:
buildPythonPackage rec {
@ -50,6 +51,10 @@ buildPythonPackage rec {
# Requires network
doCheck = false;
postInstall = lib.optionalString withAlias ''
ln -s "$out/bin/yt-dlp" "$out/bin/youtube-dl"
'';
meta = with lib; {
homepage = "https://github.com/yt-dlp/yt-dlp/";
description = "Command-line tool to download videos from YouTube.com and other sites (youtube-dl fork)";

View file

@ -8,16 +8,16 @@ let
in rustPlatform.buildRustPackage rec {
pname = "vaultwarden";
version = "1.22.1";
version = "1.22.2";
src = fetchFromGitHub {
owner = "dani-garcia";
repo = pname;
rev = version;
sha256 = "sha256-aXbnNO3mTAgE1yNx7YVDo1vPpO8ACZpBGHQ633fNZ3k=";
sha256 = "sha256-37+Gor3xyo0yb3I4rrleJoPnqTA7G3WmeMSTltthi2E=";
};
cargoSha256 = "sha256-SFzq3OU0a0s3zlEzUkqGdZb/knYafqDamLy4ghH4i8I=";
cargoSha256 = "sha256-+zu5OfvXj8DMglf5Xv5ZcaUlbE03cwyD8TN7YftgWO0=";
nativeBuildInputs = [ pkg-config ];
buildInputs = with lib; [ openssl ]

View file

@ -130,6 +130,16 @@
};
version = "2.4.0";
};
ansi = {
groups = ["default"];
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "14ims9zfal4gs2wpx2m5rd8zsrl2k794d359shkrsgg3fhr2a22l";
type = "gem";
};
version = "1.5.0";
};
ast = {
groups = ["default"];
platforms = [];