Initial commit
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+8
@@ -0,0 +1,8 @@
|
||||
import { ExtraSpawnOptions } from "builder-util";
|
||||
import { ExecFileOptions, SpawnOptions } from "child_process";
|
||||
import { VmManager } from "./vm";
|
||||
export declare class MonoVmManager extends VmManager {
|
||||
constructor();
|
||||
exec(file: string, args: Array<string>, options?: ExecFileOptions, isLogOutIfDebug?: boolean): Promise<string>;
|
||||
spawn(file: string, args: Array<string>, options?: SpawnOptions, extraOptions?: ExtraSpawnOptions): Promise<any>;
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.MonoVmManager = void 0;
|
||||
const builder_util_1 = require("builder-util");
|
||||
const vm_1 = require("./vm");
|
||||
class MonoVmManager extends vm_1.VmManager {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
exec(file, args, options, isLogOutIfDebug = true) {
|
||||
return (0, builder_util_1.exec)("mono", [file].concat(args), {
|
||||
...options,
|
||||
}, isLogOutIfDebug);
|
||||
}
|
||||
spawn(file, args, options, extraOptions) {
|
||||
return (0, builder_util_1.spawn)("mono", [file].concat(args), options, extraOptions);
|
||||
}
|
||||
}
|
||||
exports.MonoVmManager = MonoVmManager;
|
||||
//# sourceMappingURL=MonoVm.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"MonoVm.js","sourceRoot":"","sources":["../../src/vm/MonoVm.ts"],"names":[],"mappings":";;;AAAA,+CAA6D;AAE7D,6BAAgC;AAEhC,MAAa,aAAc,SAAQ,cAAS;IAC1C;QACE,KAAK,EAAE,CAAA;IACT,CAAC;IAED,IAAI,CAAC,IAAY,EAAE,IAAmB,EAAE,OAAyB,EAAE,eAAe,GAAG,IAAI;QACvF,OAAO,IAAA,mBAAI,EACT,MAAM,EACN,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EACnB;YACE,GAAG,OAAO;SACX,EACD,eAAe,CAChB,CAAA;IACH,CAAC;IAED,KAAK,CAAC,IAAY,EAAE,IAAmB,EAAE,OAAsB,EAAE,YAAgC;QAC/F,OAAO,IAAA,oBAAK,EAAC,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,YAAY,CAAC,CAAA;IAClE,CAAC;CACF;AAnBD,sCAmBC","sourcesContent":["import { exec, ExtraSpawnOptions, spawn } from \"builder-util\"\nimport { ExecFileOptions, SpawnOptions } from \"child_process\"\nimport { VmManager } from \"./vm\"\n\nexport class MonoVmManager extends VmManager {\n constructor() {\n super()\n }\n\n exec(file: string, args: Array<string>, options?: ExecFileOptions, isLogOutIfDebug = true): Promise<string> {\n return exec(\n \"mono\",\n [file].concat(args),\n {\n ...options,\n },\n isLogOutIfDebug\n )\n }\n\n spawn(file: string, args: Array<string>, options?: SpawnOptions, extraOptions?: ExtraSpawnOptions): Promise<any> {\n return spawn(\"mono\", [file].concat(args), options, extraOptions)\n }\n}\n"]}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
export declare function macPathToParallelsWindows(file: string): string;
|
||||
export interface ParallelsVm {
|
||||
id: string;
|
||||
name: string;
|
||||
os: "win-10" | "win-11" | "ubuntu" | "elementary";
|
||||
state: "running" | "suspended" | "stopped";
|
||||
}
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ParallelsVmManager = void 0;
|
||||
exports.parseVmList = parseVmList;
|
||||
exports.macPathToParallelsWindows = macPathToParallelsWindows;
|
||||
const builder_util_1 = require("builder-util");
|
||||
const child_process_1 = require("child_process");
|
||||
const vm_1 = require("./vm");
|
||||
/** @internal */
|
||||
async function parseVmList(debugLogger) {
|
||||
// do not log output if debug - it is huge, logged using debugLogger
|
||||
let rawList = await (0, builder_util_1.exec)("prlctl", ["list", "-i", "-s", "name"], undefined, false);
|
||||
debugLogger.add("parallels.list", rawList);
|
||||
rawList = rawList.substring(rawList.indexOf("ID:"));
|
||||
// let match: Array<string> | null
|
||||
const result = [];
|
||||
for (const info of rawList
|
||||
.split("\n\n")
|
||||
.map(it => it.trim())
|
||||
.filter(it => it.length > 0)) {
|
||||
const vm = {};
|
||||
for (const line of info.split("\n")) {
|
||||
const meta = /^([^:("]+): (.*)$/.exec(line);
|
||||
if (meta == null) {
|
||||
continue;
|
||||
}
|
||||
const key = meta[1].toLowerCase();
|
||||
if (key === "id" || key === "os" || key === "name" || key === "state" || key === "name") {
|
||||
vm[key] = meta[2].trim();
|
||||
}
|
||||
}
|
||||
result.push(vm);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/** @internal */
|
||||
class ParallelsVmManager extends vm_1.VmManager {
|
||||
constructor(vm) {
|
||||
super();
|
||||
this.vm = vm;
|
||||
this.isExitHookAdded = false;
|
||||
this.startPromise = this.doStartVm();
|
||||
}
|
||||
get pathSep() {
|
||||
return "/";
|
||||
}
|
||||
handleExecuteError(error) {
|
||||
if (error.message.includes("Unable to open new session in this virtual machine")) {
|
||||
throw new Error(`Please ensure that your are logged in "${this.vm.name}" parallels virtual machine. In the future please do not stop VM, but suspend.\n\n${error.message}`);
|
||||
}
|
||||
builder_util_1.log.warn("ensure that 'Share folders' is set to 'All Disks', see https://goo.gl/E6XphP");
|
||||
throw error;
|
||||
}
|
||||
async exec(file, args, options) {
|
||||
await this.ensureThatVmStarted();
|
||||
// it is important to use "--current-user" to execute command under logged in user - to access certs.
|
||||
return await (0, builder_util_1.exec)("prlctl", ["exec", this.vm.id, "--current-user", file.startsWith("/") ? macPathToParallelsWindows(file) : file].concat(args), options).catch(error => this.handleExecuteError(error));
|
||||
}
|
||||
async spawn(file, args, options, extraOptions) {
|
||||
await this.ensureThatVmStarted();
|
||||
return await (0, builder_util_1.spawn)("prlctl", ["exec", this.vm.id, file].concat(args), options, extraOptions).catch(error => this.handleExecuteError(error));
|
||||
}
|
||||
async doStartVm() {
|
||||
const vmId = this.vm.id;
|
||||
const state = this.vm.state;
|
||||
if (state === "running") {
|
||||
return;
|
||||
}
|
||||
if (!this.isExitHookAdded) {
|
||||
this.isExitHookAdded = true;
|
||||
require("async-exit-hook")((callback) => {
|
||||
const stopArgs = ["suspend", vmId];
|
||||
if (callback == null) {
|
||||
(0, child_process_1.execFileSync)("prlctl", stopArgs);
|
||||
}
|
||||
else {
|
||||
(0, builder_util_1.exec)("prlctl", stopArgs).then(callback).catch(callback);
|
||||
}
|
||||
});
|
||||
}
|
||||
await (0, builder_util_1.exec)("prlctl", ["start", vmId]);
|
||||
}
|
||||
ensureThatVmStarted() {
|
||||
let startPromise = this.startPromise;
|
||||
if (startPromise == null) {
|
||||
startPromise = this.doStartVm();
|
||||
this.startPromise = startPromise;
|
||||
}
|
||||
return startPromise;
|
||||
}
|
||||
toVmFile(file) {
|
||||
// https://stackoverflow.com/questions/4742992/cannot-access-network-drive-in-powershell-running-as-administrator
|
||||
return macPathToParallelsWindows(file);
|
||||
}
|
||||
}
|
||||
exports.ParallelsVmManager = ParallelsVmManager;
|
||||
function macPathToParallelsWindows(file) {
|
||||
if (file.startsWith("C:\\")) {
|
||||
return file;
|
||||
}
|
||||
return "\\\\Mac\\Host\\" + file.replace(/\//g, "\\");
|
||||
}
|
||||
//# sourceMappingURL=ParallelsVm.js.map
|
||||
+1
File diff suppressed because one or more lines are too long
+6
@@ -0,0 +1,6 @@
|
||||
import { Lazy } from "lazy-val";
|
||||
import { VmManager } from "./vm";
|
||||
export declare class PwshVmManager extends VmManager {
|
||||
constructor();
|
||||
readonly powershellCommand: Lazy<string>;
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.PwshVmManager = void 0;
|
||||
const builder_util_1 = require("builder-util");
|
||||
const lazy_val_1 = require("lazy-val");
|
||||
const vm_1 = require("./vm");
|
||||
class PwshVmManager extends vm_1.VmManager {
|
||||
constructor() {
|
||||
super();
|
||||
this.powershellCommand = new lazy_val_1.Lazy(async () => {
|
||||
builder_util_1.log.info(null, "checking for `pwsh` for powershell");
|
||||
if (await vm_1.isPwshAvailable.value) {
|
||||
return "pwsh";
|
||||
}
|
||||
const errorMessage = `unable to find \`pwsh\`, please install per instructions linked in logs`;
|
||||
builder_util_1.log.error({
|
||||
mac: "https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-on-macos",
|
||||
linux: "https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-on-linux",
|
||||
}, errorMessage);
|
||||
throw new Error(errorMessage);
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.PwshVmManager = PwshVmManager;
|
||||
//# sourceMappingURL=PwshVm.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"PwshVm.js","sourceRoot":"","sources":["../../src/vm/PwshVm.ts"],"names":[],"mappings":";;;AAAA,+CAAkC;AAClC,uCAA+B;AAC/B,6BAAiD;AAEjD,MAAa,aAAc,SAAQ,cAAS;IAC1C;QACE,KAAK,EAAE,CAAA;QAGA,sBAAiB,GAAG,IAAI,eAAI,CAAS,KAAK,IAAI,EAAE;YACvD,kBAAG,CAAC,IAAI,CAAC,IAAI,EAAE,oCAAoC,CAAC,CAAA;YACpD,IAAI,MAAM,oBAAe,CAAC,KAAK,EAAE,CAAC;gBAChC,OAAO,MAAM,CAAA;YACf,CAAC;YACD,MAAM,YAAY,GAAG,yEAAyE,CAAA;YAC9F,kBAAG,CAAC,KAAK,CACP;gBACE,GAAG,EAAE,+FAA+F;gBACpG,KAAK,EAAE,+FAA+F;aACvG,EACD,YAAY,CACb,CAAA;YACD,MAAM,IAAI,KAAK,CAAC,YAAY,CAAC,CAAA;QAC/B,CAAC,CAAC,CAAA;IAhBF,CAAC;CAiBF;AApBD,sCAoBC","sourcesContent":["import { log } from \"builder-util\"\nimport { Lazy } from \"lazy-val\"\nimport { isPwshAvailable, VmManager } from \"./vm\"\n\nexport class PwshVmManager extends VmManager {\n constructor() {\n super()\n }\n\n readonly powershellCommand = new Lazy<string>(async () => {\n log.info(null, \"checking for `pwsh` for powershell\")\n if (await isPwshAvailable.value) {\n return \"pwsh\"\n }\n const errorMessage = `unable to find \\`pwsh\\`, please install per instructions linked in logs`\n log.error(\n {\n mac: \"https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-on-macos\",\n linux: \"https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-on-linux\",\n },\n errorMessage\n )\n throw new Error(errorMessage)\n })\n}\n"]}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
import { ExtraSpawnOptions } from "builder-util";
|
||||
import { ExecFileOptions, SpawnOptions } from "child_process";
|
||||
import { VmManager } from "./vm";
|
||||
export declare class WineVmManager extends VmManager {
|
||||
constructor();
|
||||
exec(file: string, args: Array<string>, options?: ExecFileOptions, isLogOutIfDebug?: boolean): Promise<string>;
|
||||
spawn(file: string, args: Array<string>, options?: SpawnOptions, extraOptions?: ExtraSpawnOptions): Promise<any>;
|
||||
toVmFile(file: string): string;
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.WineVmManager = void 0;
|
||||
const path = require("path");
|
||||
const wine_1 = require("../wine");
|
||||
const vm_1 = require("./vm");
|
||||
class WineVmManager extends vm_1.VmManager {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
exec(file, args, options, isLogOutIfDebug = true) {
|
||||
return (0, wine_1.execWine)(file, null, args, options);
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
spawn(file, args, options, extraOptions) {
|
||||
throw new Error("Unsupported");
|
||||
}
|
||||
toVmFile(file) {
|
||||
return path.win32.join("Z:", file);
|
||||
}
|
||||
}
|
||||
exports.WineVmManager = WineVmManager;
|
||||
//# sourceMappingURL=WineVm.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"WineVm.js","sourceRoot":"","sources":["../../src/vm/WineVm.ts"],"names":[],"mappings":";;;AAEA,6BAA4B;AAC5B,kCAAkC;AAClC,6BAAgC;AAEhC,MAAa,aAAc,SAAQ,cAAS;IAC1C;QACE,KAAK,EAAE,CAAA;IACT,CAAC;IAED,6DAA6D;IAC7D,IAAI,CAAC,IAAY,EAAE,IAAmB,EAAE,OAAyB,EAAE,eAAe,GAAG,IAAI;QACvF,OAAO,IAAA,eAAQ,EAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;IAC5C,CAAC;IAED,6DAA6D;IAC7D,KAAK,CAAC,IAAY,EAAE,IAAmB,EAAE,OAAsB,EAAE,YAAgC;QAC/F,MAAM,IAAI,KAAK,CAAC,aAAa,CAAC,CAAA;IAChC,CAAC;IAED,QAAQ,CAAC,IAAY;QACnB,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;IACpC,CAAC;CACF;AAlBD,sCAkBC","sourcesContent":["import { ExtraSpawnOptions } from \"builder-util\"\nimport { ExecFileOptions, SpawnOptions } from \"child_process\"\nimport * as path from \"path\"\nimport { execWine } from \"../wine\"\nimport { VmManager } from \"./vm\"\n\nexport class WineVmManager extends VmManager {\n constructor() {\n super()\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n exec(file: string, args: Array<string>, options?: ExecFileOptions, isLogOutIfDebug = true): Promise<string> {\n return execWine(file, null, args, options)\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n spawn(file: string, args: Array<string>, options?: SpawnOptions, extraOptions?: ExtraSpawnOptions): Promise<any> {\n throw new Error(\"Unsupported\")\n }\n\n toVmFile(file: string): string {\n return path.win32.join(\"Z:\", file)\n }\n}\n"]}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
import { DebugLogger, ExtraSpawnOptions } from "builder-util";
|
||||
import { ExecFileOptions, SpawnOptions } from "child_process";
|
||||
import { Lazy } from "lazy-val";
|
||||
export declare class VmManager {
|
||||
get pathSep(): string;
|
||||
exec(file: string, args: Array<string>, options?: ExecFileOptions, isLogOutIfDebug?: boolean): Promise<string>;
|
||||
spawn(file: string, args: Array<string>, options?: SpawnOptions, extraOptions?: ExtraSpawnOptions): Promise<any>;
|
||||
toVmFile(file: string): string;
|
||||
readonly powershellCommand: Lazy<string>;
|
||||
}
|
||||
export declare function getWindowsVm(debugLogger: DebugLogger): Promise<VmManager>;
|
||||
export declare const isPwshAvailable: Lazy<boolean>;
|
||||
export declare const isCommandAvailable: (command: string, args: string[]) => Promise<boolean>;
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.isCommandAvailable = exports.isPwshAvailable = exports.VmManager = void 0;
|
||||
exports.getWindowsVm = getWindowsVm;
|
||||
const builder_util_1 = require("builder-util");
|
||||
const lazy_val_1 = require("lazy-val");
|
||||
const path = require("path");
|
||||
class VmManager {
|
||||
constructor() {
|
||||
this.powershellCommand = new lazy_val_1.Lazy(() => {
|
||||
return this.exec("powershell.exe", ["-NoProfile", "-NonInteractive", "-Command", `Get-Command pwsh.exe`])
|
||||
.then(() => {
|
||||
builder_util_1.log.info(null, "identified pwsh.exe");
|
||||
return "pwsh.exe";
|
||||
})
|
||||
.catch(() => {
|
||||
builder_util_1.log.info(null, "unable to find pwsh.exe, falling back to powershell.exe");
|
||||
return "powershell.exe";
|
||||
});
|
||||
});
|
||||
}
|
||||
get pathSep() {
|
||||
return path.sep;
|
||||
}
|
||||
exec(file, args, options, isLogOutIfDebug = true) {
|
||||
return (0, builder_util_1.exec)(file, args, options, isLogOutIfDebug);
|
||||
}
|
||||
spawn(file, args, options, extraOptions) {
|
||||
return (0, builder_util_1.spawn)(file, args, options, extraOptions);
|
||||
}
|
||||
toVmFile(file) {
|
||||
return file;
|
||||
}
|
||||
}
|
||||
exports.VmManager = VmManager;
|
||||
async function getWindowsVm(debugLogger) {
|
||||
const parallelsVmModule = await Promise.resolve().then(() => require("./ParallelsVm"));
|
||||
let vmList = [];
|
||||
try {
|
||||
vmList = (await parallelsVmModule.parseVmList(debugLogger)).filter(it => ["win-10", "win-11"].includes(it.os));
|
||||
}
|
||||
catch (_error) {
|
||||
if ((await exports.isPwshAvailable.value) && (await isWineAvailable.value)) {
|
||||
const vmModule = await Promise.resolve().then(() => require("./PwshVm"));
|
||||
return new vmModule.PwshVmManager();
|
||||
}
|
||||
}
|
||||
if (vmList.length === 0) {
|
||||
throw new builder_util_1.InvalidConfigurationError("Cannot find suitable Parallels Desktop virtual machine (Windows 10 is required) and cannot access `pwsh` and `wine` locally");
|
||||
}
|
||||
// prefer running or suspended vm
|
||||
return new parallelsVmModule.ParallelsVmManager(vmList.find(it => it.state === "running") || vmList.find(it => it.state === "suspended") || vmList[0]);
|
||||
}
|
||||
const isWineAvailable = new lazy_val_1.Lazy(async () => {
|
||||
return (0, exports.isCommandAvailable)("wine", ["--version"]);
|
||||
});
|
||||
exports.isPwshAvailable = new lazy_val_1.Lazy(async () => {
|
||||
return (0, exports.isCommandAvailable)("pwsh", ["--version"]);
|
||||
});
|
||||
const isCommandAvailable = async (command, args) => {
|
||||
try {
|
||||
await (0, builder_util_1.exec)(command, args);
|
||||
return true;
|
||||
}
|
||||
catch {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
exports.isCommandAvailable = isCommandAvailable;
|
||||
//# sourceMappingURL=vm.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"vm.js","sourceRoot":"","sources":["../../src/vm/vm.ts"],"names":[],"mappings":"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","sourcesContent":["import { DebugLogger, exec, ExtraSpawnOptions, InvalidConfigurationError, log, spawn } from \"builder-util\"\nimport { ExecFileOptions, SpawnOptions } from \"child_process\"\nimport { Lazy } from \"lazy-val\"\nimport * as path from \"path\"\nimport { ParallelsVm } from \"./ParallelsVm\"\nexport class VmManager {\n get pathSep(): string {\n return path.sep\n }\n\n exec(file: string, args: Array<string>, options?: ExecFileOptions, isLogOutIfDebug = true): Promise<string> {\n return exec(file, args, options, isLogOutIfDebug)\n }\n\n spawn(file: string, args: Array<string>, options?: SpawnOptions, extraOptions?: ExtraSpawnOptions): Promise<any> {\n return spawn(file, args, options, extraOptions)\n }\n\n toVmFile(file: string): string {\n return file\n }\n\n readonly powershellCommand = new Lazy(() => {\n return this.exec(\"powershell.exe\", [\"-NoProfile\", \"-NonInteractive\", \"-Command\", `Get-Command pwsh.exe`])\n .then(() => {\n log.info(null, \"identified pwsh.exe\")\n return \"pwsh.exe\"\n })\n .catch(() => {\n log.info(null, \"unable to find pwsh.exe, falling back to powershell.exe\")\n return \"powershell.exe\"\n })\n })\n}\n\nexport async function getWindowsVm(debugLogger: DebugLogger): Promise<VmManager> {\n const parallelsVmModule = await import(\"./ParallelsVm\")\n let vmList: ParallelsVm[] = []\n try {\n vmList = (await parallelsVmModule.parseVmList(debugLogger)).filter(it => [\"win-10\", \"win-11\"].includes(it.os))\n } catch (_error) {\n if ((await isPwshAvailable.value) && (await isWineAvailable.value)) {\n const vmModule = await import(\"./PwshVm\")\n return new vmModule.PwshVmManager()\n }\n }\n if (vmList.length === 0) {\n throw new InvalidConfigurationError(\"Cannot find suitable Parallels Desktop virtual machine (Windows 10 is required) and cannot access `pwsh` and `wine` locally\")\n }\n\n // prefer running or suspended vm\n return new parallelsVmModule.ParallelsVmManager(vmList.find(it => it.state === \"running\") || vmList.find(it => it.state === \"suspended\") || vmList[0])\n}\n\nconst isWineAvailable = new Lazy(async () => {\n return isCommandAvailable(\"wine\", [\"--version\"])\n})\n\nexport const isPwshAvailable = new Lazy(async () => {\n return isCommandAvailable(\"pwsh\", [\"--version\"])\n})\n\nexport const isCommandAvailable = async (command: string, args: string[]) => {\n try {\n await exec(command, args)\n return true\n } catch {\n return false\n }\n}\n"]}
|
||||
Reference in New Issue
Block a user