Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
deno: [1.0.5, 1.1.3, 1.2.2]
deno: [1.0.5, 1.1.3, 1.2.2, 1.3.0]
steps:
- uses: actions/checkout@v2
with:
Expand Down
2 changes: 1 addition & 1 deletion .vscode/denox.code-workspace
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
}
],
"settings": {
"deno.enabled": true
"deno.enable": true
}
}
2 changes: 1 addition & 1 deletion denox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ cli.on("command:*", () => {

cli.example("denox run start");

cli.help(() => ({}));
cli.help();

cli.version(CURRENT_VERSION);

Expand Down
12 changes: 7 additions & 5 deletions deps.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
export { parse as parseYaml } from "https://deno.land/std@0.42.0/encoding/yaml.ts";
export { YAMLError } from "https://deno.land/std@0.42.0/encoding/yaml/error.ts";
export { red } from "https://deno.land/std@0.50.0/fmt/colors.ts";
export { parse as parseYaml } from "https://deno.land/std@0.61.0/encoding/yaml.ts";
export { YAMLError } from "https://deno.land/std@0.61.0/encoding/_yaml/error.ts";
export { red } from "https://deno.land/std@0.61.0/fmt/colors.ts";
export { extname, resolve } from "https://deno.land/std@0.61.0/path/mod.ts";

// @deno-types="https://unpkg.com/cac@6.5.9/mod.d.ts"
export { cac } from "https://unpkg.com/cac@6.5.9/mod.js";
export { config as getDotEnvConfig, DotenvConfig } from "https://deno.land/x/dotenv@v0.5.0/mod.ts";

// @deno-types="https://unpkg.com/cac@6.6.1/mod.d.ts"
export { cac } from "https://unpkg.com/cac@6.6.1/mod.js";
4 changes: 2 additions & 2 deletions dev_deps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ export {
assertEquals,
assertArrayContains,
assertThrows,
assertStrContains,
assertStringContains,
assertThrowsAsync,
} from "https://deno.land/std@0.50.0/testing/asserts.ts";
} from "https://deno.land/std@0.60.0/testing/asserts.ts";

export { stripColor } from "https://deno.land/std@0.61.0/fmt/colors.ts";

Expand Down
4 changes: 2 additions & 2 deletions src/deno_options/parse.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { validateOptions } from "./validate.ts";
import { buildDenoCLIOptionsArgs, CLIArgument } from "./build_cli_arguments.ts";
import { WorkspaceGlobal, WorkspaceScript } from "../interfaces.ts";
import { WorkspaceGlobal, WorkspaceScriptFile } from "../interfaces.ts";

function parseDenoOptions(
workspaceGlobal: WorkspaceGlobal,
workspaceScript: WorkspaceScript,
workspaceScript: WorkspaceScriptFile,
): CLIArgument[] {
const denoGlobalOptions = workspaceGlobal?.deno_options;
const denoScriptOptions = workspaceScript?.deno_options;
Expand Down
20 changes: 20 additions & 0 deletions src/env/build_deno_env.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { WorkspaceEnv } from "../interfaces.ts";
import { getDotEnvConfig, resolve, DotenvConfig } from "../../deps.ts";

function buildDenoEnv(
workspaceScript: WorkspaceEnv,
workspaceGlobal: WorkspaceEnv,
): DotenvConfig {
let env = Deno.env.toObject();
const envFilePath = workspaceScript.env_file || workspaceGlobal.env_file;

if (envFilePath) {
env = { ...env, ...getDotEnvConfig({ path: resolve(envFilePath) }) };
}

env = { ...env, ...workspaceGlobal.env_vars, ...workspaceScript.env_vars };

return env;
}

export { buildDenoEnv };
15 changes: 15 additions & 0 deletions src/env/parse.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { DotenvConfig } from "../../deps.ts";

function replaceCommandEnvVars(command: string, env: DotenvConfig): string {
const envKeys: string[] = Object.keys(env);
let parsedCommand = command;

envKeys.forEach((envKey: string) => {
const envValue: string = env[envKey];
parsedCommand = parsedCommand.replace(`$${envKey}`, envValue);
});

return parsedCommand;
}

export { replaceCommandEnvVars };
26 changes: 22 additions & 4 deletions src/interfaces.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,33 @@
import { DotenvConfig } from "../deps.ts";

type DenoOptionValue = unknown;

type DenoOptionsEntries = {
[key: string]: DenoOptionValue;
};

type WorkspaceOptions = {
interface WorkspaceEnv {
env_file?: string;
env_vars?: DotenvConfig;
}

interface WorkspaceOptions {
deno_options?: DenoOptionsEntries;
};
}

type WorkspaceScript = {
type WorkspaceScriptFile = {
file: string;
} & WorkspaceOptions;

type WorkspaceGlobal = WorkspaceOptions;
interface WorkspaceScriptCommand {
command: string;
}

type WorkspaceScript =
& (WorkspaceScriptFile | WorkspaceScriptCommand)
& WorkspaceEnv;

type WorkspaceGlobal = WorkspaceOptions & WorkspaceEnv;

type DenoWorkspace = {
scripts: {
Expand All @@ -26,6 +41,9 @@ export {
WorkspaceGlobal,
WorkspaceScript,
WorkspaceOptions,
WorkspaceEnv,
WorkspaceScriptFile,
WorkspaceScriptCommand,
DenoOptionsEntries,
DenoOptionValue,
};
112 changes: 96 additions & 16 deletions src/run.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,31 @@
import { CURRENT_VERSION, GITHUB_REPO_NAME } from "./const.ts";

import * as consolex from "./utils/consolex.ts";
import { ScriptNotFoundError } from "./utils/DenoXErrors.ts";
import {
ScriptNotFoundError,
WorkspaceMissingFileOrCommand,
WorkspaceFileAndCommandSpecified,
} from "./utils/DenoXErrors.ts";

import { upgradeVersionMessage } from "./lib/upgrade_version.ts";

import { loadDenoWorkspace } from "./parser/deno_workspace.ts";
import { parseDenoOptions } from "./deno_options/parse.ts";
import { CLIArgument } from "./deno_options/build_cli_arguments.ts";
import { WorkspaceOptions, WorkspaceScript } from "./interfaces.ts";
import {
WorkspaceOptions,
WorkspaceScript,
WorkspaceScriptFile,
WorkspaceScriptCommand,
WorkspaceEnv,
} from "./interfaces.ts";
import { DotenvConfig } from "../deps.ts";
import { buildDenoEnv } from "./env/build_deno_env.ts";
import { replaceCommandEnvVars } from "./env/parse.ts";

async function run(scriptName: string): Promise<void> {
try {
const args = Deno.args.slice(2);
const { code } = await _runScript(scriptName, args);
const { code } = await _runScript(scriptName);

await upgradeVersionMessage(CURRENT_VERSION, GITHUB_REPO_NAME);

Expand All @@ -32,7 +44,6 @@ async function run(scriptName: string): Promise<void> {

async function _runScript(
scriptName: string,
args: string[],
): Promise<{ code: number }> {
const workspace = await loadDenoWorkspace();

Expand All @@ -43,15 +54,51 @@ async function _runScript(
throw new ScriptNotFoundError(scriptName);
}

return await _runDenoFile(workspaceScript, workspaceGlobal, args);
const env = _getDenoEnv(workspaceScript, workspaceGlobal);
const args = Deno.args.slice(2);

return await _runDenoFileOrCommand(
{ scriptName, workspaceScript, workspaceGlobal, args, env },
);
}

async function _runDenoFile(
workspaceScript: WorkspaceScript,
workspaceGlobal: WorkspaceOptions,
args: string[],
type DenoRunParams = {
scriptName: string;
workspaceScript: WorkspaceScript;
workspaceGlobal: WorkspaceOptions;
args: string[];
env: DotenvConfig;
};

async function _runDenoFileOrCommand(
{ scriptName, workspaceScript, workspaceGlobal, args, env }: DenoRunParams,
): Promise<{ code: number }> {
const denoOptions = await _getDenoOptions(workspaceScript, workspaceGlobal);
const workspaceCommand = (workspaceScript as WorkspaceScriptCommand);
const workspaceFile = (workspaceScript as WorkspaceScriptFile);
if (workspaceFile.file && workspaceCommand.command) {
throw new WorkspaceFileAndCommandSpecified(scriptName);
} else if (typeof workspaceFile.file !== undefined) {
return await _runDenoFile({ workspaceFile, workspaceGlobal, args, env });
} else if (typeof workspaceCommand.command !== undefined) {
return await _runCommand({ workspaceScript: workspaceCommand, args, env });
}
throw new WorkspaceMissingFileOrCommand(scriptName);
}

type DenoRunFileParams = {
workspaceFile: WorkspaceScriptFile;
workspaceGlobal: WorkspaceOptions;
args: string[];
env: DotenvConfig;
};

async function _runDenoFile({
workspaceFile,
workspaceGlobal,
args,
env,
}: DenoRunFileParams): Promise<{ code: number }> {
const denoOptions = _getDenoOptions(workspaceFile, workspaceGlobal);
const process = Deno.run({
// ToDO: remove '@ts-ignore' (and eslint directive) when vscode_deno is fixed to work with @deno_types; ref: <https://github.com/cacjs/cac/issues/75> , <https://github.com/denoland/vscode_deno/issues/21>
/* eslint @typescript-eslint/ban-ts-comment: "off" */
Expand All @@ -61,22 +108,55 @@ async function _runDenoFile(
"deno",
"run",
...denoOptions,
workspaceScript.file,
workspaceFile.file,
...args,
],
env: env,
});
const { code } = await process.status();
return { code };
}

type DenoRunCommandParams = {
workspaceScript: WorkspaceScriptCommand;
args: string[];
env: DotenvConfig;
};

async function _runCommand({
workspaceScript,
args,
env,
}: DenoRunCommandParams): Promise<{ code: number }> {
const commandWithEnvVars = replaceCommandEnvVars(workspaceScript.command, env)
const process = Deno.run({
cmd: [
commandWithEnvVars,
...args,
],
env: env,
});
const { code } = await process.status();
return { code };
}

async function _getDenoOptions(
workspaceScript: WorkspaceScript,
function _getDenoEnv(
workspaceScript: WorkspaceEnv,
workspaceGlobal: WorkspaceEnv,
): DotenvConfig {
return buildDenoEnv(
workspaceScript,
workspaceGlobal,
);
}

function _getDenoOptions(
workspaceFile: WorkspaceScriptFile,
workspaceGlobal: WorkspaceOptions,
): Promise<CLIArgument[]> {
): CLIArgument[] {
return parseDenoOptions(
workspaceGlobal,
workspaceScript,
workspaceFile,
);
}

Expand Down
18 changes: 18 additions & 0 deletions src/utils/DenoXErrors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,22 @@ class WorkspaceFileIsMalformed extends DenoXError {
}
}

class WorkspaceMissingFileOrCommand extends DenoXError {
constructor(scriptName: string) {
super(`
Script "${scriptName}" have no file or command specified please add one.
`);
}
}

class WorkspaceFileAndCommandSpecified extends DenoXError {
constructor(scriptName: string) {
super(`
Script "${scriptName}" have a file and a command specified please remove one.
`);
}
}

class DenoOptionNotRecognized extends DenoXError {
constructor(option: string) {
super(`
Expand All @@ -58,6 +74,8 @@ export {
ScriptNotFoundError,
WorkspaceNotFoundError,
WorkspaceFileIsMalformed,
WorkspaceFileAndCommandSpecified,
WorkspaceMissingFileOrCommand,
DenoOptionNotRecognized,
DenoOptionIncorrectType,
};
4 changes: 2 additions & 2 deletions src/utils/__tests__/file.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {
assertEquals,
assertThrowsAsync,
resolve,
assertStrContains,
assertStringContains,
} from "../../../dev_deps.ts";
import { getFileContent, getFirstExistingPath, exists } from "../file.ts";

Expand All @@ -11,7 +11,7 @@ Deno.test("read file", async () => {
"./src/utils/__tests__/fixture/file.txt",
);

assertStrContains(
assertStringContains(
fileContent,
"test file content",
);
Expand Down
Loading