mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-21 00:02:23 +00:00
a46aa641f9
* feat: add R language support Add R as a new supported scripting language in Windmill, following the same pattern used for Ruby. Includes: - Backend: ScriptLang::Rlang enum variant, DB migration, tree-sitter-r parser crate with tests, WASM parser binding, R executor with NSJail sandboxing, job dispatch and signature parsing - Frontend: language picker, R icon, syntax highlighting, editor bar insertions (Sys.getenv, get_variable, get_resource), schema inference, init code template, BETA badge - CLI: .r extension mapping, sync support, bootstrap template R scripts use `main <- function(...)` syntax, jsonlite for JSON serialization, and system curl for the Windmill client helper. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add R package resolution and installation Parse library()/require() calls from R scripts to extract dependencies. Resolve versions from CRAN, cache lockfiles in pip_resolution_cache, and install packages to a shared R library cache. The run step sets R_LIBS_USER so installed packages are available to the script. - Parser: parse_r_requirements() extracts package names from AST - Executor: resolve() generates lockfile, install() installs from CRAN - Worker lockfiles: wire up R resolve for dependency jobs Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add nsjail sandboxing for R resolve and install phases Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: fix R get_variable/get_resource and add sandbox annotation + e2e tests Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: fix R arg inference with JS fallback parser and get_variable/get_resource Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix flake * nsjail * nits * fix: R install improvements - suppress verbose output, flat lockfile logging, Dockerfile R support, rlimits - Suppress renv verbose output during resolve and install (controlled by #verbose annotation) - Filter renv from install list (already loaded, causes noisy restart message) - Log compact "resolved N packages" instead of full renv.lock JSON - Add R (r-base, r-cran-renv) to DockerfileFull and DockerfileFullEe - Use disable_rl for nsjail install config (R compiles from source) - Reduce default concurrency from 20 to 5 - Add rlang to openflow.openapi.yaml - Fix MainArgSignature (no_main_func -> auto_kind) after main merge Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * final * fix: remove accidental R install from multiplayer Dockerfile Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: remove R from Windows build and DockerfileExtra Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: rename R migration to avoid timestamp collision with trigger_filter_logic Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * all * fix: R install improvements - suppress verbose output, flat lockfile logging, Dockerfile R support, rlimits Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: add clear error when Rscript binary is missing Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: fix type errors in R fallback parser, use format! in wrap(), add R system prompts Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: pyranota <pyra@duck.com>
118 lines
3.4 KiB
TypeScript
118 lines
3.4 KiB
TypeScript
export type ScriptLanguage =
|
|
| "python3"
|
|
| "deno"
|
|
| "bun"
|
|
| "nativets"
|
|
| "go"
|
|
| "bash"
|
|
| "powershell"
|
|
| "postgresql"
|
|
| "mysql"
|
|
| "bigquery"
|
|
| "duckdb"
|
|
| "oracledb"
|
|
| "snowflake"
|
|
| "mssql"
|
|
| "graphql"
|
|
| "php"
|
|
| "rust"
|
|
| "csharp"
|
|
| "nu"
|
|
| "ansible"
|
|
| "ruby"
|
|
| "rlang"
|
|
| "java";
|
|
// for related places search: ADD_NEW_LANG
|
|
|
|
// To make language support raw requirements:
|
|
// 1. Add value here
|
|
// 2. Modify backend to allow raw deps
|
|
export type WorkspaceDependenciesLanguage =
|
|
| { language: "bun", filename /** (raw requirements filename) */: "package.json" }
|
|
| { language: "python3", filename: "requirements.in" }
|
|
| { language: "php", filename: "composer.json" }
|
|
| { language: "go", filename: "go.mod" }
|
|
| { language: "powershell", filename: "modules.json" };
|
|
|
|
export const workspaceDependenciesLanguages: WorkspaceDependenciesLanguage[] = [
|
|
{ language: "bun", filename: "package.json" },
|
|
{ language: "python3", filename: "requirements.in" },
|
|
{ language: "php", filename: "composer.json" },
|
|
{ language: "go", filename: "go.mod" },
|
|
{ language: "powershell", filename: "modules.json" },
|
|
] as const;
|
|
|
|
/**
|
|
* Returns true if a script in the given language requires a lock file.
|
|
* Matches the condition in updateScriptLock (metadata.ts).
|
|
*/
|
|
export function languageNeedsLock(language: ScriptLanguage | string): boolean {
|
|
return (
|
|
(workspaceDependenciesLanguages.some((l) => l.language === language) &&
|
|
language !== "powershell") ||
|
|
language === "deno" ||
|
|
language === "rust" ||
|
|
language === "ansible"
|
|
);
|
|
}
|
|
|
|
export function inferContentTypeFromFilePath(
|
|
contentPath: string,
|
|
defaultTs: "bun" | "deno" | undefined
|
|
): ScriptLanguage {
|
|
if (contentPath.endsWith(".py")) {
|
|
return "python3";
|
|
} else if (contentPath.endsWith("fetch.ts")) {
|
|
return "nativets";
|
|
} else if (contentPath.endsWith("bun.ts")) {
|
|
return "bun";
|
|
} else if (contentPath.endsWith("deno.ts")) {
|
|
return "deno";
|
|
} else if (contentPath.endsWith(".ts")) {
|
|
return defaultTs ?? "bun";
|
|
} else if (contentPath.endsWith(".go")) {
|
|
return "go";
|
|
} else if (contentPath.endsWith(".my.sql")) {
|
|
return "mysql";
|
|
} else if (contentPath.endsWith(".bq.sql")) {
|
|
return "bigquery";
|
|
} else if (contentPath.endsWith(".odb.sql")) {
|
|
return "oracledb";
|
|
} else if (contentPath.endsWith(".duckdb.sql")) {
|
|
return "duckdb";
|
|
} else if (contentPath.endsWith(".sf.sql")) {
|
|
return "snowflake";
|
|
} else if (contentPath.endsWith(".ms.sql")) {
|
|
return "mssql";
|
|
} else if (contentPath.endsWith(".pg.sql")) {
|
|
return "postgresql";
|
|
} else if (contentPath.endsWith(".gql")) {
|
|
return "graphql";
|
|
} else if (contentPath.endsWith(".sh")) {
|
|
return "bash";
|
|
} else if (contentPath.endsWith(".ps1")) {
|
|
return "powershell";
|
|
} else if (contentPath.endsWith(".php")) {
|
|
return "php";
|
|
} else if (contentPath.endsWith(".rs")) {
|
|
return "rust";
|
|
} else if (contentPath.endsWith(".cs")) {
|
|
return "csharp";
|
|
} else if (contentPath.endsWith(".playbook.yml")) {
|
|
return "ansible";
|
|
} else if (contentPath.endsWith(".nu")) {
|
|
return "nu";
|
|
} else if (contentPath.endsWith(".java")) {
|
|
return "java";
|
|
} else if (contentPath.endsWith(".rb")) {
|
|
return "ruby";
|
|
} else if (contentPath.endsWith(".r")) {
|
|
return "rlang";
|
|
// for related places search: ADD_NEW_LANG
|
|
} else {
|
|
throw new Error(
|
|
"Invalid language: " + contentPath.substring(contentPath.lastIndexOf("."))
|
|
);
|
|
}
|
|
}
|