feat: workspace dependencies (#7124)

* commit raw requirements

Signed-off-by: pyranota <pyra@duck.com>

* raw requirements

Signed-off-by: pyranota <pyra@duck.com>

* implement `parse_annotation`

Signed-off-by: pyranota <pyra@duck.com>

* more progress on wdeps

Signed-off-by: pyranota <pyra@duck.com>

* more progress

Signed-off-by: pyranota <pyra@duck.com>

* fixes

Signed-off-by: pyranota <pyra@duck.com>

* more progress

Signed-off-by: pyranota <pyra@duck.com>

* fixes

Signed-off-by: pyranota <pyra@duck.com>

* cli improvements + raw deps

Signed-off-by: pyranota <pyra@duck.com>

* cleanup

Signed-off-by: pyranota <pyra@duck.com>

* fix python versions

Signed-off-by: pyranota <pyra@duck.com>

* progress

Signed-off-by: pyranota <pyra@duck.com>

* update :)

Signed-off-by: pyranota <pyra@duck.com>

* add MaybeLock

Signed-off-by: pyranota <pyra@duck.com>

* go WIP

Signed-off-by: pyranota <pyra@duck.com>

* fix python ignoring py version from requirements

Signed-off-by: pyranota <pyra@duck.com>

* optimize php

Signed-off-by: pyranota <pyra@duck.com>

* require admin to alter

Signed-off-by: pyranota <pyra@duck.com>

* fix(cli): flow generateLocks raw deps

Signed-off-by: pyranota <pyra@duck.com>

* progress in checklist

Signed-off-by: pyranota <pyra@duck.com>

* fix agent workers

Signed-off-by: pyranota <pyra@duck.com>

* nits

Signed-off-by: pyranota <pyra@duck.com>

* nits

Signed-off-by: pyranota <pyra@duck.com>

* nit: remove default features

Signed-off-by: pyranota <pyra@duck.com>

* oh-wow

Signed-off-by: pyranota <pyra@duck.com>

* remove dbg!

Signed-off-by: pyranota <pyra@duck.com>

* nits

Signed-off-by: pyranota <pyra@duck.com>

* add indexes

Signed-off-by: pyranota <pyra@duck.com>

* cleanup

Signed-off-by: pyranota <pyra@duck.com>

* nits

Signed-off-by: pyranota <pyra@duck.com>

* remove todos

Signed-off-by: pyranota <pyra@duck.com>

* fix cli

Signed-off-by: pyranota <pyra@duck.com>

* add debug flag

Signed-off-by: pyranota <pyra@duck.com>

* cli: remove noise

Signed-off-by: pyranota <pyra@duck.com>

* fix cli

Signed-off-by: pyranota <pyra@duck.com>

* remove todos

Signed-off-by: pyranota <pyra@duck.com>

* trigger deps correctly

Signed-off-by: pyranota <pyra@duck.com>

* fix frontend

Signed-off-by: pyranota <pyra@duck.com>

* fix frontend again

Signed-off-by: pyranota <pyra@duck.com>

* finally fix frontend

Signed-off-by: pyranota <pyra@duck.com>

* ee repo ref

Signed-off-by: pyranota <pyra@duck.com>

* fix all

Signed-off-by: pyranota <pyra@duck.com>

* more fixes...

Signed-off-by: pyranota <pyra@duck.com>

* remove test

Signed-off-by: pyranota <pyra@duck.com>

* Update backend-test.yml

* comment out legacy test

Signed-off-by: pyranota <pyra@duck.com>

* fix ci

Signed-off-by: pyranota <pyra@duck.com>

* fix ci?

Signed-off-by: pyranota <pyra@duck.com>

* comment out thing

Signed-off-by: pyranota <pyra@duck.com>

* ignore test

Signed-off-by: pyranota <pyra@duck.com>

* ci

Signed-off-by: pyranota <pyra@duck.com>

* base fixture

Signed-off-by: pyranota <pyra@duck.com>

* fix regression

Signed-off-by: pyranota <pyra@duck.com>

* fix docs links

Signed-off-by: pyranota <pyra@duck.com>

* update min version

Signed-off-by: pyranota <pyra@duck.com>

* simplify

* implement cache for get_latest

Signed-off-by: pyranota <pyra@duck.com>

* move to workspace settings

Signed-off-by: pyranota <pyra@duck.com>

* sqlx + migration

Signed-off-by: pyranota <pyra@duck.com>

* more migrations

Signed-off-by: pyranota <pyra@duck.com>

* use box pin

Signed-off-by: pyranota <pyra@duck.com>

* nit

Signed-off-by: pyranota <pyra@duck.com>

---------

Signed-off-by: pyranota <pyra@duck.com>
Co-authored-by: Ruben Fiszel <ruben@windmill.dev>
This commit is contained in:
Pyra
2025-11-28 17:00:11 +01:00
committed by GitHub
parent e26b5c94a3
commit d38c96db36
94 changed files with 6919 additions and 1944 deletions

View File

@@ -26,13 +26,14 @@ import {
import { Workspace } from "../workspace/workspace.ts";
import {
generateScriptMetadataInternal,
getRawWorkspaceDependencies,
parseMetadataFile,
} from "../../utils/metadata.ts";
import {
LanguageWithRawReqsSupport,
WorkspaceDependenciesLanguage,
ScriptLanguage,
inferContentTypeFromFilePath,
languagesWithRawReqsSupport,
workspaceDependenciesLanguages,
} from "../../utils/script_common.ts";
import {
elementsToMap,
@@ -88,14 +89,13 @@ async function push(opts: PushOptions, filePath: string) {
await requireLogin(opts);
const codebases = await listSyncCodebases(opts as SyncOptions);
const globalDeps = await findGlobalDeps();
await handleFile(
filePath,
workspace,
[],
undefined,
opts,
globalDeps,
await getRawWorkspaceDependencies(),
codebases
);
log.info(colors.bold.underline.green(`Script ${filePath} pushed`));
@@ -156,7 +156,7 @@ export async function handleScriptMetadata(
workspace: Workspace,
alreadySynced: string[],
message: string | undefined,
globalDeps: GlobalDeps,
rawWorkspaceDependencies: Record<string, string>,
codebases: SyncCodebase[],
opts: GlobalOptions
): Promise<boolean> {
@@ -172,7 +172,7 @@ export async function handleScriptMetadata(
alreadySynced,
message,
opts,
globalDeps,
rawWorkspaceDependencies,
codebases
);
} else {
@@ -194,7 +194,7 @@ export async function handleFile(
alreadySynced: string[],
message: string | undefined,
opts: (GlobalOptions & { defaultTs?: "bun" | "deno" } & Skips) | undefined,
globalDeps: GlobalDeps,
rawWorkspaceDependencies: Record<string, string>,
codebases: SyncCodebase[]
): Promise<boolean> {
if (
@@ -326,7 +326,7 @@ export async function handleFile(
path,
workspaceRemote: workspace,
schemaOnly: codebase ? true : undefined,
globalDeps,
rawWorkspaceDependencies,
codebases,
}
: undefined
@@ -943,39 +943,10 @@ async function bootstrap(
}
export type GlobalDeps = Map<
LanguageWithRawReqsSupport,
WorkspaceDependenciesLanguage,
Record<string, string>
>;
export async function findGlobalDeps(): Promise<GlobalDeps> {
var globalDeps: GlobalDeps = new Map();
const els = await FSFSElement(Deno.cwd(), [], false);
for await (const entry of readDirRecursiveWithIgnore((p, isDir) => {
p = SEP + p;
return (
!isDir &&
// Skip if the filename is not one of lockfile names
!languagesWithRawReqsSupport.some((lockfile) =>
p.endsWith(SEP + lockfile.rrFilename)
)
);
}, els)) {
if (entry.isDirectory || entry.ignored) continue;
const content = await entry.getContentText();
// Iterate over available languages to find which lockfile
languagesWithRawReqsSupport.map((lock) => {
if (entry.path.endsWith(lock.rrFilename)) {
const current = globalDeps.get(lock) ?? {};
current[
entry.path.substring(0, entry.path.length - lock.rrFilename.length)
] = content;
globalDeps.set(lock, current);
}
});
}
return globalDeps;
}
async function generateMetadata(
opts: GlobalOptions & {
lockOnly?: boolean;
@@ -999,7 +970,7 @@ async function generateMetadata(
opts = await mergeConfigWithConfigFile(opts);
const codebases = await listSyncCodebases(opts);
const globalDeps = await findGlobalDeps();
const rawWorkspaceDependencies = await getRawWorkspaceDependencies();
if (scriptPath) {
// read script metadata file
await generateScriptMetadataInternal(
@@ -1008,11 +979,12 @@ async function generateMetadata(
opts,
false,
false,
globalDeps,
rawWorkspaceDependencies,
codebases,
false
);
} else {
// TODO: test this as well.
const ignore = await ignoreF(opts);
const elems = await elementsToMap(
await FSFSElement(Deno.cwd(), codebases, false),
@@ -1036,7 +1008,7 @@ async function generateMetadata(
opts,
true,
true,
globalDeps,
rawWorkspaceDependencies,
codebases,
false
);
@@ -1063,6 +1035,7 @@ async function generateMetadata(
log.info(colors.green.bold("No metadata to update"));
return;
}
// TODO: test this
for (const e of Object.keys(elems)) {
await generateScriptMetadataInternal(
e,
@@ -1070,7 +1043,7 @@ async function generateMetadata(
opts,
false,
true,
globalDeps,
rawWorkspaceDependencies,
codebases,
false
);