mirror of
https://github.com/NixOS/nixpkgs.git
synced 2024-10-31 06:31:20 +00:00
lisp-modules: use wrapLisp to wrap Lisps
The previous approach of manually repeating a complex pattern inside Common Lisp implementation package declarations was fragile and hard to change. After reading python and lua modules code in Nixpkgs, I was able to come up with something better. The function `wrapLisp` doesn't need to be inside package declarations so all the code for wrapping Lisps can be in `all-packages.nix`. This works by wrapping the `override` function created from `mkDerivation` to accept a new argument `packageOverrides`. One problem with this is that `override.__functionArgs` disappears. But one can look at the source code of a package to discover what can be overridden.
This commit is contained in:
parent
653ba45834
commit
84eea85ad9
@ -285,44 +285,27 @@ loaded.
|
||||
|
||||
## Adding a new Lisp
|
||||
|
||||
Three additional functions are exposed, and are meant for wrapping Common Lisp
|
||||
derivations: `commonLispPackagesFor`, `lispWithPackages` and`build-asdf-system`.
|
||||
The function `wrapLisp` is used to wrap Common Lisp implementations and does this:
|
||||
|
||||
`commonLispPackagesFor` returns a package set for the provided Lisp "spec". Such
|
||||
a spec is an attribute set of the following keys:
|
||||
- Adds the `pkgs` attribute
|
||||
- Adds the `withPackages` attribute
|
||||
- Adds the `buildASDFSystem` attribute
|
||||
- Modifies `override` to take an additional `packageOverrides` argument
|
||||
|
||||
- `pkg`: the Lisp package derivation
|
||||
- `program`: The name of executable file in `${pkg}/bin/`
|
||||
- `flags`: A list of flags to always pass to `program`
|
||||
`wrapLisp` takes these arguments:
|
||||
|
||||
- `pkg`: the Lisp package
|
||||
- `faslExt`: Implementation-specific extension for FASL files
|
||||
- `asdf`: The ASDF version to use
|
||||
- `program`: The name of executable file in `${pkg}/bin/` (Default: `pkg.pname`)
|
||||
- `flags`: A list of flags to always pass to `program` (Default: `[]`)
|
||||
- `asdf`: The ASDF version to use (Default: `pkgs.asdf_3_3`)
|
||||
|
||||
The `spec` is an argument to every Lisp, and can be customized via `override`:
|
||||
This example wraps CLISP:
|
||||
|
||||
```
|
||||
sbcl.override {
|
||||
spec = {
|
||||
pkg = pkgs.sbcl_2_1_1;
|
||||
flags = [ "--dynamic-space-size" "4096" ];
|
||||
faslExt = "fasl";
|
||||
asdf = pkgs.asdf_3_1;
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
`lispWithPackages` returns a function to create wrappers.
|
||||
|
||||
`build-asdf-system` is the wrapper around `stdenv.mkDerivation`.
|
||||
|
||||
To wrap a new Lisp, include the following in its `passthru`:
|
||||
|
||||
```
|
||||
passthru = let
|
||||
spec' = spec // { pkg = sbcl; };
|
||||
pkgs = (commonLispPackagesFor spec').overrideScope' packageOverrides;
|
||||
in {
|
||||
inherit pkgs;
|
||||
withPackages = lispWithPackages pkgs;
|
||||
buildASDFSystem = args: build-asdf-system (args // spec');
|
||||
wrapLisp {
|
||||
pkg = clisp;
|
||||
faslExt = "fas";
|
||||
flags = ["-E" "UTF8"];
|
||||
}
|
||||
```
|
||||
|
@ -1,12 +1,5 @@
|
||||
{lib, stdenv, fetchurl, ant, jre, jdk
|
||||
# For packages
|
||||
, asdf_3_3
|
||||
, commonLispPackagesFor
|
||||
, lispWithPackages
|
||||
, build-asdf-system
|
||||
, spec ? { faslExt = "abcl"; program = "abcl"; flags = []; asdf = asdf_3_3; }
|
||||
, packageOverrides ? (self: super: {})}:
|
||||
let abcl = stdenv.mkDerivation rec {
|
||||
{lib, stdenv, fetchurl, ant, jre, jdk, ...}:
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "abcl";
|
||||
version = "1.9.0";
|
||||
# or fetchFromGitHub(owner,repo,rev) or fetchgit(rev)
|
||||
@ -47,15 +40,4 @@ let abcl = stdenv.mkDerivation rec {
|
||||
platforms = lib.platforms.linux;
|
||||
homepage = "https://common-lisp.net/project/armedbear/";
|
||||
};
|
||||
|
||||
# For packages
|
||||
passthru = let
|
||||
spec' = spec // { pkg = abcl; };
|
||||
pkgs = (commonLispPackagesFor spec').overrideScope' packageOverrides;
|
||||
in {
|
||||
inherit pkgs;
|
||||
withPackages = lispWithPackages pkgs;
|
||||
buildASDFSystem = args: build-asdf-system (args // spec');
|
||||
};
|
||||
};
|
||||
in abcl
|
||||
}
|
||||
|
@ -1,12 +1,4 @@
|
||||
{ lib, stdenv, fetchurl, fetchpatch, runCommand, bootstrap_cmds, coreutils, glibc, m4, runtimeShell
|
||||
# For packages
|
||||
, asdf_3_3
|
||||
, commonLispPackagesFor
|
||||
, lispWithPackages
|
||||
, build-asdf-system
|
||||
, spec ? { faslExt = "lx64fsl"; program = "ccl"; flags = ""; asdf = asdf_3_3; }
|
||||
, packageOverrides ? (self: super: {})
|
||||
}:
|
||||
{ lib, stdenv, fetchurl, fetchpatch, runCommand, bootstrap_cmds, coreutils, glibc, m4, runtimeShell, ... }:
|
||||
|
||||
let
|
||||
options = rec {
|
||||
@ -56,7 +48,9 @@ let
|
||||
tar czf $out ccl
|
||||
'';
|
||||
|
||||
ccl = stdenv.mkDerivation rec {
|
||||
in
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "ccl";
|
||||
version = "1.12";
|
||||
|
||||
@ -131,14 +125,4 @@ ccl = stdenv.mkDerivation rec {
|
||||
broken = (stdenv.isDarwin && stdenv.isx86_64);
|
||||
license = licenses.asl20;
|
||||
};
|
||||
|
||||
passthru = let
|
||||
spec' = spec // { pkg = ccl; };
|
||||
pkgs = (commonLispPackagesFor spec').overrideScope' packageOverrides;
|
||||
in {
|
||||
inherit pkgs;
|
||||
withPackages = lispWithPackages pkgs;
|
||||
buildASDFSystem = args: build-asdf-system (args // spec');
|
||||
};
|
||||
|
||||
}; in ccl
|
||||
}
|
||||
|
@ -14,16 +14,9 @@
|
||||
, threadSupport ? false
|
||||
, useBoehmgc ? true
|
||||
, boehmgc
|
||||
# For packages
|
||||
, asdf_3_3
|
||||
, commonLispPackagesFor
|
||||
, lispWithPackages
|
||||
, build-asdf-system
|
||||
, spec ? { faslExt = "fas"; program = "ecl"; flags = []; asdf = asdf_3_3; }
|
||||
, packageOverrides ? (self: super: {})
|
||||
}:
|
||||
, ... }:
|
||||
|
||||
let ecl = stdenv.mkDerivation rec {
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "ecl";
|
||||
version = "16.1.2";
|
||||
|
||||
@ -103,14 +96,4 @@ let ecl = stdenv.mkDerivation rec {
|
||||
# never built on aarch64-darwin since first introduction in nixpkgs
|
||||
broken = stdenv.isDarwin && stdenv.isAarch64;
|
||||
};
|
||||
|
||||
passthru = let
|
||||
spec' = spec // { pkg = ecl; };
|
||||
pkgs = (commonLispPackagesFor spec').overrideScope' packageOverrides;
|
||||
in {
|
||||
inherit pkgs;
|
||||
withPackages = lispWithPackages pkgs;
|
||||
buildASDFSystem = args: build-asdf-system (args // spec');
|
||||
};
|
||||
};
|
||||
in ecl
|
||||
}
|
||||
|
@ -15,16 +15,9 @@
|
||||
, threadSupport ? true
|
||||
, useBoehmgc ? false
|
||||
, boehmgc
|
||||
# For packages
|
||||
, asdf_3_3
|
||||
, commonLispPackagesFor
|
||||
, lispWithPackages
|
||||
, build-asdf-system
|
||||
, spec ? { faslExt = "fas"; program = "ecl"; flags = []; asdf = asdf_3_3; }
|
||||
, packageOverrides ? (self: super: {})
|
||||
}:
|
||||
, ... }:
|
||||
|
||||
let ecl = stdenv.mkDerivation rec {
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "ecl";
|
||||
version = "21.2.1";
|
||||
|
||||
@ -90,15 +83,4 @@ let ecl = stdenv.mkDerivation rec {
|
||||
platforms = platforms.unix;
|
||||
changelog = "https://gitlab.com/embeddable-common-lisp/ecl/-/raw/${version}/CHANGELOG";
|
||||
};
|
||||
|
||||
# For packages
|
||||
passthru = let
|
||||
spec' = spec // { pkg = ecl; };
|
||||
pkgs = (commonLispPackagesFor spec').overrideScope' packageOverrides;
|
||||
in {
|
||||
inherit pkgs;
|
||||
withPackages = lispWithPackages pkgs;
|
||||
buildASDFSystem = args: build-asdf-system (args // spec');
|
||||
};
|
||||
|
||||
}; in ecl
|
||||
}
|
||||
|
@ -10,14 +10,7 @@
|
||||
, coreCompression ? lib.versionAtLeast version "2.2.6"
|
||||
, texinfo
|
||||
, version
|
||||
# For packages
|
||||
, asdf_3_3
|
||||
, commonLispPackagesFor
|
||||
, lispWithPackages
|
||||
, build-asdf-system
|
||||
, spec ? { faslExt = "fasl"; program = "sbcl"; flags = []; asdf = asdf_3_3; }
|
||||
, packageOverrides ? (self: super: {})
|
||||
}:
|
||||
, ... }:
|
||||
|
||||
let
|
||||
versionMap = {
|
||||
@ -74,7 +67,7 @@ let
|
||||
};
|
||||
};
|
||||
|
||||
sbcl = with versionMap.${version};
|
||||
in with versionMap.${version};
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "sbcl";
|
||||
@ -226,15 +219,4 @@ stdenv.mkDerivation rec {
|
||||
'');
|
||||
|
||||
meta = sbclBootstrap.meta;
|
||||
|
||||
# For packages
|
||||
passthru = let
|
||||
spec' = spec // { pkg = sbcl; };
|
||||
pkgs = (commonLispPackagesFor spec').overrideScope' packageOverrides;
|
||||
in {
|
||||
inherit pkgs;
|
||||
withPackages = lispWithPackages pkgs;
|
||||
buildASDFSystem = args: build-asdf-system (args // spec');
|
||||
};
|
||||
};
|
||||
in sbcl
|
||||
}
|
||||
|
@ -18,19 +18,12 @@
|
||||
]
|
||||
++ lib.optionals stdenv.isLinux [ "bindings/glibc" "zlib" "wildcard" ]
|
||||
++ lib.optional x11Support "clx/new-clx"
|
||||
# For packages
|
||||
, asdf_3_3
|
||||
, commonLispPackagesFor
|
||||
, lispWithPackages
|
||||
, build-asdf-system
|
||||
, spec ? { faslExt = "fas"; program = "clisp"; flags = ["-E" "UTF-8"]; asdf = asdf_3_3; }
|
||||
, packageOverrides ? (self: super: {})
|
||||
}:
|
||||
, ... }:
|
||||
|
||||
assert x11Support -> (libX11 != null && libXau != null && libXt != null
|
||||
&& libXpm != null && xorgproto != null && libXext != null);
|
||||
|
||||
let clisp = stdenv.mkDerivation rec {
|
||||
stdenv.mkDerivation rec {
|
||||
version = "2.49";
|
||||
pname = "clisp";
|
||||
|
||||
@ -112,14 +105,4 @@ let clisp = stdenv.mkDerivation rec {
|
||||
broken = stdenv.hostPlatform.isDarwin || stdenv.hostPlatform.isAarch64;
|
||||
license = lib.licenses.gpl2;
|
||||
};
|
||||
|
||||
passthru = let
|
||||
spec' = spec // { pkg = clisp; };
|
||||
pkgs = (commonLispPackagesFor spec').overrideScope' packageOverrides;
|
||||
in {
|
||||
inherit pkgs;
|
||||
withPackages = lispWithPackages pkgs;
|
||||
buildASDFSystem = args: build-asdf-system (args // spec');
|
||||
};
|
||||
|
||||
}; in clisp
|
||||
}
|
||||
|
@ -17,19 +17,12 @@
|
||||
]
|
||||
++ lib.optionals stdenv.isLinux [ "bindings/glibc" "zlib" ]
|
||||
++ lib.optional x11Support "clx/new-clx"
|
||||
# For packages
|
||||
, asdf_3_3
|
||||
, commonLispPackagesFor
|
||||
, lispWithPackages
|
||||
, build-asdf-system
|
||||
, spec ? { faslExt = "fas"; program = "clisp"; flags = "-E UTF-8"; asdf = asdf_3_3; }
|
||||
, packageOverrides ? (self: super: {})
|
||||
}:
|
||||
, ... }:
|
||||
|
||||
assert x11Support -> (libX11 != null && libXau != null && libXt != null
|
||||
&& libXpm != null && xorgproto != null && libXext != null);
|
||||
|
||||
let clisp = stdenv.mkDerivation rec {
|
||||
stdenv.mkDerivation rec {
|
||||
version = "2.50pre20171114";
|
||||
pname = "clisp";
|
||||
|
||||
@ -102,14 +95,4 @@ let clisp = stdenv.mkDerivation rec {
|
||||
# problems on Darwin: https://github.com/NixOS/nixpkgs/issues/20062
|
||||
platforms = lib.platforms.linux;
|
||||
};
|
||||
|
||||
passthru = let
|
||||
spec' = spec // { pkg = clisp; };
|
||||
pkgs = (commonLispPackagesFor spec').overrideScope' packageOverrides;
|
||||
in {
|
||||
inherit pkgs;
|
||||
withPackages = lispWithPackages pkgs;
|
||||
buildASDFSystem = args: build-asdf-system (args // spec');
|
||||
};
|
||||
|
||||
}; in clisp
|
||||
}
|
||||
|
@ -170,4 +170,4 @@ in lib.makeScope pkgs.newScope (self: {")
|
||||
,@(when (or (find #\/ name)
|
||||
(find name +broken-packages+ :test #'string=))
|
||||
'(("meta" (:attrs ("broken" (:symbol "true")))))))))))))
|
||||
(format f "~%})"))))
|
||||
(format f "~%})~%"))))
|
||||
|
@ -286,8 +286,25 @@ let
|
||||
'';
|
||||
});
|
||||
|
||||
in {
|
||||
inherit commonLispPackagesFor;
|
||||
inherit lispWithPackages;
|
||||
inherit build-asdf-system;
|
||||
}
|
||||
wrapLisp = { pkg, faslExt, program ? pkg.pname, flags ? [], asdf ? pkgs.asdf_3_3 }:
|
||||
let
|
||||
spec = { inherit pkg faslExt program flags asdf; };
|
||||
pkgs = commonLispPackagesFor spec;
|
||||
withPackages = lispWithPackages pkgs;
|
||||
override =
|
||||
{ packageOverrides ? (self: super: {}) , ... } @ attrs:
|
||||
let
|
||||
pkg' = spec.pkg.override attrs;
|
||||
spec' = spec // { pkg = pkg'; };
|
||||
pkgs = (commonLispPackagesFor spec').overrideScope' packageOverrides;
|
||||
withPackages = lispWithPackages pkgs;
|
||||
in pkg' // {
|
||||
inherit pkgs withPackages override;
|
||||
buildASDFSystem = args: build-asdf-system (args // spec');
|
||||
};
|
||||
in pkg // {
|
||||
inherit pkgs withPackages override;
|
||||
buildASDFSystem = args: build-asdf-system (args // spec);
|
||||
};
|
||||
|
||||
in wrapLisp
|
||||
|
@ -24177,55 +24177,116 @@ with pkgs;
|
||||
texLive = null;
|
||||
};
|
||||
|
||||
inherit (callPackage ../development/lisp-modules/nix-cl.nix {})
|
||||
commonLispPackagesFor
|
||||
lispWithPackages
|
||||
build-asdf-system
|
||||
;
|
||||
wrapLisp = callPackage ../development/lisp-modules/nix-cl.nix {};
|
||||
|
||||
# Armed Bear Common Lisp
|
||||
abcl = callPackage ../development/compilers/abcl { };
|
||||
abcl = wrapLisp {
|
||||
pkg = callPackage ../development/compilers/abcl { };
|
||||
faslExt = "abcl";
|
||||
};
|
||||
|
||||
# Clozure Common Lisp
|
||||
ccl = callPackage ../development/compilers/ccl {
|
||||
inherit (buildPackages.darwin) bootstrap_cmds;
|
||||
ccl = wrapLisp {
|
||||
pkg = callPackage ../development/compilers/ccl {
|
||||
inherit (buildPackages.darwin) bootstrap_cmds;
|
||||
};
|
||||
faslExt = "lx64fsl";
|
||||
};
|
||||
|
||||
# Clasp Common Lisp
|
||||
clasp-common-lisp = callPackage ../development/compilers/clasp {
|
||||
llvmPackages = llvmPackages_15;
|
||||
stdenv = llvmPackages_15.stdenv;
|
||||
clasp-common-lisp = wrapLisp {
|
||||
pkg = callPackage ../development/compilers/clasp {
|
||||
llvmPackages = llvmPackages_15;
|
||||
stdenv = llvmPackages_15.stdenv;
|
||||
};
|
||||
faslExt = "fasp";
|
||||
};
|
||||
|
||||
# CLISP
|
||||
clisp = callPackage ../development/interpreters/clisp {
|
||||
clisp = wrapLisp {
|
||||
pkg = callPackage ../development/interpreters/clisp {
|
||||
# On newer readline8 fails as:
|
||||
# #<FOREIGN-VARIABLE "rl_readline_state" #x...>
|
||||
# does not have the required size or alignment
|
||||
readline = readline63;
|
||||
};
|
||||
faslExt = "fas";
|
||||
flags = ["-E" "UTF-8"];
|
||||
};
|
||||
|
||||
clisp-tip = callPackage ../development/interpreters/clisp/hg.nix { };
|
||||
clisp-tip = wrapLisp {
|
||||
pkg = callPackage ../development/interpreters/clisp/hg.nix { };
|
||||
faslExt = "fas";
|
||||
flags = ["-E" "UTF-8"];
|
||||
};
|
||||
|
||||
# Embeddable Common Lisp
|
||||
ecl = callPackage ../development/compilers/ecl { };
|
||||
ecl_16_1_2 = callPackage ../development/compilers/ecl/16.1.2.nix { };
|
||||
ecl = wrapLisp {
|
||||
pkg = callPackage ../development/compilers/ecl { };
|
||||
faslExt = "fas";
|
||||
};
|
||||
ecl_16_1_2 = wrapLisp {
|
||||
pkg = callPackage ../development/compilers/ecl/16.1.2.nix { };
|
||||
faslExt = "fas";
|
||||
};
|
||||
|
||||
# Steel Bank Common Lisp
|
||||
sbclBootstrap = callPackage ../development/compilers/sbcl/bootstrap.nix {};
|
||||
sbcl_2_0_8 = callPackage ../development/compilers/sbcl/2.x.nix { version = "2.0.8"; };
|
||||
sbcl_2_0_9 = callPackage ../development/compilers/sbcl/2.x.nix { version = "2.0.9"; };
|
||||
sbcl_2_1_1 = callPackage ../development/compilers/sbcl/2.x.nix { version = "2.1.1"; };
|
||||
sbcl_2_1_2 = callPackage ../development/compilers/sbcl/2.x.nix { version = "2.1.2"; };
|
||||
sbcl_2_1_9 = callPackage ../development/compilers/sbcl/2.x.nix { version = "2.1.9"; };
|
||||
sbcl_2_1_10 = callPackage ../development/compilers/sbcl/2.x.nix { version = "2.1.10"; };
|
||||
sbcl_2_1_11 = callPackage ../development/compilers/sbcl/2.x.nix { version = "2.1.11"; };
|
||||
sbcl_2_2_4 = callPackage ../development/compilers/sbcl/2.x.nix { version = "2.2.4"; };
|
||||
sbcl_2_2_6 = callPackage ../development/compilers/sbcl/2.x.nix { version = "2.2.6"; };
|
||||
sbcl_2_2_9 = callPackage ../development/compilers/sbcl/2.x.nix { version = "2.2.9"; };
|
||||
sbcl_2_2_10 = callPackage ../development/compilers/sbcl/2.x.nix { version = "2.2.10"; };
|
||||
sbcl_2_2_11 = callPackage ../development/compilers/sbcl/2.x.nix { version = "2.2.11"; };
|
||||
sbcl_2_3_0 = callPackage ../development/compilers/sbcl/2.x.nix { version = "2.3.0"; };
|
||||
sbclBootstrap = wrapLisp {
|
||||
pkg = callPackage ../development/compilers/sbcl/bootstrap.nix {};
|
||||
faslExt = "fasl";
|
||||
};
|
||||
sbcl_2_0_8 = wrapLisp {
|
||||
pkg = callPackage ../development/compilers/sbcl/2.x.nix { version = "2.0.8"; };
|
||||
faslExt = "fasl";
|
||||
};
|
||||
sbcl_2_0_9 = wrapLisp {
|
||||
pkg = callPackage ../development/compilers/sbcl/2.x.nix { version = "2.0.9"; };
|
||||
faslExt = "fasl";
|
||||
};
|
||||
sbcl_2_1_1 = wrapLisp {
|
||||
pkg = callPackage ../development/compilers/sbcl/2.x.nix { version = "2.1.1"; };
|
||||
faslExt = "fasl";
|
||||
};
|
||||
sbcl_2_1_2 = wrapLisp {
|
||||
pkg = callPackage ../development/compilers/sbcl/2.x.nix { version = "2.1.2"; };
|
||||
faslExt = "fasl";
|
||||
};
|
||||
sbcl_2_1_9 = wrapLisp {
|
||||
pkg = callPackage ../development/compilers/sbcl/2.x.nix { version = "2.1.9"; };
|
||||
faslExt = "fasl";
|
||||
};
|
||||
sbcl_2_1_10 = wrapLisp {
|
||||
pkg = callPackage ../development/compilers/sbcl/2.x.nix { version = "2.1.10"; };
|
||||
faslExt = "fasl";
|
||||
};
|
||||
sbcl_2_1_11 = wrapLisp {
|
||||
pkg = callPackage ../development/compilers/sbcl/2.x.nix { version = "2.1.11"; };
|
||||
faslExt = "fasl";
|
||||
};
|
||||
sbcl_2_2_4 = wrapLisp {
|
||||
pkg = callPackage ../development/compilers/sbcl/2.x.nix { version = "2.2.4"; };
|
||||
faslExt = "fasl";
|
||||
};
|
||||
sbcl_2_2_6 = wrapLisp {
|
||||
pkg = callPackage ../development/compilers/sbcl/2.x.nix { version = "2.2.6"; };
|
||||
faslExt = "fasl";
|
||||
};
|
||||
sbcl_2_2_9 = wrapLisp {
|
||||
pkg = callPackage ../development/compilers/sbcl/2.x.nix { version = "2.2.9"; };
|
||||
faslExt = "fasl";
|
||||
};
|
||||
sbcl_2_2_10 = wrapLisp {
|
||||
pkg = callPackage ../development/compilers/sbcl/2.x.nix { version = "2.2.10"; };
|
||||
faslExt = "fasl";
|
||||
};
|
||||
sbcl_2_2_11 = wrapLisp {
|
||||
pkg = callPackage ../development/compilers/sbcl/2.x.nix { version = "2.2.11"; };
|
||||
faslExt = "fasl";
|
||||
};
|
||||
sbcl_2_3_0 = wrapLisp {
|
||||
pkg = callPackage ../development/compilers/sbcl/2.x.nix { version = "2.3.0"; };
|
||||
faslExt = "fasl";
|
||||
};
|
||||
sbcl = sbcl_2_3_0;
|
||||
|
||||
sbclPackages = recurseIntoAttrs sbcl.pkgs;
|
||||
|
Loading…
Reference in New Issue
Block a user