mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-19 00:02:03 +00:00
feat(cli): allow all sync options to be passable from wmill.yaml directly
This commit is contained in:
+23
-4
@@ -1,17 +1,36 @@
|
||||
import { yamlParse } from "./deps.ts";
|
||||
|
||||
export interface WmillConfiguration {
|
||||
export interface SyncOptions {
|
||||
stateful?: boolean;
|
||||
raw?: boolean;
|
||||
yes?: boolean;
|
||||
skipPull?: boolean;
|
||||
failConflicts?: boolean;
|
||||
plainSecrets?: boolean;
|
||||
json?: boolean;
|
||||
skipVariables?: boolean;
|
||||
skipResources?: boolean;
|
||||
skipSecrets?: boolean;
|
||||
includeSchedules?: boolean;
|
||||
message?: string;
|
||||
includes?: string[];
|
||||
extraIncludes?: string[];
|
||||
excludes?: string[];
|
||||
}
|
||||
export async function readConfigFile(): Promise<WmillConfiguration> {
|
||||
|
||||
export async function readConfigFile(): Promise<SyncOptions> {
|
||||
try {
|
||||
const conf = yamlParse(
|
||||
await Deno.readTextFile("wmill.yaml")
|
||||
) as WmillConfiguration;
|
||||
) as SyncOptions;
|
||||
|
||||
return typeof conf == "object" ? conf : ({} as WmillConfiguration);
|
||||
return typeof conf == "object" ? conf : ({} as SyncOptions);
|
||||
} catch (e) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
export async function mergeConfigWithConfigFile<T>(opts: T): Promise<T> {
|
||||
const configFile = await readConfigFile();
|
||||
return Object.assign(configFile, opts);
|
||||
}
|
||||
|
||||
@@ -101,6 +101,7 @@ export async function fetchVersion(baseUrl: string): Promise<string> {
|
||||
const extraHeaders = getHeaders();
|
||||
if (extraHeaders) {
|
||||
for (const [key, value] of Object.entries(extraHeaders)) {
|
||||
// @ts-ignore
|
||||
requestHeaders.set(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
+9
-9
@@ -3,18 +3,18 @@ export { setClient } from "https://deno.land/x/windmill@v1.226.1/mod.ts";
|
||||
export * from "https://deno.land/x/windmill@v1.226.1/windmill-api/index.ts";
|
||||
export { SEP } from "https://deno.land/std@0.201.0/path/separator.ts";
|
||||
// cliffy
|
||||
export { Command } from "https://deno.land/x/cliffy@v1.0.0-rc.2/command/mod.ts";
|
||||
export { Table } from "https://deno.land/x/cliffy@v1.0.0-rc.2/table/table.ts";
|
||||
export { colors } from "https://deno.land/x/cliffy@v1.0.0-rc.2/ansi/colors.ts";
|
||||
export { Secret } from "https://deno.land/x/cliffy@v1.0.0-rc.2/prompt/secret.ts";
|
||||
export { Select } from "https://deno.land/x/cliffy@v1.0.0-rc.2/prompt/select.ts";
|
||||
export { Confirm } from "https://deno.land/x/cliffy@v1.0.0-rc.2/prompt/confirm.ts";
|
||||
export { Input } from "https://deno.land/x/cliffy@v1.0.0-rc.2/prompt/input.ts";
|
||||
export { Command } from "https://deno.land/x/cliffy@v1.0.0-rc.3/command/mod.ts";
|
||||
export { Table } from "https://deno.land/x/cliffy@v1.0.0-rc.3/table/table.ts";
|
||||
export { colors } from "https://deno.land/x/cliffy@v1.0.0-rc.3/ansi/colors.ts";
|
||||
export { Secret } from "https://deno.land/x/cliffy@v1.0.0-rc.3/prompt/secret.ts";
|
||||
export { Select } from "https://deno.land/x/cliffy@v1.0.0-rc.3/prompt/select.ts";
|
||||
export { Confirm } from "https://deno.land/x/cliffy@v1.0.0-rc.3/prompt/confirm.ts";
|
||||
export { Input } from "https://deno.land/x/cliffy@v1.0.0-rc.3/prompt/input.ts";
|
||||
export {
|
||||
DenoLandProvider,
|
||||
UpgradeCommand,
|
||||
} from "https://deno.land/x/cliffy@v1.0.0-rc.2/command/upgrade/mod.ts";
|
||||
export { CompletionsCommand } from "https://deno.land/x/cliffy@v1.0.0-rc.2/command/completions/mod.ts";
|
||||
} from "https://deno.land/x/cliffy@v1.0.0-rc.3/command/upgrade/mod.ts";
|
||||
export { CompletionsCommand } from "https://deno.land/x/cliffy@v1.0.0-rc.3/command/completions/mod.ts";
|
||||
// std
|
||||
export * as path from "https://deno.land/std@0.184.0/path/mod.ts";
|
||||
export { ensureDir } from "https://deno.land/std@0.184.0/fs/ensure_dir.ts";
|
||||
|
||||
+6
-4
@@ -3,18 +3,20 @@ import { Application, Command, Router, log, open, path } from "./deps.ts";
|
||||
import { GlobalOptions } from "./types.ts";
|
||||
import { ignoreF } from "./sync.ts";
|
||||
import { requireLogin, resolveWorkspace } from "./context.ts";
|
||||
import { SyncOptions, mergeConfigWithConfigFile } from "./conf.ts";
|
||||
|
||||
const PORT = 3001;
|
||||
async function dev(opts: GlobalOptions & { filter?: string }) {
|
||||
async function dev(opts: GlobalOptions & SyncOptions) {
|
||||
const workspace = await resolveWorkspace(opts);
|
||||
await requireLogin(opts);
|
||||
|
||||
log.info("Started dev mode");
|
||||
let currentLastEdit: LastEdit | undefined = undefined;
|
||||
|
||||
const watcher = Deno.watchFs(opts.filter ?? ".");
|
||||
const watcher = Deno.watchFs(".");
|
||||
const base = await Deno.realPath(".");
|
||||
const ignore = await ignoreF();
|
||||
opts = await mergeConfigWithConfigFile(opts);
|
||||
const ignore = await ignoreF(opts);
|
||||
|
||||
async function watchChanges() {
|
||||
for await (const event of watcher) {
|
||||
@@ -159,7 +161,7 @@ async function dev(opts: GlobalOptions & { filter?: string }) {
|
||||
const command = new Command()
|
||||
.description("Launch a dev server that will spawn a webserver with HMR")
|
||||
.option(
|
||||
"--filter <filter:string>",
|
||||
"--includes <pattern...:string>",
|
||||
"Filter paths givena glob pattern or path"
|
||||
)
|
||||
// deno-lint-ignore no-explicit-any
|
||||
|
||||
+32
-42
@@ -37,8 +37,7 @@ import { handleScriptMetadata, removeExtensionToPath } from "./script.ts";
|
||||
|
||||
import { handleFile } from "./script.ts";
|
||||
import { deepEqual } from "./utils.ts";
|
||||
import { read } from "https://deno.land/x/cbor@v1.4.1/decode.js";
|
||||
import { readConfigFile } from "./conf.ts";
|
||||
import { SyncOptions, mergeConfigWithConfigFile } from "./conf.ts";
|
||||
|
||||
type DynFSElement = {
|
||||
isDirectory: boolean;
|
||||
@@ -442,11 +441,10 @@ export const isWhitelisted = (p: string) => {
|
||||
return p == "." + SEP || p == "" || p == "u" || p == "f" || p == "g";
|
||||
};
|
||||
|
||||
export async function ignoreF(): Promise<
|
||||
(p: string, isDirectory: boolean) => boolean
|
||||
> {
|
||||
const wmillconf = await readConfigFile();
|
||||
|
||||
export async function ignoreF(wmillconf: {
|
||||
includes?: string[];
|
||||
excludes?: string[];
|
||||
}): Promise<(p: string, isDirectory: boolean) => boolean> {
|
||||
let whitelist: { approve(file: string): boolean } | undefined = undefined;
|
||||
|
||||
if (wmillconf?.includes || wmillconf?.excludes) {
|
||||
@@ -502,19 +500,9 @@ export async function ignoreF(): Promise<
|
||||
};
|
||||
}
|
||||
|
||||
async function pull(
|
||||
opts: GlobalOptions & {
|
||||
stateful: boolean;
|
||||
yes: boolean;
|
||||
failConflicts: boolean;
|
||||
plainSecrets?: boolean;
|
||||
json?: boolean;
|
||||
skipVariables?: boolean;
|
||||
skipResources?: boolean;
|
||||
skipSecrets?: boolean;
|
||||
includeSchedules?: boolean;
|
||||
}
|
||||
) {
|
||||
async function pull(opts: GlobalOptions & SyncOptions) {
|
||||
opts = await mergeConfigWithConfigFile(opts);
|
||||
|
||||
if (opts.stateful) {
|
||||
await ensureDir(path.join(Deno.cwd(), ".wmill"));
|
||||
}
|
||||
@@ -544,7 +532,7 @@ async function pull(
|
||||
const changes = await compareDynFSElement(
|
||||
remote,
|
||||
local,
|
||||
await ignoreF(),
|
||||
await ignoreF(opts),
|
||||
opts.json ?? false,
|
||||
opts,
|
||||
false
|
||||
@@ -713,22 +701,8 @@ function removeSuffix(str: string, suffix: string) {
|
||||
return str.slice(0, str.length - suffix.length);
|
||||
}
|
||||
|
||||
async function push(
|
||||
opts: GlobalOptions & {
|
||||
stateful: boolean;
|
||||
raw: boolean;
|
||||
yes: boolean;
|
||||
skipPull: boolean;
|
||||
failConflicts: boolean;
|
||||
plainSecrets?: boolean;
|
||||
json?: boolean;
|
||||
skipVariables?: boolean;
|
||||
skipResources?: boolean;
|
||||
skipSecrets?: boolean;
|
||||
includeSchedules?: boolean;
|
||||
message?: string;
|
||||
}
|
||||
) {
|
||||
async function push(opts: GlobalOptions & SyncOptions) {
|
||||
opts = await mergeConfigWithConfigFile(opts);
|
||||
if (opts.raw) {
|
||||
log.info("--raw is now the default, you can remove it as a flag");
|
||||
}
|
||||
@@ -767,7 +741,7 @@ async function push(
|
||||
const changes = await compareDynFSElement(
|
||||
local,
|
||||
remote,
|
||||
await ignoreF(),
|
||||
await ignoreF(opts),
|
||||
opts.json ?? false,
|
||||
opts,
|
||||
true
|
||||
@@ -990,12 +964,12 @@ const command = new Command()
|
||||
)
|
||||
.option(
|
||||
"--raw",
|
||||
"Push without using state, just overwrite. (Will be removed as a flag and made the default behavior in the future)"
|
||||
"Push without using state, just overwrite. (Default, has no effect)"
|
||||
)
|
||||
.option("--yes", "Pull without needing confirmation")
|
||||
.option(
|
||||
"--stateful",
|
||||
"Pull using state tracking (create .wmill folder and needed for --fail-conflicts). Default currently but will change in favor of --raw"
|
||||
"Pull using state tracking (create .wmill folder and needed for --fail-conflicts)"
|
||||
)
|
||||
.option("--plain-secrets", "Pull secrets as plain text")
|
||||
.option("--json", "Use JSON instead of YAML")
|
||||
@@ -1003,6 +977,14 @@ const command = new Command()
|
||||
.option("--skip-secrets", "Skip syncing only secrets variables")
|
||||
.option("--skip-resources", "Skip syncing resources")
|
||||
.option("--include-schedules", "Include syncing schedules")
|
||||
.option(
|
||||
"-i --includes <patterns...:file>",
|
||||
"Patterns to specify which file to take into account (among files that are compatible with windmill). Patterns can include * (any string until '/') and ** (any string)"
|
||||
)
|
||||
.option(
|
||||
"-e --excludes <patterns...:file>",
|
||||
"Patterns to specify which file to NOT take into account."
|
||||
)
|
||||
// deno-lint-ignore no-explicit-any
|
||||
.action(pull as any)
|
||||
.command("push")
|
||||
@@ -1015,11 +997,11 @@ const command = new Command()
|
||||
)
|
||||
.option(
|
||||
"--raw",
|
||||
"Push without using state, just overwrite. (Will be removed as a flag and made the default behavior in the future)"
|
||||
"Push without using state, just overwrite. (Default, has no effect)"
|
||||
)
|
||||
.option(
|
||||
"--stateful",
|
||||
"Pull using state tracking (use .wmill folder and needed for --fail-conflicts). Default currently but will change in favor of --raw"
|
||||
"Pull using state tracking (use .wmill folder and needed for --fail-conflicts)w"
|
||||
)
|
||||
.option("--skip-pull", "(stateful only) Push without pulling first")
|
||||
.option("--yes", "Push without needing confirmation")
|
||||
@@ -1029,6 +1011,14 @@ const command = new Command()
|
||||
.option("--skip-secrets", "Skip syncing only secrets variables")
|
||||
.option("--skip-resources", "Skip syncing resources")
|
||||
.option("--include-schedules", "Include syncing schedules")
|
||||
.option(
|
||||
"-i --includes <patterns...:file>",
|
||||
"Patterns to specify which file to take into account (among files that are compatible with windmill). Patterns can include * (any string until '/') and ** (any string)"
|
||||
)
|
||||
.option(
|
||||
"-e --excludes <patterns...:file>",
|
||||
"Patterns to specify which file to NOT take into account."
|
||||
)
|
||||
.option(
|
||||
"--message <message:string>",
|
||||
"Include a message that will be added to all scripts/flows/apps updated during this push"
|
||||
|
||||
Reference in New Issue
Block a user