From 82a45427465a56ae3d0faa33155aec4f59836828 Mon Sep 17 00:00:00 2001 From: "Timothy J. Aveni" Date: Tue, 22 Sep 2026 13:51:32 -0700 Subject: [PATCH] Build composable Camino packages with explicit type and source dependencies --- grammar/QuixosLock.g4 | 2 + nix/checked-candidate.nix | 69 ++++- src/bindings/index.ts | 15 +- src/capability-language/assembly.ts | 99 ++++--- src/capability-language/authoring-context.ts | 4 +- src/capability-language/authoring-inspect.ts | 2 +- src/capability-language/candidate-check.ts | 3 +- src/capability-language/checked-build.ts | 2 +- src/capability-language/execution-scaffold.ts | 2 +- src/capability-language/git-resolver.ts | 2 +- src/capability-language/pin-upgrades.ts | 24 +- src/capability-language/resource-cli.ts | 20 +- src/capability-language/structural-edits.ts | 6 +- src/capability-language/structural-plan.ts | 6 +- src/capability-language/tool-cli.ts | 74 ++++-- src/capability-language/workspace-cli.ts | 19 +- src/execution-world/client-contracts.ts | 14 +- src/execution-world/receipts.ts | 8 +- src/resource-lock/generated/QuixosLock.interp | 4 +- src/resource-lock/generated/QuixosLock.tokens | 58 +++-- .../generated/QuixosLockLexer.interp | 5 +- .../generated/QuixosLockLexer.tokens | 58 +++-- .../generated/QuixosLockLexer.ts | 241 +++++++++--------- .../generated/QuixosLockParser.ts | 89 ++++--- src/resource-lock/parser.ts | 6 +- src/resource-lock/types.ts | 2 +- test/artifact-files.test.ts | 19 ++ test/build-dependencies.test.ts | 76 ++++++ test/emit-managed.ts | 21 ++ test/pin-upgrades.test.ts | 206 +++++++-------- 30 files changed, 736 insertions(+), 420 deletions(-) create mode 100644 test/build-dependencies.test.ts diff --git a/grammar/QuixosLock.g4 b/grammar/QuixosLock.g4 index e8b41a1..ae2525e 100644 --- a/grammar/QuixosLock.g4 +++ b/grammar/QuixosLock.g4 @@ -20,6 +20,7 @@ importEntry resourceKind : INTERFACE | PACKAGE + | BUILD ; sourceBlock @@ -58,6 +59,7 @@ QUIXOS: 'quixos'; SOURCE: 'source'; INTERFACE: 'interface'; PACKAGE: 'package'; +BUILD: 'build'; REPOSITORY: 'repository'; COMMIT: 'commit'; POLICY: 'policy'; diff --git a/nix/checked-candidate.nix b/nix/checked-candidate.nix index fcb6fec..7e61b45 100644 --- a/nix/checked-candidate.nix +++ b/nix/checked-candidate.nix @@ -34,7 +34,8 @@ let ''; lock = builtins.fromJSON (builtins.readFile lockFile); children = map ( - entry: load (ancestors ++ [ (sourceKey source) ]) (entry.source // { inherit (entry) kind; }) + entry: + load (ancestors ++ [ (sourceKey source) ]) (entry.source // { inherit (entry) kind binding; }) ) lock.resources; in source // { inherit directory children lock; }; @@ -50,6 +51,12 @@ let ); runtimePackages = runtime.packages.${system}; flatten = node: [ node ] ++ pkgs.lib.concatMap flatten node.children; + capabilityFlatten = + node: + if node.kind == "build" then + [ ] + else + [ node ] ++ pkgs.lib.concatMap capabilityFlatten node.children; nodes = builtins.attrValues ( builtins.listToAttrs ( map (node: { @@ -94,6 +101,51 @@ let } ''; contract = compile root; + buildDependencies = + node: + builtins.listToAttrs ( + map (dependency: { + name = dependency.binding; + value = { + src = dependency.directory; + source = { inherit (dependency) repository commit; }; + flake = builtins.getFlake "git+${dependency.repository}?rev=${dependency.commit}&ref=refs/tags/quixos-reachability/${dependency.commit}"; + }; + }) (builtins.filter (dependency: dependency.kind == "build") node.children) + ); + reactContracts = + node: + let + interfaces = builtins.attrValues ( + builtins.listToAttrs ( + map (dependency: { + name = sourceKey dependency; + value = dependency; + }) (builtins.filter (dependency: dependency.kind == "interface") (capabilityFlatten node)) + ) + ); + in + pkgs.lib.concatMap ( + dependency: + if !builtins.pathExists (dependency.directory + "/flake.nix") then + [ ] + else + let + source = builtins.getFlake "git+${dependency.repository}?rev=${dependency.commit}&ref=refs/tags/quixos-reachability/${dependency.commit}"; + build = source.quixosInterfaces.${system}.reactTypes or null; + in + if build == null then + [ ] + else + [ + (build { + interface = "${compile dependency}/candidate.json"; + generator = protocol; + typescript = runtimePackages.camino-replica-core.dependencies; + dependencies = buildDependencies dependency; + }) + ] + ) interfaces; checkPackage = node: let @@ -126,11 +178,13 @@ let sharedRuntime = runtimePackages.camino-shared-runtime; typescript = runtimePackages.camino-replica-core.dependencies; packageRevisionId = candidate.revision.revisionId; + dependencies = buildDependencies node; } // pkgs.lib.optionalAttrs (componentEntries != [ ]) { react = { sdk = runtimePackages.camino-react; runtime = runtimePackages.camino-react-runtime; + contracts = reactContracts node; }; } else @@ -157,7 +211,18 @@ let if contractOnly then [ ] else - map checkPackage (builtins.filter (node: node.kind == "package") nodes); + map checkPackage ( + builtins.filter (node: node.kind == "package") ( + builtins.attrValues ( + builtins.listToAttrs ( + map (node: { + name = sourceKey node; + value = node; + }) (capabilityFlatten root) + ) + ) + ) + ); manifest = pkgs.writeText "qx-candidate-checks.json" (builtins.toJSON checks); bindingOptions = pkgs.writeText "qx-typescript-options.json" ( builtins.toJSON ( diff --git a/src/bindings/index.ts b/src/bindings/index.ts index 8290516..8afc11a 100644 --- a/src/bindings/index.ts +++ b/src/bindings/index.ts @@ -17,24 +17,29 @@ export type BindingSchema = { interfaceTemplates?: InterfaceRevision[]; packages: PackageRevision[]; }; -export const bindingSchema = (compiled: Pick): BindingSchema => ({ +export const bindingSchema = ( + compiled: Pick & + Partial>, +): BindingSchema => ({ format: "quixos-bindings", version: 1, - interfaceTemplates: compiled.resources.flatMap((node) => + interfaceTemplates: (compiled.capabilityResources ?? compiled.resources).flatMap((node) => node.resource.kind === "interface" && node.resource.revision.template ? [node.resource.revision] : [], ), interfaces: [ ...new Map( - compiled.resources + (compiled.capabilityResources ?? compiled.resources) .flatMap((node) => [ ...(node.resource.kind === "interface" ? [node.resource.revision] : []), - ...(node.resource.specializations ?? []), + ...(node.resource.kind === "build" ? [] : (node.resource.specializations ?? [])), ]) .filter((entry) => !entry.template) .map((entry) => [entry.revisionId, entry]), ).values(), ], - packages: compiled.resources.flatMap((node) => (node.resource.kind === "package" ? [node.resource.revision] : [])), + packages: (compiled.capabilityResources ?? compiled.resources).flatMap((node) => + node.resource.kind === "package" ? [node.resource.revision] : [], + ), }); export const specializeBindingSchema = ( diff --git a/src/capability-language/assembly.ts b/src/capability-language/assembly.ts index f55edab..748bcaf 100644 --- a/src/capability-language/assembly.ts +++ b/src/capability-language/assembly.ts @@ -47,7 +47,7 @@ export type ResolvedCapabilityResource = { source: GitSource; directory: string; lock: QuixosRepositoryLock; - resource: CapabilityResource; + resource: CapabilityResource | { kind: "build" }; dependencies: ReadonlyMap; }; @@ -56,13 +56,15 @@ export type CompiledWorkspaceRepository = { plan: CompiledWorkspaceRevision; lock: QuixosRepositoryLock; resources: ResolvedCapabilityResource[]; + capabilityResources: ResolvedCapabilityResource[]; directResources: ReadonlyMap; }; export type CompiledCapabilityResourceRepository = { - resource: CapabilityResource; + resource: CapabilityResource | { kind: "build" }; lock: QuixosRepositoryLock; resources: ResolvedCapabilityResource[]; + capabilityResources: ResolvedCapabilityResource[]; directResources: ReadonlyMap; }; @@ -79,7 +81,10 @@ const assertImportsMatchLock = ( resources: readonly LockedResource[], ) => { const authored = [...imports].map(importsKey).sort(); - const locked = [...resources].map(importsKey).sort(); + const locked = resources + .filter((entry) => entry.kind !== "build") + .map(importsKey) + .sort(); if (authored.length !== locked.length || authored.some((entry, index) => entry !== locked[index])) { throw new Error( `${label} imports do not match quixos.lock:\n` + @@ -137,13 +142,19 @@ const diagnosticsMessage = ( }) .join("\n")}`; -const revisionFor = (node: ResolvedCapabilityResource) => node.resource.revision; +const revisionFor = (node: ResolvedCapabilityResource) => { + if (node.resource.kind === "build") throw Error("Build sources have no capability revision"); + return node.resource.revision; +}; -const resourceClosure = (roots: readonly ResolvedCapabilityResource[]): ResolvedCapabilityResource[] => { +const resourceClosure = ( + roots: readonly ResolvedCapabilityResource[], + capabilityOnly = false, +): ResolvedCapabilityResource[] => { const result: ResolvedCapabilityResource[] = []; const seen = new Set(); const visit = (node: ResolvedCapabilityResource) => { - if (seen.has(node.key)) return; + if (seen.has(node.key) || (capabilityOnly && node.kind === "build")) return; seen.add(node.key); for (const dependency of node.dependencies.values()) visit(dependency); result.push(node); @@ -155,28 +166,36 @@ const resourceClosure = (roots: readonly ResolvedCapabilityResource[]): Resolved const environmentFor = ( direct: readonly [LockedResource, ResolvedCapabilityResource][], closure: readonly ResolvedCapabilityResource[], -): CapabilityImportEnvironment => ({ - interfaces: new Map( - direct.flatMap(([locked, node]) => - node.resource.kind === "interface" ? [[locked.binding, node.resource.revision] as const] : [], +): CapabilityImportEnvironment => { + closure = resourceClosure( + direct.map(([, node]) => node), + true, + ); + return { + interfaces: new Map( + direct.flatMap(([locked, node]) => + node.resource.kind === "interface" ? [[locked.binding, node.resource.revision] as const] : [], + ), ), - ), - packages: new Map( - direct.flatMap(([locked, node]) => - node.resource.kind === "package" ? [[locked.binding, node.resource.revision] as const] : [], + packages: new Map( + direct.flatMap(([locked, node]) => + node.resource.kind === "package" ? [[locked.binding, node.resource.revision] as const] : [], + ), ), - ), - interfaceClosure: exactRevisions( - closure.flatMap((node) => [ - ...(node.resource.kind === "interface" ? [node.resource.revision] : []), - ...(node.resource.specializations ?? []), - ]), - ), - packageClosure: exactRevisions( - closure.flatMap((node) => (node.resource.kind === "package" ? [node.resource.revision] : [])), - ), - externalAtoms: exactAtoms(closure.flatMap((node) => node.resource.externalAtoms)), -}); + interfaceClosure: exactRevisions( + closure.flatMap((node) => [ + ...(node.resource.kind === "interface" ? [node.resource.revision] : []), + ...(node.resource.kind === "build" ? [] : (node.resource.specializations ?? [])), + ]), + ), + packageClosure: exactRevisions( + closure.flatMap((node) => (node.resource.kind === "package" ? [node.resource.revision] : [])), + ), + externalAtoms: exactAtoms( + closure.flatMap((node) => (node.resource.kind === "build" ? [] : node.resource.externalAtoms)), + ), + }; +}; const createResourceGraphResolver = (quixosCommit: string, resolveResource: CapabilityRepositoryResolver) => { const resolved = new Map>(); @@ -218,6 +237,19 @@ const createResourceGraphResolver = (quixosCommit: string, resolveResource: Capa for (const dependency of lockResult.lock.resources) { directPairs.push([dependency, await visit(dependency)]); } + if (locked.kind === "build") { + return { + key, + kind: locked.kind, + source: locked.source, + directory: snapshot.directory, + lock: lockResult.lock, + resource: { kind: "build" as const }, + dependencies: new Map( + directPairs.map(([dependency, node]) => [bindingKey(dependency.kind, dependency.binding), node]), + ), + }; + } const dependencyClosure = resourceClosure(directPairs.map(([, node]) => node)); const environment = environmentFor(directPairs, dependencyClosure); const manifestName = locked.kind === "interface" ? "interface.qx" : "package.qx"; @@ -332,6 +364,7 @@ export const compileCapabilityResourceRepository = async (options: { resource: root.resource, lock: root.lock, resources: await resolver.nodes(), + capabilityResources: resourceClosure([root], true), directResources: root.dependencies, }; }; @@ -376,11 +409,13 @@ export const compileWorkspaceRepository = async (options: { ); } assertImportsMatchLock(workspacePath, compiled.imports, rootLock.resources); - const availableInterfaceIds = new Set( - nodes.flatMap((node) => (node.resource.kind === "interface" ? [node.resource.revision.revisionId] : [])), - ); + const availableInterfaceIds = new Set((environment.interfaceClosure ?? []).map((iface) => iface.revisionId)); const availableAtomIds = new Set(compiled.workspace.atoms.map((atom) => atom.id)); - for (const node of nodes) { + for (const node of resourceClosure( + directPairs.map(([, node]) => node), + true, + )) { + if (node.resource.kind === "build") continue; for (const requirement of node.resource.externalInterfaces) { if (!availableInterfaceIds.has(requirement.revisionId)) { throw new Error( @@ -430,6 +465,10 @@ export const compileWorkspaceRepository = async (options: { plan: checked.plan, lock: rootLock, resources: nodes, + capabilityResources: resourceClosure( + directPairs.map(([, node]) => node), + true, + ), directResources: new Map(directPairs.map(([locked, node]) => [bindingKey(locked.kind, locked.binding), node])), }; }; diff --git a/src/capability-language/authoring-context.ts b/src/capability-language/authoring-context.ts index f91a318..2402292 100644 --- a/src/capability-language/authoring-context.ts +++ b/src/capability-language/authoring-context.ts @@ -3,7 +3,7 @@ import path from "node:path"; import { loadQuixosLock, type GitSource } from "../resource-lock/index.js"; export type AuthoringResource = { - kind: "workspace" | "interface" | "package"; + kind: "workspace" | "interface" | "package" | "build"; directory: string; resourceId?: string; source?: GitSource; @@ -31,7 +31,7 @@ export async function authoringContext(start: string) { if (typeof entry.directory === "string" && path.isAbsolute(entry.directory)) entry.directory = path.relative(workbench, entry.directory); if ( - !["interface", "package"].includes(entry.kind) || + !["interface", "package", "build"].includes(entry.kind) || !entry.source || !/^resources\/[A-Za-z0-9][A-Za-z0-9._-]*$/.test(entry.directory) ) { diff --git a/src/capability-language/authoring-inspect.ts b/src/capability-language/authoring-inspect.ts index 54544f2..c81ae0b 100644 --- a/src/capability-language/authoring-inspect.ts +++ b/src/capability-language/authoring-inspect.ts @@ -69,7 +69,7 @@ export async function inspectAuthoringRepository(root: string, historyLimit = 10 declarations: syntax ? [...walkSyntax(syntax.root)] .filter((node) => - /^(?:interface|package|atom|state|edge|method|function|event|conformance|component|presentation)\w*Decl$/.test( + /^(?:(?:interface|package|atom|state|edge|method|function|event|conformance|presentation)\w*Decl|module(?:Member|Export))$/.test( node.kind, ), ) diff --git a/src/capability-language/candidate-check.ts b/src/capability-language/candidate-check.ts index 6a67de9..45c9ea2 100644 --- a/src/capability-language/candidate-check.ts +++ b/src/capability-language/candidate-check.ts @@ -209,7 +209,7 @@ export const checkWorkspaceCandidate = async (options: { : []; const evolution = planEvolution(baseline, compiled.workspace, { reviews }); blockers.push(...evolution.blockers); - for (const resource of compiled.resources.filter((entry) => entry.kind === "package")) { + for (const resource of compiled.capabilityResources.filter((entry) => entry.kind === "package")) { // Per-package recursive schema, identical to host activation, not unrelated // workspace declarations that would unnecessarily invalidate build caches. const candidate = await compileCapabilityResourceRepository({ @@ -218,6 +218,7 @@ export const checkWorkspaceCandidate = async (options: { source: resource.source, resolveResource, }); + if (candidate.resource.kind !== "package") throw Error("Expected checked package contract"); const schema = path.join(temporary, "bindings.json"); await fs.writeFile( schema, diff --git a/src/capability-language/checked-build.ts b/src/capability-language/checked-build.ts index d08b50a..ee04814 100644 --- a/src/capability-language/checked-build.ts +++ b/src/capability-language/checked-build.ts @@ -107,7 +107,7 @@ export async function buildCheckedPackage(source: string, schema: string, packag * nested fetches. Keep build noise in a named log, with a bounded failure tail. */ export async function buildImmutableCandidate( source: { repository: string; commit: string }, - kind: "workspace" | "interface" | "package", + kind: "workspace" | "interface" | "package" | "build", logFile: string, contractOnly = false, ): Promise { diff --git a/src/capability-language/execution-scaffold.ts b/src/capability-language/execution-scaffold.ts index 9ec6fb5..424252a 100644 --- a/src/capability-language/execution-scaffold.ts +++ b/src/capability-language/execution-scaffold.ts @@ -56,7 +56,7 @@ export async function executionScaffold( flake-utils.lib.eachDefaultSystem (system: let pkgs = import nixpkgs { inherit system; }; in { - quixosPackages.checkedArtifacts = { plan, generator, core, sharedRuntime, typescript, packageRevisionId, react ? null }: + quixosPackages.checkedArtifacts = { plan, generator, core, sharedRuntime, typescript, packageRevisionId, react ? null, ... }: (import (helpers + "/artifacts.nix")) { inherit pkgs plan core sharedRuntime typescript packageRevisionId; protocol = generator; diff --git a/src/capability-language/git-resolver.ts b/src/capability-language/git-resolver.ts index c87dcfc..5175e5c 100644 --- a/src/capability-language/git-resolver.ts +++ b/src/capability-language/git-resolver.ts @@ -38,7 +38,7 @@ export const createGitCapabilityResolver = async (options: { }>; }; for (const entry of document.resources ?? []) { - if (entry.kind !== "interface" && entry.kind !== "package") { + if (entry.kind !== "interface" && entry.kind !== "package" && entry.kind !== "build") { throw new Error(`Snapshot map has unsupported resource kind ${entry.kind}`); } const key = sourceKey(entry.kind, entry.repository, entry.commit); diff --git a/src/capability-language/pin-upgrades.ts b/src/capability-language/pin-upgrades.ts index 5748d98..21b24f9 100644 --- a/src/capability-language/pin-upgrades.ts +++ b/src/capability-language/pin-upgrades.ts @@ -19,7 +19,7 @@ import { planEvolution, type WorkspaceRevision, type EvolutionReview } from "../ import { withFileLock } from "./file-lock.js"; const execFile = promisify(callback); type Source = { repository: string; commit: string }; -export type UpgradeNode = { kind: "workspace" | "package" | "interface"; directory: string; source: Source }; +export type UpgradeNode = { kind: "workspace" | "package" | "interface" | "build"; directory: string; source: Source }; export type UpgradeSpec = { nodes: UpgradeNode[]; quixos?: Source; @@ -105,7 +105,7 @@ export const discoverUpgradeSpec = async (workbench: string): Promise ({ + ...graph.resources.map((entry: { kind: "interface" | "package" | "build"; directory: string; source: Source }) => ({ kind: entry.kind, source: entry.source, directory: path.relative(workbench, path.resolve(workbench, entry.directory)), @@ -139,7 +139,7 @@ export const planPinUpgrades = async (workbenchPath: string, spec: UpgradeSpec): const keys = new Map(); for (const node of spec.nodes) { validSource(node.source); - if (!["workspace", "package", "interface"].includes(node.kind) || keys.has(sourceKey(node))) + if (!["workspace", "package", "interface", "build"].includes(node.kind) || keys.has(sourceKey(node))) throw new Error("Duplicate/invalid upgrade resource identity"); keys.set(sourceKey(node), node.directory); } @@ -423,14 +423,14 @@ export const applyPinUpgrades = async ( const directory = await location(plan.workbench, node.directory); const standalone = await compileCapabilityResourceRepository({ rootDirectory: directory, - kind: node.kind as "package" | "interface", + kind: node.kind as "package" | "interface" | "build", source, resolveResource, }); for (const dependency of standalone.resources) resources.set(dependency.key, dependency); resources.set(key, { key, - kind: node.kind as "package" | "interface", + kind: node.kind as "package" | "interface" | "build", source, directory, lock: standalone.lock, @@ -450,11 +450,15 @@ export const applyPinUpgrades = async ( kind: node.kind, source: node.source, directory: node.directory, - resourceId: - node.resource.kind === "interface" - ? node.resource.revision.interfaceId - : node.resource.revision.packageId, - revisionId: node.resource.revision.revisionId, + ...(node.resource.kind === "build" + ? {} + : { + resourceId: + node.resource.kind === "interface" + ? node.resource.revision.interfaceId + : node.resource.revision.packageId, + revisionId: node.resource.revision.revisionId, + }), dependencies: [...node.dependencies.entries()].map(([binding, dependency]) => ({ binding, resourceKey: dependency.key, diff --git a/src/capability-language/resource-cli.ts b/src/capability-language/resource-cli.ts index 77c8de3..ae67357 100644 --- a/src/capability-language/resource-cli.ts +++ b/src/capability-language/resource-cli.ts @@ -6,7 +6,7 @@ import { bindingSchema } from "../bindings/index.js"; import { compileCapabilityResourceRepository, type ResolvedCapabilityResource } from "./assembly.js"; import { createGitCapabilityResolver } from "./git-resolver.js"; -const usage = `usage: quixos-resource-compile --root DIRECTORY --kind interface|package +const usage = `usage: quixos-resource-compile --root DIRECTORY --kind interface|package|build --repository URL --commit GIT_REV --checkout-root DIRECTORY [--snapshot-map PATH] [--snapshot-only true] [--graph-out PATH] [--schema-out PATH] @@ -41,7 +41,13 @@ const parseArgs = (args: string[]) => { const repository = values.get("--repository"); const commit = values.get("--commit")?.toLowerCase(); const checkoutRoot = values.get("--checkout-root"); - if (!rootDirectory || !repository || !commit || !checkoutRoot || (kind !== "interface" && kind !== "package")) { + if ( + !rootDirectory || + !repository || + !commit || + !checkoutRoot || + (kind !== "interface" && kind !== "package" && kind !== "build") + ) { throw new Error(usage); } if (!/^([0-9a-f]{40}|[0-9a-f]{64})$/.test(commit)) { @@ -67,9 +73,13 @@ const graphEntry = (node: ResolvedCapabilityResource) => ({ kind: node.kind, source: node.source, directory: node.directory, - resourceId: - node.resource.kind === "interface" ? node.resource.revision.interfaceId : node.resource.revision.packageId, - revisionId: node.resource.revision.revisionId, + ...(node.resource.kind === "build" + ? {} + : { + resourceId: + node.resource.kind === "interface" ? node.resource.revision.interfaceId : node.resource.revision.packageId, + revisionId: node.resource.revision.revisionId, + }), dependencies: [...node.dependencies.entries()].map(([binding, dependency]) => ({ binding, resourceKey: dependency.key, diff --git a/src/capability-language/structural-edits.ts b/src/capability-language/structural-edits.ts index c73b1a7..65cab67 100644 --- a/src/capability-language/structural-edits.ts +++ b/src/capability-language/structural-edits.ts @@ -15,7 +15,7 @@ export type StructuralEdit = | { operation: "quixos-pin"; source: { repository: string; commit: string } } | { operation: "dependency"; - kind: "interface" | "package"; + kind: "interface" | "package" | "build"; name: string; source: { repository: string; commit: string } | null; }; @@ -29,6 +29,8 @@ const selectable = new Set([ "packageResourceDecl", "atomDecl", "valueMember", + "moduleMember", + "moduleExport", "relationshipMember", "operationMember", "packageOperationExport", @@ -155,7 +157,7 @@ export const editStructure = (source: string, edit: StructuralEdit): string => { if (edit.operation === "dependency") { const parsed = parseQuixosLockDocument(source); if (!parsed.ok) throw new Error("Cannot scaffold an invalid lockfile"); - if (!["interface", "package"].includes(edit.kind) || !/^[A-Za-z_][A-Za-z0-9_]*$/.test(edit.name)) + if (!["interface", "package", "build"].includes(edit.kind) || !/^[A-Za-z_][A-Za-z0-9_]*$/.test(edit.name)) throw new Error("Invalid dependency selector"); const parser = new QuixosLockParser(new CommonTokenStream(new QuixosLockLexer(CharStream.fromString(source)))); const tree = parser.document(); diff --git a/src/capability-language/structural-plan.ts b/src/capability-language/structural-plan.ts index 5759058..80abff8 100644 --- a/src/capability-language/structural-plan.ts +++ b/src/capability-language/structural-plan.ts @@ -13,7 +13,7 @@ import { parseQuixosLockDocument } from "../resource-lock/index.js"; import { withFileLock } from "./file-lock.js"; export type StructuralRequest = { - kind: "workspace" | "interface" | "package"; + kind: "workspace" | "interface" | "package" | "build"; source?: { repository: string; commit: string }; resourceRoot?: string; validation?: "syntax" | "resource-graph"; @@ -159,10 +159,10 @@ export const planStructure = async (rootPath: string, request: StructuralRequest const resourceRoot = path.join(snapshot.directory, request.resourceRoot ?? ""); if (request.kind === "workspace") await compileWorkspaceRepository({ rootDirectory: resourceRoot, resolveResource }); - else if (["package", "interface"].includes(request.kind) && request.source) { + else if (["package", "interface", "build"].includes(request.kind) && request.source) { const compiled = await compileCapabilityResourceRepository({ rootDirectory: resourceRoot, - kind: request.kind as "package" | "interface", + kind: request.kind as "package" | "interface" | "build", source: { resolver: "git", ...request.source }, resolveResource, }); diff --git a/src/capability-language/tool-cli.ts b/src/capability-language/tool-cli.ts index fd614ee..c86a7ac 100644 --- a/src/capability-language/tool-cli.ts +++ b/src/capability-language/tool-cli.ts @@ -192,16 +192,16 @@ const main = async () => { } if (command === "check-committed" && !args.includes("--help")) { const [kind, repository, commit, log, ...extra] = args; - if (!["workspace", "interface", "package"].includes(kind) || !log || extra.length) - throw new Error("usage: quixos-qx check-committed workspace|interface|package REPOSITORY COMMIT LOG_FILE"); + if (!["workspace", "interface", "package", "build"].includes(kind) || !log || extra.length) + throw new Error("usage: quixos-qx check-committed workspace|interface|package|build REPOSITORY COMMIT LOG_FILE"); process.stdout.write( - `${await buildImmutableCandidate({ repository, commit }, kind as "workspace" | "interface" | "package", log)}\n`, + `${await buildImmutableCandidate({ repository, commit }, kind as "workspace" | "interface" | "package" | "build", log)}\n`, ); return; } if (!command || command === "--help" || args.includes("--help")) { process.stdout.write( - "quixos-qx: author-check, author-contract, converge, worklist, inspect, resources, check-committed, source-baseline, scaffold-package, scaffold-interface, scaffold-function, scaffold-query, scaffold-dependency, scaffold-structure, scaffold-resume, pin-upgrade, parse, lint, format\n" + + "quixos-qx: author-check, author-contract, converge, worklist, inspect, resources, check-committed, source-baseline, scaffold-package, scaffold-interface, scaffold-build, scaffold-function, scaffold-query, scaffold-dependency, scaffold-structure, scaffold-resume, pin-upgrade, parse, lint, format\n" + "inspect WORKBENCH [RESOURCE] shows provisional contracts, with explicit historical fallback; never verification evidence.\n" + "resources WORKBENCH lists registered editable repositories. Use qx-workspace for the workspace authoring workflow.\n", ); @@ -226,7 +226,7 @@ const main = async () => { if (flags.length && !flags[0].startsWith("--")) { repository = flags.shift(); commit = flags.shift(); - } else if (root && ["interface", "package"].includes(kind) && name) { + } else if (root && ["interface", "package", "build"].includes(kind) && name) { const context = await authoringContext(root); const alias = await realpath(path.join(context.workbench, `${kind}s`, name)).catch(() => null); const matches = context.resources.filter( @@ -256,15 +256,17 @@ const main = async () => { } if ( !root || - !["interface", "package"].includes(kind) || + !["interface", "package", "build"].includes(kind) || !/^[A-Za-z_][A-Za-z0-9_]*$/.test(name ?? "") || !repository || !commit || flags.some((flag) => flag !== "--write") ) - throw new Error("usage: quixos-qx scaffold-dependency ROOT interface|package NAME REPOSITORY COMMIT [--write]"); - const resourceKind = kind as "package" | "interface"; - let entrypoint: "workspace" | "package" | "interface" | undefined; + throw new Error( + "usage: quixos-qx scaffold-dependency ROOT interface|package|build NAME REPOSITORY COMMIT [--write]", + ); + const resourceKind = kind as "package" | "interface" | "build"; + let entrypoint: "workspace" | "package" | "interface" | "build" | undefined; for (const candidate of ["workspace", "package", "interface"] as const) { try { await readFile(path.join(root, `${candidate}.qx`)); @@ -274,7 +276,14 @@ const main = async () => { if ((error as NodeJS.ErrnoException).code !== "ENOENT") throw error; } } - if (!entrypoint) throw new Error("No QX repository entrypoint"); + if (!entrypoint) { + const context = await authoringContext(root); + const selected = context.resources.find( + (entry) => path.join(context.workbench, entry.directory) === path.resolve(root), + ); + if (selected?.kind !== "build") throw new Error("No QX repository entrypoint"); + entrypoint = "build"; + } const lock = await loadQuixosLock(path.join(root, "quixos.lock")); if (!lock.ok) throw new Error("Invalid resource lock"); let target = "quixos.lock"; @@ -288,7 +297,9 @@ const main = async () => { source: await authorSource(root), validation: "syntax", files: [ - { file: `${entrypoint}.qx`, edits: [{ operation: "import", kind: resourceKind, name }] }, + ...(entrypoint !== "build" && resourceKind !== "build" + ? [{ file: `${entrypoint}.qx`, edits: [{ operation: "import" as const, kind: resourceKind, name }] }] + : []), { file: target, edits: [{ operation: "dependency", kind: resourceKind, name, source: { repository, commit } }], @@ -301,26 +312,45 @@ const main = async () => { ); return; } - if (command === "scaffold-interface") { + if (command === "scaffold-interface" || command === "scaffold-build") { + const isBuild = command === "scaffold-build"; const [root, specFile, ...flags] = args; if (!root || !specFile || flags.some((flag) => flag !== "--write")) - throw new Error("usage: quixos-qx scaffold-interface ROOT SPEC_JSON [--write]"); + throw new Error("usage: quixos-qx scaffold-interface|scaffold-build ROOT SPEC_JSON [--write]"); const spec = (await readSpec(specFile)) as ScaffoldRecipe; - if (!spec.name || !/^[A-Za-z_][A-Za-z0-9_]*$/.test(spec.name) || !spec.id || !spec.revision || !spec.tools?.quixos) - throw new Error("Interface scaffold requires name, id, revision and Quixos toolchain source"); + if ( + !spec.name || + !/^[A-Za-z_][A-Za-z0-9_]*$/.test(spec.name) || + (!isBuild && (!spec.id || !spec.revision)) || + !spec.tools?.quixos + ) + throw new Error( + isBuild + ? "Build scaffold requires name and Quixos toolchain source" + : "Interface scaffold requires name, id, revision and Quixos toolchain source", + ); const request: StructuralRequest = { - kind: "interface", + kind: isBuild ? "build" : "interface", // Like package scaffolding, declaration creation is provisional. Imports // can be attached next; the normal check verifies the complete graph. validation: "syntax", source: spec.source, files: [ - { - file: "interface.qx", - create: - spec.declaration ?? - `interface ${spec.name} id ${JSON.stringify(spec.id)} revision ${JSON.stringify(spec.revision)} {\n}\n`, - }, + ...(!isBuild + ? [ + { + file: "interface.qx", + create: + spec.declaration ?? + `interface ${spec.name} id ${JSON.stringify(spec.id)} revision ${JSON.stringify(spec.revision)} {\n}\n`, + }, + ] + : [ + { + file: "README.md", + create: `# ${spec.name}\n\nManaged build dependency. Consumers select sources or Nix outputs through context.dependencies.\n`, + }, + ]), { file: "quixos.lock", create: formatQuixosLock({ diff --git a/src/capability-language/workspace-cli.ts b/src/capability-language/workspace-cli.ts index e7ddac0..82b4ac0 100644 --- a/src/capability-language/workspace-cli.ts +++ b/src/capability-language/workspace-cli.ts @@ -83,11 +83,15 @@ const main = async () => { kind: node.kind, source: node.source, directory: node.directory, - resourceId: - node.resource.kind === "interface" - ? node.resource.revision.interfaceId - : node.resource.revision.packageId, - revisionId: node.resource.revision.revisionId, + ...(node.resource.kind === "build" + ? {} + : { + resourceId: + node.resource.kind === "interface" + ? node.resource.revision.interfaceId + : node.resource.revision.packageId, + revisionId: node.resource.revision.revisionId, + }), dependencies: [...node.dependencies.entries()].map(([binding, dependency]) => ({ binding, resourceKey: dependency.key, @@ -108,14 +112,15 @@ const main = async () => { } if (options.schemasOut) { const schemas: Record = {}; - for (const node of assembled.resources.filter((entry) => entry.kind === "package")) { + for (const node of assembled.capabilityResources.filter((entry) => entry.kind === "package")) { const closure = new Map(); const visit = (entry: typeof node) => { - if (closure.has(entry.key)) return; + if (closure.has(entry.key) || entry.kind === "build") return; closure.set(entry.key, entry); entry.dependencies.forEach(visit); }; visit(node); + if (node.resource.kind !== "package") continue; schemas[node.resource.revision.revisionId] = specializeBindingSchema( bindingSchema({ resources: [...closure.values()] }), candidate, diff --git a/src/execution-world/client-contracts.ts b/src/execution-world/client-contracts.ts index 5dc58fd..7f99735 100644 --- a/src/execution-world/client-contracts.ts +++ b/src/execution-world/client-contracts.ts @@ -137,6 +137,7 @@ export function generatePackageQueryClientBindings( export function generateComponentClientBindings(plan: ExecutionPlan, packageRevision: string): string { const pkg = plan.definition.workspace.packageImports.find((pkg) => pkg.revisionId === packageRevision); const components = plan.definition.packages.find((pkg) => pkg.revision === packageRevision)?.components; + const modules = plan.definition.packages.find((pkg) => pkg.revision === packageRevision)?.modules ?? []; if (!pkg || !components?.length) throw new ExecutionPlanError("NO_COMPONENT_CONTRACT", packageRevision, "Package declares no component entries"); const byId = new Map(plan.definition.workspace.interfaceImports.map((iface) => [iface.revisionId as string, iface])); @@ -166,12 +167,15 @@ export function generateComponentClientBindings(plan: ExecutionPlan, packageRevi subjectBindings + "\n" + queries + - "\nexport interface Components {\n" + + "\nexport interface ModuleProps {}\n" + + "export type ExtraModuleProps = K extends keyof ModuleProps ? ModuleProps[K] : {};\n" + + "export interface Modules {\n" + components - .map( - (component) => - `${JSON.stringify(component.displayName)}: ComponentType>;`, - ) + .map((component) => { + const module = modules.find((module) => module.id === component.id)!; + const key = JSON.stringify([module.interfaceRevisionId, module.memberId]); + return `${JSON.stringify(component.displayName)}: ComponentType & ExtraModuleProps<${JSON.stringify(key)}>>;`; + }) .join("\n") + "\n}\n" ); diff --git a/src/execution-world/receipts.ts b/src/execution-world/receipts.ts index b2de639..689c6af 100644 --- a/src/execution-world/receipts.ts +++ b/src/execution-world/receipts.ts @@ -39,7 +39,13 @@ export function expectedArtifactReceipt( // A process service may implement transactions in any language. Only the // checked JS module path promises generated TypeScript adapter evidence. const available = new Set( - manifest.implementations.filter((i) => i.compatibility === "quixos-js-module-v1").map((i) => i.target), + manifest.implementations + .filter( + (i) => + i.compatibility === "quixos-js-module-v1" && + i.exports.some((id) => pkg.exports.some((entry) => entry.id === id && entry.execution.kind !== "remote")), + ) + .map((i) => i.target), ); const targets = [ ...new Set( diff --git a/src/resource-lock/generated/QuixosLock.interp b/src/resource-lock/generated/QuixosLock.interp index 256f43b..083e8bf 100644 --- a/src/resource-lock/generated/QuixosLock.interp +++ b/src/resource-lock/generated/QuixosLock.interp @@ -7,6 +7,7 @@ null 'source' 'interface' 'package' +'build' 'repository' 'commit' 'policy' @@ -34,6 +35,7 @@ QUIXOS SOURCE INTERFACE PACKAGE +BUILD REPOSITORY COMMIT POLICY @@ -66,4 +68,4 @@ stringLiteral atn: -[4, 1, 24, 87, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 1, 0, 1, 0, 3, 0, 23, 8, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 5, 0, 31, 8, 0, 10, 0, 12, 0, 34, 9, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 3, 6, 74, 8, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 0, 0, 10, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 0, 2, 1, 0, 6, 7, 1, 0, 12, 14, 81, 0, 20, 1, 0, 0, 0, 2, 38, 1, 0, 0, 0, 4, 42, 1, 0, 0, 0, 6, 47, 1, 0, 0, 0, 8, 51, 1, 0, 0, 0, 10, 53, 1, 0, 0, 0, 12, 62, 1, 0, 0, 0, 14, 80, 1, 0, 0, 0, 16, 82, 1, 0, 0, 0, 18, 84, 1, 0, 0, 0, 20, 22, 5, 1, 0, 0, 21, 23, 5, 2, 0, 0, 22, 21, 1, 0, 0, 0, 22, 23, 1, 0, 0, 0, 23, 24, 1, 0, 0, 0, 24, 25, 5, 3, 0, 0, 25, 26, 5, 19, 0, 0, 26, 32, 5, 16, 0, 0, 27, 31, 3, 2, 1, 0, 28, 31, 3, 6, 3, 0, 29, 31, 3, 4, 2, 0, 30, 27, 1, 0, 0, 0, 30, 28, 1, 0, 0, 0, 30, 29, 1, 0, 0, 0, 31, 34, 1, 0, 0, 0, 32, 30, 1, 0, 0, 0, 32, 33, 1, 0, 0, 0, 33, 35, 1, 0, 0, 0, 34, 32, 1, 0, 0, 0, 35, 36, 5, 17, 0, 0, 36, 37, 5, 0, 0, 1, 37, 1, 1, 0, 0, 0, 38, 39, 5, 4, 0, 0, 39, 40, 5, 5, 0, 0, 40, 41, 3, 12, 6, 0, 41, 3, 1, 0, 0, 0, 42, 43, 3, 8, 4, 0, 43, 44, 3, 16, 8, 0, 44, 45, 5, 5, 0, 0, 45, 46, 3, 10, 5, 0, 46, 5, 1, 0, 0, 0, 47, 48, 5, 15, 0, 0, 48, 49, 3, 18, 9, 0, 49, 50, 5, 18, 0, 0, 50, 7, 1, 0, 0, 0, 51, 52, 7, 0, 0, 0, 52, 9, 1, 0, 0, 0, 53, 54, 5, 16, 0, 0, 54, 55, 5, 8, 0, 0, 55, 56, 3, 18, 9, 0, 56, 57, 5, 18, 0, 0, 57, 58, 5, 9, 0, 0, 58, 59, 3, 18, 9, 0, 59, 60, 5, 18, 0, 0, 60, 61, 5, 17, 0, 0, 61, 11, 1, 0, 0, 0, 62, 63, 5, 16, 0, 0, 63, 64, 5, 8, 0, 0, 64, 65, 3, 18, 9, 0, 65, 73, 5, 18, 0, 0, 66, 67, 5, 10, 0, 0, 67, 68, 3, 14, 7, 0, 68, 69, 5, 18, 0, 0, 69, 70, 5, 11, 0, 0, 70, 71, 3, 18, 9, 0, 71, 72, 5, 18, 0, 0, 72, 74, 1, 0, 0, 0, 73, 66, 1, 0, 0, 0, 73, 74, 1, 0, 0, 0, 74, 75, 1, 0, 0, 0, 75, 76, 5, 9, 0, 0, 76, 77, 3, 18, 9, 0, 77, 78, 5, 18, 0, 0, 78, 79, 5, 17, 0, 0, 79, 13, 1, 0, 0, 0, 80, 81, 7, 1, 0, 0, 81, 15, 1, 0, 0, 0, 82, 83, 5, 20, 0, 0, 83, 17, 1, 0, 0, 0, 84, 85, 5, 21, 0, 0, 85, 19, 1, 0, 0, 0, 4, 22, 30, 32, 73] \ No newline at end of file +[4, 1, 25, 87, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 1, 0, 1, 0, 3, 0, 23, 8, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 5, 0, 31, 8, 0, 10, 0, 12, 0, 34, 9, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 3, 6, 74, 8, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 0, 0, 10, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 0, 2, 1, 0, 6, 8, 1, 0, 13, 15, 81, 0, 20, 1, 0, 0, 0, 2, 38, 1, 0, 0, 0, 4, 42, 1, 0, 0, 0, 6, 47, 1, 0, 0, 0, 8, 51, 1, 0, 0, 0, 10, 53, 1, 0, 0, 0, 12, 62, 1, 0, 0, 0, 14, 80, 1, 0, 0, 0, 16, 82, 1, 0, 0, 0, 18, 84, 1, 0, 0, 0, 20, 22, 5, 1, 0, 0, 21, 23, 5, 2, 0, 0, 22, 21, 1, 0, 0, 0, 22, 23, 1, 0, 0, 0, 23, 24, 1, 0, 0, 0, 24, 25, 5, 3, 0, 0, 25, 26, 5, 20, 0, 0, 26, 32, 5, 17, 0, 0, 27, 31, 3, 2, 1, 0, 28, 31, 3, 6, 3, 0, 29, 31, 3, 4, 2, 0, 30, 27, 1, 0, 0, 0, 30, 28, 1, 0, 0, 0, 30, 29, 1, 0, 0, 0, 31, 34, 1, 0, 0, 0, 32, 30, 1, 0, 0, 0, 32, 33, 1, 0, 0, 0, 33, 35, 1, 0, 0, 0, 34, 32, 1, 0, 0, 0, 35, 36, 5, 18, 0, 0, 36, 37, 5, 0, 0, 1, 37, 1, 1, 0, 0, 0, 38, 39, 5, 4, 0, 0, 39, 40, 5, 5, 0, 0, 40, 41, 3, 12, 6, 0, 41, 3, 1, 0, 0, 0, 42, 43, 3, 8, 4, 0, 43, 44, 3, 16, 8, 0, 44, 45, 5, 5, 0, 0, 45, 46, 3, 10, 5, 0, 46, 5, 1, 0, 0, 0, 47, 48, 5, 16, 0, 0, 48, 49, 3, 18, 9, 0, 49, 50, 5, 19, 0, 0, 50, 7, 1, 0, 0, 0, 51, 52, 7, 0, 0, 0, 52, 9, 1, 0, 0, 0, 53, 54, 5, 17, 0, 0, 54, 55, 5, 9, 0, 0, 55, 56, 3, 18, 9, 0, 56, 57, 5, 19, 0, 0, 57, 58, 5, 10, 0, 0, 58, 59, 3, 18, 9, 0, 59, 60, 5, 19, 0, 0, 60, 61, 5, 18, 0, 0, 61, 11, 1, 0, 0, 0, 62, 63, 5, 17, 0, 0, 63, 64, 5, 9, 0, 0, 64, 65, 3, 18, 9, 0, 65, 73, 5, 19, 0, 0, 66, 67, 5, 11, 0, 0, 67, 68, 3, 14, 7, 0, 68, 69, 5, 19, 0, 0, 69, 70, 5, 12, 0, 0, 70, 71, 3, 18, 9, 0, 71, 72, 5, 19, 0, 0, 72, 74, 1, 0, 0, 0, 73, 66, 1, 0, 0, 0, 73, 74, 1, 0, 0, 0, 74, 75, 1, 0, 0, 0, 75, 76, 5, 10, 0, 0, 76, 77, 3, 18, 9, 0, 77, 78, 5, 19, 0, 0, 78, 79, 5, 18, 0, 0, 79, 13, 1, 0, 0, 0, 80, 81, 7, 1, 0, 0, 81, 15, 1, 0, 0, 0, 82, 83, 5, 21, 0, 0, 83, 17, 1, 0, 0, 0, 84, 85, 5, 22, 0, 0, 85, 19, 1, 0, 0, 0, 4, 22, 30, 32, 73] \ No newline at end of file diff --git a/src/resource-lock/generated/QuixosLock.tokens b/src/resource-lock/generated/QuixosLock.tokens index fe6ae89..19c20a7 100644 --- a/src/resource-lock/generated/QuixosLock.tokens +++ b/src/resource-lock/generated/QuixosLock.tokens @@ -5,23 +5,24 @@ QUIXOS=4 SOURCE=5 INTERFACE=6 PACKAGE=7 -REPOSITORY=8 -COMMIT=9 -POLICY=10 -REF=11 -PINNED=12 -TRACK_RELEASE=13 -TRACK_DEVELOPMENT=14 -IMPORT=15 -LBRACE=16 -RBRACE=17 -SEMI=18 -INTEGER=19 -IDENTIFIER=20 -STRING_LITERAL=21 -LINE_COMMENT=22 -BLOCK_COMMENT=23 -WS=24 +BUILD=8 +REPOSITORY=9 +COMMIT=10 +POLICY=11 +REF=12 +PINNED=13 +TRACK_RELEASE=14 +TRACK_DEVELOPMENT=15 +IMPORT=16 +LBRACE=17 +RBRACE=18 +SEMI=19 +INTEGER=20 +IDENTIFIER=21 +STRING_LITERAL=22 +LINE_COMMENT=23 +BLOCK_COMMENT=24 +WS=25 'quixos-lock'=1 'fragment'=2 'version'=3 @@ -29,14 +30,15 @@ WS=24 'source'=5 'interface'=6 'package'=7 -'repository'=8 -'commit'=9 -'policy'=10 -'ref'=11 -'pinned'=12 -'track-release'=13 -'track-development'=14 -'import'=15 -'{'=16 -'}'=17 -';'=18 +'build'=8 +'repository'=9 +'commit'=10 +'policy'=11 +'ref'=12 +'pinned'=13 +'track-release'=14 +'track-development'=15 +'import'=16 +'{'=17 +'}'=18 +';'=19 diff --git a/src/resource-lock/generated/QuixosLockLexer.interp b/src/resource-lock/generated/QuixosLockLexer.interp index 81c332d..9f53487 100644 --- a/src/resource-lock/generated/QuixosLockLexer.interp +++ b/src/resource-lock/generated/QuixosLockLexer.interp @@ -7,6 +7,7 @@ null 'source' 'interface' 'package' +'build' 'repository' 'commit' 'policy' @@ -34,6 +35,7 @@ QUIXOS SOURCE INTERFACE PACKAGE +BUILD REPOSITORY COMMIT POLICY @@ -60,6 +62,7 @@ QUIXOS SOURCE INTERFACE PACKAGE +BUILD REPOSITORY COMMIT POLICY @@ -88,4 +91,4 @@ mode names: DEFAULT_MODE atn: -[4, 0, 24, 261, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 15, 1, 15, 1, 16, 1, 16, 1, 17, 1, 17, 1, 18, 4, 18, 197, 8, 18, 11, 18, 12, 18, 198, 1, 19, 1, 19, 5, 19, 203, 8, 19, 10, 19, 12, 19, 206, 9, 19, 1, 20, 1, 20, 1, 20, 5, 20, 211, 8, 20, 10, 20, 12, 20, 214, 9, 20, 1, 20, 1, 20, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 3, 21, 226, 8, 21, 1, 22, 1, 22, 1, 23, 1, 23, 1, 23, 1, 23, 5, 23, 234, 8, 23, 10, 23, 12, 23, 237, 9, 23, 1, 23, 1, 23, 1, 24, 1, 24, 1, 24, 1, 24, 5, 24, 245, 8, 24, 10, 24, 12, 24, 248, 9, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 25, 4, 25, 256, 8, 25, 11, 25, 12, 25, 257, 1, 25, 1, 25, 1, 246, 0, 26, 1, 1, 3, 2, 5, 3, 7, 4, 9, 5, 11, 6, 13, 7, 15, 8, 17, 9, 19, 10, 21, 11, 23, 12, 25, 13, 27, 14, 29, 15, 31, 16, 33, 17, 35, 18, 37, 19, 39, 20, 41, 21, 43, 0, 45, 0, 47, 22, 49, 23, 51, 24, 1, 0, 8, 1, 0, 48, 57, 3, 0, 65, 90, 95, 95, 97, 122, 4, 0, 48, 57, 65, 90, 95, 95, 97, 122, 4, 0, 10, 10, 13, 13, 34, 34, 92, 92, 8, 0, 34, 34, 47, 47, 92, 92, 98, 98, 102, 102, 110, 110, 114, 114, 116, 116, 3, 0, 48, 57, 65, 70, 97, 102, 2, 0, 10, 10, 13, 13, 3, 0, 9, 10, 13, 13, 32, 32, 266, 0, 1, 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, 0, 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 21, 1, 0, 0, 0, 0, 23, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 27, 1, 0, 0, 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 1, 0, 0, 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0, 0, 0, 0, 41, 1, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 49, 1, 0, 0, 0, 0, 51, 1, 0, 0, 0, 1, 53, 1, 0, 0, 0, 3, 65, 1, 0, 0, 0, 5, 74, 1, 0, 0, 0, 7, 82, 1, 0, 0, 0, 9, 89, 1, 0, 0, 0, 11, 96, 1, 0, 0, 0, 13, 106, 1, 0, 0, 0, 15, 114, 1, 0, 0, 0, 17, 125, 1, 0, 0, 0, 19, 132, 1, 0, 0, 0, 21, 139, 1, 0, 0, 0, 23, 143, 1, 0, 0, 0, 25, 150, 1, 0, 0, 0, 27, 164, 1, 0, 0, 0, 29, 182, 1, 0, 0, 0, 31, 189, 1, 0, 0, 0, 33, 191, 1, 0, 0, 0, 35, 193, 1, 0, 0, 0, 37, 196, 1, 0, 0, 0, 39, 200, 1, 0, 0, 0, 41, 207, 1, 0, 0, 0, 43, 217, 1, 0, 0, 0, 45, 227, 1, 0, 0, 0, 47, 229, 1, 0, 0, 0, 49, 240, 1, 0, 0, 0, 51, 255, 1, 0, 0, 0, 53, 54, 5, 113, 0, 0, 54, 55, 5, 117, 0, 0, 55, 56, 5, 105, 0, 0, 56, 57, 5, 120, 0, 0, 57, 58, 5, 111, 0, 0, 58, 59, 5, 115, 0, 0, 59, 60, 5, 45, 0, 0, 60, 61, 5, 108, 0, 0, 61, 62, 5, 111, 0, 0, 62, 63, 5, 99, 0, 0, 63, 64, 5, 107, 0, 0, 64, 2, 1, 0, 0, 0, 65, 66, 5, 102, 0, 0, 66, 67, 5, 114, 0, 0, 67, 68, 5, 97, 0, 0, 68, 69, 5, 103, 0, 0, 69, 70, 5, 109, 0, 0, 70, 71, 5, 101, 0, 0, 71, 72, 5, 110, 0, 0, 72, 73, 5, 116, 0, 0, 73, 4, 1, 0, 0, 0, 74, 75, 5, 118, 0, 0, 75, 76, 5, 101, 0, 0, 76, 77, 5, 114, 0, 0, 77, 78, 5, 115, 0, 0, 78, 79, 5, 105, 0, 0, 79, 80, 5, 111, 0, 0, 80, 81, 5, 110, 0, 0, 81, 6, 1, 0, 0, 0, 82, 83, 5, 113, 0, 0, 83, 84, 5, 117, 0, 0, 84, 85, 5, 105, 0, 0, 85, 86, 5, 120, 0, 0, 86, 87, 5, 111, 0, 0, 87, 88, 5, 115, 0, 0, 88, 8, 1, 0, 0, 0, 89, 90, 5, 115, 0, 0, 90, 91, 5, 111, 0, 0, 91, 92, 5, 117, 0, 0, 92, 93, 5, 114, 0, 0, 93, 94, 5, 99, 0, 0, 94, 95, 5, 101, 0, 0, 95, 10, 1, 0, 0, 0, 96, 97, 5, 105, 0, 0, 97, 98, 5, 110, 0, 0, 98, 99, 5, 116, 0, 0, 99, 100, 5, 101, 0, 0, 100, 101, 5, 114, 0, 0, 101, 102, 5, 102, 0, 0, 102, 103, 5, 97, 0, 0, 103, 104, 5, 99, 0, 0, 104, 105, 5, 101, 0, 0, 105, 12, 1, 0, 0, 0, 106, 107, 5, 112, 0, 0, 107, 108, 5, 97, 0, 0, 108, 109, 5, 99, 0, 0, 109, 110, 5, 107, 0, 0, 110, 111, 5, 97, 0, 0, 111, 112, 5, 103, 0, 0, 112, 113, 5, 101, 0, 0, 113, 14, 1, 0, 0, 0, 114, 115, 5, 114, 0, 0, 115, 116, 5, 101, 0, 0, 116, 117, 5, 112, 0, 0, 117, 118, 5, 111, 0, 0, 118, 119, 5, 115, 0, 0, 119, 120, 5, 105, 0, 0, 120, 121, 5, 116, 0, 0, 121, 122, 5, 111, 0, 0, 122, 123, 5, 114, 0, 0, 123, 124, 5, 121, 0, 0, 124, 16, 1, 0, 0, 0, 125, 126, 5, 99, 0, 0, 126, 127, 5, 111, 0, 0, 127, 128, 5, 109, 0, 0, 128, 129, 5, 109, 0, 0, 129, 130, 5, 105, 0, 0, 130, 131, 5, 116, 0, 0, 131, 18, 1, 0, 0, 0, 132, 133, 5, 112, 0, 0, 133, 134, 5, 111, 0, 0, 134, 135, 5, 108, 0, 0, 135, 136, 5, 105, 0, 0, 136, 137, 5, 99, 0, 0, 137, 138, 5, 121, 0, 0, 138, 20, 1, 0, 0, 0, 139, 140, 5, 114, 0, 0, 140, 141, 5, 101, 0, 0, 141, 142, 5, 102, 0, 0, 142, 22, 1, 0, 0, 0, 143, 144, 5, 112, 0, 0, 144, 145, 5, 105, 0, 0, 145, 146, 5, 110, 0, 0, 146, 147, 5, 110, 0, 0, 147, 148, 5, 101, 0, 0, 148, 149, 5, 100, 0, 0, 149, 24, 1, 0, 0, 0, 150, 151, 5, 116, 0, 0, 151, 152, 5, 114, 0, 0, 152, 153, 5, 97, 0, 0, 153, 154, 5, 99, 0, 0, 154, 155, 5, 107, 0, 0, 155, 156, 5, 45, 0, 0, 156, 157, 5, 114, 0, 0, 157, 158, 5, 101, 0, 0, 158, 159, 5, 108, 0, 0, 159, 160, 5, 101, 0, 0, 160, 161, 5, 97, 0, 0, 161, 162, 5, 115, 0, 0, 162, 163, 5, 101, 0, 0, 163, 26, 1, 0, 0, 0, 164, 165, 5, 116, 0, 0, 165, 166, 5, 114, 0, 0, 166, 167, 5, 97, 0, 0, 167, 168, 5, 99, 0, 0, 168, 169, 5, 107, 0, 0, 169, 170, 5, 45, 0, 0, 170, 171, 5, 100, 0, 0, 171, 172, 5, 101, 0, 0, 172, 173, 5, 118, 0, 0, 173, 174, 5, 101, 0, 0, 174, 175, 5, 108, 0, 0, 175, 176, 5, 111, 0, 0, 176, 177, 5, 112, 0, 0, 177, 178, 5, 109, 0, 0, 178, 179, 5, 101, 0, 0, 179, 180, 5, 110, 0, 0, 180, 181, 5, 116, 0, 0, 181, 28, 1, 0, 0, 0, 182, 183, 5, 105, 0, 0, 183, 184, 5, 109, 0, 0, 184, 185, 5, 112, 0, 0, 185, 186, 5, 111, 0, 0, 186, 187, 5, 114, 0, 0, 187, 188, 5, 116, 0, 0, 188, 30, 1, 0, 0, 0, 189, 190, 5, 123, 0, 0, 190, 32, 1, 0, 0, 0, 191, 192, 5, 125, 0, 0, 192, 34, 1, 0, 0, 0, 193, 194, 5, 59, 0, 0, 194, 36, 1, 0, 0, 0, 195, 197, 7, 0, 0, 0, 196, 195, 1, 0, 0, 0, 197, 198, 1, 0, 0, 0, 198, 196, 1, 0, 0, 0, 198, 199, 1, 0, 0, 0, 199, 38, 1, 0, 0, 0, 200, 204, 7, 1, 0, 0, 201, 203, 7, 2, 0, 0, 202, 201, 1, 0, 0, 0, 203, 206, 1, 0, 0, 0, 204, 202, 1, 0, 0, 0, 204, 205, 1, 0, 0, 0, 205, 40, 1, 0, 0, 0, 206, 204, 1, 0, 0, 0, 207, 212, 5, 34, 0, 0, 208, 211, 3, 43, 21, 0, 209, 211, 8, 3, 0, 0, 210, 208, 1, 0, 0, 0, 210, 209, 1, 0, 0, 0, 211, 214, 1, 0, 0, 0, 212, 210, 1, 0, 0, 0, 212, 213, 1, 0, 0, 0, 213, 215, 1, 0, 0, 0, 214, 212, 1, 0, 0, 0, 215, 216, 5, 34, 0, 0, 216, 42, 1, 0, 0, 0, 217, 225, 5, 92, 0, 0, 218, 226, 7, 4, 0, 0, 219, 220, 5, 117, 0, 0, 220, 221, 3, 45, 22, 0, 221, 222, 3, 45, 22, 0, 222, 223, 3, 45, 22, 0, 223, 224, 3, 45, 22, 0, 224, 226, 1, 0, 0, 0, 225, 218, 1, 0, 0, 0, 225, 219, 1, 0, 0, 0, 226, 44, 1, 0, 0, 0, 227, 228, 7, 5, 0, 0, 228, 46, 1, 0, 0, 0, 229, 230, 5, 47, 0, 0, 230, 231, 5, 47, 0, 0, 231, 235, 1, 0, 0, 0, 232, 234, 8, 6, 0, 0, 233, 232, 1, 0, 0, 0, 234, 237, 1, 0, 0, 0, 235, 233, 1, 0, 0, 0, 235, 236, 1, 0, 0, 0, 236, 238, 1, 0, 0, 0, 237, 235, 1, 0, 0, 0, 238, 239, 6, 23, 0, 0, 239, 48, 1, 0, 0, 0, 240, 241, 5, 47, 0, 0, 241, 242, 5, 42, 0, 0, 242, 246, 1, 0, 0, 0, 243, 245, 9, 0, 0, 0, 244, 243, 1, 0, 0, 0, 245, 248, 1, 0, 0, 0, 246, 247, 1, 0, 0, 0, 246, 244, 1, 0, 0, 0, 247, 249, 1, 0, 0, 0, 248, 246, 1, 0, 0, 0, 249, 250, 5, 42, 0, 0, 250, 251, 5, 47, 0, 0, 251, 252, 1, 0, 0, 0, 252, 253, 6, 24, 0, 0, 253, 50, 1, 0, 0, 0, 254, 256, 7, 7, 0, 0, 255, 254, 1, 0, 0, 0, 256, 257, 1, 0, 0, 0, 257, 255, 1, 0, 0, 0, 257, 258, 1, 0, 0, 0, 258, 259, 1, 0, 0, 0, 259, 260, 6, 25, 0, 0, 260, 52, 1, 0, 0, 0, 9, 0, 198, 204, 210, 212, 225, 235, 246, 257, 1, 6, 0, 0] \ No newline at end of file +[4, 0, 25, 269, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 11, 1, 11, 1, 11, 1, 11, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 16, 1, 16, 1, 17, 1, 17, 1, 18, 1, 18, 1, 19, 4, 19, 205, 8, 19, 11, 19, 12, 19, 206, 1, 20, 1, 20, 5, 20, 211, 8, 20, 10, 20, 12, 20, 214, 9, 20, 1, 21, 1, 21, 1, 21, 5, 21, 219, 8, 21, 10, 21, 12, 21, 222, 9, 21, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 3, 22, 234, 8, 22, 1, 23, 1, 23, 1, 24, 1, 24, 1, 24, 1, 24, 5, 24, 242, 8, 24, 10, 24, 12, 24, 245, 9, 24, 1, 24, 1, 24, 1, 25, 1, 25, 1, 25, 1, 25, 5, 25, 253, 8, 25, 10, 25, 12, 25, 256, 9, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 26, 4, 26, 264, 8, 26, 11, 26, 12, 26, 265, 1, 26, 1, 26, 1, 254, 0, 27, 1, 1, 3, 2, 5, 3, 7, 4, 9, 5, 11, 6, 13, 7, 15, 8, 17, 9, 19, 10, 21, 11, 23, 12, 25, 13, 27, 14, 29, 15, 31, 16, 33, 17, 35, 18, 37, 19, 39, 20, 41, 21, 43, 22, 45, 0, 47, 0, 49, 23, 51, 24, 53, 25, 1, 0, 8, 1, 0, 48, 57, 3, 0, 65, 90, 95, 95, 97, 122, 4, 0, 48, 57, 65, 90, 95, 95, 97, 122, 4, 0, 10, 10, 13, 13, 34, 34, 92, 92, 8, 0, 34, 34, 47, 47, 92, 92, 98, 98, 102, 102, 110, 110, 114, 114, 116, 116, 3, 0, 48, 57, 65, 70, 97, 102, 2, 0, 10, 10, 13, 13, 3, 0, 9, 10, 13, 13, 32, 32, 274, 0, 1, 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, 0, 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 21, 1, 0, 0, 0, 0, 23, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 27, 1, 0, 0, 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 1, 0, 0, 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0, 0, 0, 0, 41, 1, 0, 0, 0, 0, 43, 1, 0, 0, 0, 0, 49, 1, 0, 0, 0, 0, 51, 1, 0, 0, 0, 0, 53, 1, 0, 0, 0, 1, 55, 1, 0, 0, 0, 3, 67, 1, 0, 0, 0, 5, 76, 1, 0, 0, 0, 7, 84, 1, 0, 0, 0, 9, 91, 1, 0, 0, 0, 11, 98, 1, 0, 0, 0, 13, 108, 1, 0, 0, 0, 15, 116, 1, 0, 0, 0, 17, 122, 1, 0, 0, 0, 19, 133, 1, 0, 0, 0, 21, 140, 1, 0, 0, 0, 23, 147, 1, 0, 0, 0, 25, 151, 1, 0, 0, 0, 27, 158, 1, 0, 0, 0, 29, 172, 1, 0, 0, 0, 31, 190, 1, 0, 0, 0, 33, 197, 1, 0, 0, 0, 35, 199, 1, 0, 0, 0, 37, 201, 1, 0, 0, 0, 39, 204, 1, 0, 0, 0, 41, 208, 1, 0, 0, 0, 43, 215, 1, 0, 0, 0, 45, 225, 1, 0, 0, 0, 47, 235, 1, 0, 0, 0, 49, 237, 1, 0, 0, 0, 51, 248, 1, 0, 0, 0, 53, 263, 1, 0, 0, 0, 55, 56, 5, 113, 0, 0, 56, 57, 5, 117, 0, 0, 57, 58, 5, 105, 0, 0, 58, 59, 5, 120, 0, 0, 59, 60, 5, 111, 0, 0, 60, 61, 5, 115, 0, 0, 61, 62, 5, 45, 0, 0, 62, 63, 5, 108, 0, 0, 63, 64, 5, 111, 0, 0, 64, 65, 5, 99, 0, 0, 65, 66, 5, 107, 0, 0, 66, 2, 1, 0, 0, 0, 67, 68, 5, 102, 0, 0, 68, 69, 5, 114, 0, 0, 69, 70, 5, 97, 0, 0, 70, 71, 5, 103, 0, 0, 71, 72, 5, 109, 0, 0, 72, 73, 5, 101, 0, 0, 73, 74, 5, 110, 0, 0, 74, 75, 5, 116, 0, 0, 75, 4, 1, 0, 0, 0, 76, 77, 5, 118, 0, 0, 77, 78, 5, 101, 0, 0, 78, 79, 5, 114, 0, 0, 79, 80, 5, 115, 0, 0, 80, 81, 5, 105, 0, 0, 81, 82, 5, 111, 0, 0, 82, 83, 5, 110, 0, 0, 83, 6, 1, 0, 0, 0, 84, 85, 5, 113, 0, 0, 85, 86, 5, 117, 0, 0, 86, 87, 5, 105, 0, 0, 87, 88, 5, 120, 0, 0, 88, 89, 5, 111, 0, 0, 89, 90, 5, 115, 0, 0, 90, 8, 1, 0, 0, 0, 91, 92, 5, 115, 0, 0, 92, 93, 5, 111, 0, 0, 93, 94, 5, 117, 0, 0, 94, 95, 5, 114, 0, 0, 95, 96, 5, 99, 0, 0, 96, 97, 5, 101, 0, 0, 97, 10, 1, 0, 0, 0, 98, 99, 5, 105, 0, 0, 99, 100, 5, 110, 0, 0, 100, 101, 5, 116, 0, 0, 101, 102, 5, 101, 0, 0, 102, 103, 5, 114, 0, 0, 103, 104, 5, 102, 0, 0, 104, 105, 5, 97, 0, 0, 105, 106, 5, 99, 0, 0, 106, 107, 5, 101, 0, 0, 107, 12, 1, 0, 0, 0, 108, 109, 5, 112, 0, 0, 109, 110, 5, 97, 0, 0, 110, 111, 5, 99, 0, 0, 111, 112, 5, 107, 0, 0, 112, 113, 5, 97, 0, 0, 113, 114, 5, 103, 0, 0, 114, 115, 5, 101, 0, 0, 115, 14, 1, 0, 0, 0, 116, 117, 5, 98, 0, 0, 117, 118, 5, 117, 0, 0, 118, 119, 5, 105, 0, 0, 119, 120, 5, 108, 0, 0, 120, 121, 5, 100, 0, 0, 121, 16, 1, 0, 0, 0, 122, 123, 5, 114, 0, 0, 123, 124, 5, 101, 0, 0, 124, 125, 5, 112, 0, 0, 125, 126, 5, 111, 0, 0, 126, 127, 5, 115, 0, 0, 127, 128, 5, 105, 0, 0, 128, 129, 5, 116, 0, 0, 129, 130, 5, 111, 0, 0, 130, 131, 5, 114, 0, 0, 131, 132, 5, 121, 0, 0, 132, 18, 1, 0, 0, 0, 133, 134, 5, 99, 0, 0, 134, 135, 5, 111, 0, 0, 135, 136, 5, 109, 0, 0, 136, 137, 5, 109, 0, 0, 137, 138, 5, 105, 0, 0, 138, 139, 5, 116, 0, 0, 139, 20, 1, 0, 0, 0, 140, 141, 5, 112, 0, 0, 141, 142, 5, 111, 0, 0, 142, 143, 5, 108, 0, 0, 143, 144, 5, 105, 0, 0, 144, 145, 5, 99, 0, 0, 145, 146, 5, 121, 0, 0, 146, 22, 1, 0, 0, 0, 147, 148, 5, 114, 0, 0, 148, 149, 5, 101, 0, 0, 149, 150, 5, 102, 0, 0, 150, 24, 1, 0, 0, 0, 151, 152, 5, 112, 0, 0, 152, 153, 5, 105, 0, 0, 153, 154, 5, 110, 0, 0, 154, 155, 5, 110, 0, 0, 155, 156, 5, 101, 0, 0, 156, 157, 5, 100, 0, 0, 157, 26, 1, 0, 0, 0, 158, 159, 5, 116, 0, 0, 159, 160, 5, 114, 0, 0, 160, 161, 5, 97, 0, 0, 161, 162, 5, 99, 0, 0, 162, 163, 5, 107, 0, 0, 163, 164, 5, 45, 0, 0, 164, 165, 5, 114, 0, 0, 165, 166, 5, 101, 0, 0, 166, 167, 5, 108, 0, 0, 167, 168, 5, 101, 0, 0, 168, 169, 5, 97, 0, 0, 169, 170, 5, 115, 0, 0, 170, 171, 5, 101, 0, 0, 171, 28, 1, 0, 0, 0, 172, 173, 5, 116, 0, 0, 173, 174, 5, 114, 0, 0, 174, 175, 5, 97, 0, 0, 175, 176, 5, 99, 0, 0, 176, 177, 5, 107, 0, 0, 177, 178, 5, 45, 0, 0, 178, 179, 5, 100, 0, 0, 179, 180, 5, 101, 0, 0, 180, 181, 5, 118, 0, 0, 181, 182, 5, 101, 0, 0, 182, 183, 5, 108, 0, 0, 183, 184, 5, 111, 0, 0, 184, 185, 5, 112, 0, 0, 185, 186, 5, 109, 0, 0, 186, 187, 5, 101, 0, 0, 187, 188, 5, 110, 0, 0, 188, 189, 5, 116, 0, 0, 189, 30, 1, 0, 0, 0, 190, 191, 5, 105, 0, 0, 191, 192, 5, 109, 0, 0, 192, 193, 5, 112, 0, 0, 193, 194, 5, 111, 0, 0, 194, 195, 5, 114, 0, 0, 195, 196, 5, 116, 0, 0, 196, 32, 1, 0, 0, 0, 197, 198, 5, 123, 0, 0, 198, 34, 1, 0, 0, 0, 199, 200, 5, 125, 0, 0, 200, 36, 1, 0, 0, 0, 201, 202, 5, 59, 0, 0, 202, 38, 1, 0, 0, 0, 203, 205, 7, 0, 0, 0, 204, 203, 1, 0, 0, 0, 205, 206, 1, 0, 0, 0, 206, 204, 1, 0, 0, 0, 206, 207, 1, 0, 0, 0, 207, 40, 1, 0, 0, 0, 208, 212, 7, 1, 0, 0, 209, 211, 7, 2, 0, 0, 210, 209, 1, 0, 0, 0, 211, 214, 1, 0, 0, 0, 212, 210, 1, 0, 0, 0, 212, 213, 1, 0, 0, 0, 213, 42, 1, 0, 0, 0, 214, 212, 1, 0, 0, 0, 215, 220, 5, 34, 0, 0, 216, 219, 3, 45, 22, 0, 217, 219, 8, 3, 0, 0, 218, 216, 1, 0, 0, 0, 218, 217, 1, 0, 0, 0, 219, 222, 1, 0, 0, 0, 220, 218, 1, 0, 0, 0, 220, 221, 1, 0, 0, 0, 221, 223, 1, 0, 0, 0, 222, 220, 1, 0, 0, 0, 223, 224, 5, 34, 0, 0, 224, 44, 1, 0, 0, 0, 225, 233, 5, 92, 0, 0, 226, 234, 7, 4, 0, 0, 227, 228, 5, 117, 0, 0, 228, 229, 3, 47, 23, 0, 229, 230, 3, 47, 23, 0, 230, 231, 3, 47, 23, 0, 231, 232, 3, 47, 23, 0, 232, 234, 1, 0, 0, 0, 233, 226, 1, 0, 0, 0, 233, 227, 1, 0, 0, 0, 234, 46, 1, 0, 0, 0, 235, 236, 7, 5, 0, 0, 236, 48, 1, 0, 0, 0, 237, 238, 5, 47, 0, 0, 238, 239, 5, 47, 0, 0, 239, 243, 1, 0, 0, 0, 240, 242, 8, 6, 0, 0, 241, 240, 1, 0, 0, 0, 242, 245, 1, 0, 0, 0, 243, 241, 1, 0, 0, 0, 243, 244, 1, 0, 0, 0, 244, 246, 1, 0, 0, 0, 245, 243, 1, 0, 0, 0, 246, 247, 6, 24, 0, 0, 247, 50, 1, 0, 0, 0, 248, 249, 5, 47, 0, 0, 249, 250, 5, 42, 0, 0, 250, 254, 1, 0, 0, 0, 251, 253, 9, 0, 0, 0, 252, 251, 1, 0, 0, 0, 253, 256, 1, 0, 0, 0, 254, 255, 1, 0, 0, 0, 254, 252, 1, 0, 0, 0, 255, 257, 1, 0, 0, 0, 256, 254, 1, 0, 0, 0, 257, 258, 5, 42, 0, 0, 258, 259, 5, 47, 0, 0, 259, 260, 1, 0, 0, 0, 260, 261, 6, 25, 0, 0, 261, 52, 1, 0, 0, 0, 262, 264, 7, 7, 0, 0, 263, 262, 1, 0, 0, 0, 264, 265, 1, 0, 0, 0, 265, 263, 1, 0, 0, 0, 265, 266, 1, 0, 0, 0, 266, 267, 1, 0, 0, 0, 267, 268, 6, 26, 0, 0, 268, 54, 1, 0, 0, 0, 9, 0, 206, 212, 218, 220, 233, 243, 254, 265, 1, 6, 0, 0] \ No newline at end of file diff --git a/src/resource-lock/generated/QuixosLockLexer.tokens b/src/resource-lock/generated/QuixosLockLexer.tokens index fe6ae89..19c20a7 100644 --- a/src/resource-lock/generated/QuixosLockLexer.tokens +++ b/src/resource-lock/generated/QuixosLockLexer.tokens @@ -5,23 +5,24 @@ QUIXOS=4 SOURCE=5 INTERFACE=6 PACKAGE=7 -REPOSITORY=8 -COMMIT=9 -POLICY=10 -REF=11 -PINNED=12 -TRACK_RELEASE=13 -TRACK_DEVELOPMENT=14 -IMPORT=15 -LBRACE=16 -RBRACE=17 -SEMI=18 -INTEGER=19 -IDENTIFIER=20 -STRING_LITERAL=21 -LINE_COMMENT=22 -BLOCK_COMMENT=23 -WS=24 +BUILD=8 +REPOSITORY=9 +COMMIT=10 +POLICY=11 +REF=12 +PINNED=13 +TRACK_RELEASE=14 +TRACK_DEVELOPMENT=15 +IMPORT=16 +LBRACE=17 +RBRACE=18 +SEMI=19 +INTEGER=20 +IDENTIFIER=21 +STRING_LITERAL=22 +LINE_COMMENT=23 +BLOCK_COMMENT=24 +WS=25 'quixos-lock'=1 'fragment'=2 'version'=3 @@ -29,14 +30,15 @@ WS=24 'source'=5 'interface'=6 'package'=7 -'repository'=8 -'commit'=9 -'policy'=10 -'ref'=11 -'pinned'=12 -'track-release'=13 -'track-development'=14 -'import'=15 -'{'=16 -'}'=17 -';'=18 +'build'=8 +'repository'=9 +'commit'=10 +'policy'=11 +'ref'=12 +'pinned'=13 +'track-release'=14 +'track-development'=15 +'import'=16 +'{'=17 +'}'=18 +';'=19 diff --git a/src/resource-lock/generated/QuixosLockLexer.ts b/src/resource-lock/generated/QuixosLockLexer.ts index 30003f3..821313f 100644 --- a/src/resource-lock/generated/QuixosLockLexer.ts +++ b/src/resource-lock/generated/QuixosLockLexer.ts @@ -11,23 +11,24 @@ export class QuixosLockLexer extends antlr.Lexer { public static readonly SOURCE = 5; public static readonly INTERFACE = 6; public static readonly PACKAGE = 7; - public static readonly REPOSITORY = 8; - public static readonly COMMIT = 9; - public static readonly POLICY = 10; - public static readonly REF = 11; - public static readonly PINNED = 12; - public static readonly TRACK_RELEASE = 13; - public static readonly TRACK_DEVELOPMENT = 14; - public static readonly IMPORT = 15; - public static readonly LBRACE = 16; - public static readonly RBRACE = 17; - public static readonly SEMI = 18; - public static readonly INTEGER = 19; - public static readonly IDENTIFIER = 20; - public static readonly STRING_LITERAL = 21; - public static readonly LINE_COMMENT = 22; - public static readonly BLOCK_COMMENT = 23; - public static readonly WS = 24; + public static readonly BUILD = 8; + public static readonly REPOSITORY = 9; + public static readonly COMMIT = 10; + public static readonly POLICY = 11; + public static readonly REF = 12; + public static readonly PINNED = 13; + public static readonly TRACK_RELEASE = 14; + public static readonly TRACK_DEVELOPMENT = 15; + public static readonly IMPORT = 16; + public static readonly LBRACE = 17; + public static readonly RBRACE = 18; + public static readonly SEMI = 19; + public static readonly INTEGER = 20; + public static readonly IDENTIFIER = 21; + public static readonly STRING_LITERAL = 22; + public static readonly LINE_COMMENT = 23; + public static readonly BLOCK_COMMENT = 24; + public static readonly WS = 25; public static readonly channelNames = [ "DEFAULT_TOKEN_CHANNEL", "HIDDEN" @@ -35,17 +36,17 @@ export class QuixosLockLexer extends antlr.Lexer { public static readonly literalNames = [ null, "'quixos-lock'", "'fragment'", "'version'", "'quixos'", "'source'", - "'interface'", "'package'", "'repository'", "'commit'", "'policy'", - "'ref'", "'pinned'", "'track-release'", "'track-development'", "'import'", - "'{'", "'}'", "';'" + "'interface'", "'package'", "'build'", "'repository'", "'commit'", + "'policy'", "'ref'", "'pinned'", "'track-release'", "'track-development'", + "'import'", "'{'", "'}'", "';'" ]; public static readonly symbolicNames = [ null, "QUIXOS_LOCK", "FRAGMENT", "VERSION", "QUIXOS", "SOURCE", - "INTERFACE", "PACKAGE", "REPOSITORY", "COMMIT", "POLICY", "REF", - "PINNED", "TRACK_RELEASE", "TRACK_DEVELOPMENT", "IMPORT", "LBRACE", - "RBRACE", "SEMI", "INTEGER", "IDENTIFIER", "STRING_LITERAL", "LINE_COMMENT", - "BLOCK_COMMENT", "WS" + "INTERFACE", "PACKAGE", "BUILD", "REPOSITORY", "COMMIT", "POLICY", + "REF", "PINNED", "TRACK_RELEASE", "TRACK_DEVELOPMENT", "IMPORT", + "LBRACE", "RBRACE", "SEMI", "INTEGER", "IDENTIFIER", "STRING_LITERAL", + "LINE_COMMENT", "BLOCK_COMMENT", "WS" ]; public static readonly modeNames = [ @@ -54,10 +55,10 @@ export class QuixosLockLexer extends antlr.Lexer { public static readonly ruleNames = [ "QUIXOS_LOCK", "FRAGMENT", "VERSION", "QUIXOS", "SOURCE", "INTERFACE", - "PACKAGE", "REPOSITORY", "COMMIT", "POLICY", "REF", "PINNED", "TRACK_RELEASE", - "TRACK_DEVELOPMENT", "IMPORT", "LBRACE", "RBRACE", "SEMI", "INTEGER", - "IDENTIFIER", "STRING_LITERAL", "ESC", "HEX", "LINE_COMMENT", "BLOCK_COMMENT", - "WS", + "PACKAGE", "BUILD", "REPOSITORY", "COMMIT", "POLICY", "REF", "PINNED", + "TRACK_RELEASE", "TRACK_DEVELOPMENT", "IMPORT", "LBRACE", "RBRACE", + "SEMI", "INTEGER", "IDENTIFIER", "STRING_LITERAL", "ESC", "HEX", + "LINE_COMMENT", "BLOCK_COMMENT", "WS", ]; @@ -79,99 +80,101 @@ export class QuixosLockLexer extends antlr.Lexer { public get modeNames(): string[] { return QuixosLockLexer.modeNames; } public static readonly _serializedATN: number[] = [ - 4,0,24,261,6,-1,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5, + 4,0,25,269,6,-1,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5, 2,6,7,6,2,7,7,7,2,8,7,8,2,9,7,9,2,10,7,10,2,11,7,11,2,12,7,12,2, 13,7,13,2,14,7,14,2,15,7,15,2,16,7,16,2,17,7,17,2,18,7,18,2,19,7, - 19,2,20,7,20,2,21,7,21,2,22,7,22,2,23,7,23,2,24,7,24,2,25,7,25,1, - 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,3,1,3,1,3,1, - 3,1,3,1,3,1,3,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,5,1,5,1,5,1,5,1,5,1, - 5,1,5,1,5,1,5,1,5,1,6,1,6,1,6,1,6,1,6,1,6,1,6,1,6,1,7,1,7,1,7,1, - 7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,9,1, - 9,1,9,1,9,1,9,1,9,1,9,1,10,1,10,1,10,1,10,1,11,1,11,1,11,1,11,1, - 11,1,11,1,11,1,12,1,12,1,12,1,12,1,12,1,12,1,12,1,12,1,12,1,12,1, - 12,1,12,1,12,1,12,1,13,1,13,1,13,1,13,1,13,1,13,1,13,1,13,1,13,1, - 13,1,13,1,13,1,13,1,13,1,13,1,13,1,13,1,13,1,14,1,14,1,14,1,14,1, - 14,1,14,1,14,1,15,1,15,1,16,1,16,1,17,1,17,1,18,4,18,197,8,18,11, - 18,12,18,198,1,19,1,19,5,19,203,8,19,10,19,12,19,206,9,19,1,20,1, - 20,1,20,5,20,211,8,20,10,20,12,20,214,9,20,1,20,1,20,1,21,1,21,1, - 21,1,21,1,21,1,21,1,21,1,21,3,21,226,8,21,1,22,1,22,1,23,1,23,1, - 23,1,23,5,23,234,8,23,10,23,12,23,237,9,23,1,23,1,23,1,24,1,24,1, - 24,1,24,5,24,245,8,24,10,24,12,24,248,9,24,1,24,1,24,1,24,1,24,1, - 24,1,25,4,25,256,8,25,11,25,12,25,257,1,25,1,25,1,246,0,26,1,1,3, - 2,5,3,7,4,9,5,11,6,13,7,15,8,17,9,19,10,21,11,23,12,25,13,27,14, - 29,15,31,16,33,17,35,18,37,19,39,20,41,21,43,0,45,0,47,22,49,23, - 51,24,1,0,8,1,0,48,57,3,0,65,90,95,95,97,122,4,0,48,57,65,90,95, - 95,97,122,4,0,10,10,13,13,34,34,92,92,8,0,34,34,47,47,92,92,98,98, - 102,102,110,110,114,114,116,116,3,0,48,57,65,70,97,102,2,0,10,10, - 13,13,3,0,9,10,13,13,32,32,266,0,1,1,0,0,0,0,3,1,0,0,0,0,5,1,0,0, - 0,0,7,1,0,0,0,0,9,1,0,0,0,0,11,1,0,0,0,0,13,1,0,0,0,0,15,1,0,0,0, - 0,17,1,0,0,0,0,19,1,0,0,0,0,21,1,0,0,0,0,23,1,0,0,0,0,25,1,0,0,0, - 0,27,1,0,0,0,0,29,1,0,0,0,0,31,1,0,0,0,0,33,1,0,0,0,0,35,1,0,0,0, - 0,37,1,0,0,0,0,39,1,0,0,0,0,41,1,0,0,0,0,47,1,0,0,0,0,49,1,0,0,0, - 0,51,1,0,0,0,1,53,1,0,0,0,3,65,1,0,0,0,5,74,1,0,0,0,7,82,1,0,0,0, - 9,89,1,0,0,0,11,96,1,0,0,0,13,106,1,0,0,0,15,114,1,0,0,0,17,125, - 1,0,0,0,19,132,1,0,0,0,21,139,1,0,0,0,23,143,1,0,0,0,25,150,1,0, - 0,0,27,164,1,0,0,0,29,182,1,0,0,0,31,189,1,0,0,0,33,191,1,0,0,0, - 35,193,1,0,0,0,37,196,1,0,0,0,39,200,1,0,0,0,41,207,1,0,0,0,43,217, - 1,0,0,0,45,227,1,0,0,0,47,229,1,0,0,0,49,240,1,0,0,0,51,255,1,0, - 0,0,53,54,5,113,0,0,54,55,5,117,0,0,55,56,5,105,0,0,56,57,5,120, - 0,0,57,58,5,111,0,0,58,59,5,115,0,0,59,60,5,45,0,0,60,61,5,108,0, - 0,61,62,5,111,0,0,62,63,5,99,0,0,63,64,5,107,0,0,64,2,1,0,0,0,65, - 66,5,102,0,0,66,67,5,114,0,0,67,68,5,97,0,0,68,69,5,103,0,0,69,70, - 5,109,0,0,70,71,5,101,0,0,71,72,5,110,0,0,72,73,5,116,0,0,73,4,1, - 0,0,0,74,75,5,118,0,0,75,76,5,101,0,0,76,77,5,114,0,0,77,78,5,115, - 0,0,78,79,5,105,0,0,79,80,5,111,0,0,80,81,5,110,0,0,81,6,1,0,0,0, - 82,83,5,113,0,0,83,84,5,117,0,0,84,85,5,105,0,0,85,86,5,120,0,0, - 86,87,5,111,0,0,87,88,5,115,0,0,88,8,1,0,0,0,89,90,5,115,0,0,90, - 91,5,111,0,0,91,92,5,117,0,0,92,93,5,114,0,0,93,94,5,99,0,0,94,95, - 5,101,0,0,95,10,1,0,0,0,96,97,5,105,0,0,97,98,5,110,0,0,98,99,5, - 116,0,0,99,100,5,101,0,0,100,101,5,114,0,0,101,102,5,102,0,0,102, - 103,5,97,0,0,103,104,5,99,0,0,104,105,5,101,0,0,105,12,1,0,0,0,106, - 107,5,112,0,0,107,108,5,97,0,0,108,109,5,99,0,0,109,110,5,107,0, - 0,110,111,5,97,0,0,111,112,5,103,0,0,112,113,5,101,0,0,113,14,1, - 0,0,0,114,115,5,114,0,0,115,116,5,101,0,0,116,117,5,112,0,0,117, - 118,5,111,0,0,118,119,5,115,0,0,119,120,5,105,0,0,120,121,5,116, - 0,0,121,122,5,111,0,0,122,123,5,114,0,0,123,124,5,121,0,0,124,16, - 1,0,0,0,125,126,5,99,0,0,126,127,5,111,0,0,127,128,5,109,0,0,128, - 129,5,109,0,0,129,130,5,105,0,0,130,131,5,116,0,0,131,18,1,0,0,0, - 132,133,5,112,0,0,133,134,5,111,0,0,134,135,5,108,0,0,135,136,5, - 105,0,0,136,137,5,99,0,0,137,138,5,121,0,0,138,20,1,0,0,0,139,140, - 5,114,0,0,140,141,5,101,0,0,141,142,5,102,0,0,142,22,1,0,0,0,143, - 144,5,112,0,0,144,145,5,105,0,0,145,146,5,110,0,0,146,147,5,110, - 0,0,147,148,5,101,0,0,148,149,5,100,0,0,149,24,1,0,0,0,150,151,5, - 116,0,0,151,152,5,114,0,0,152,153,5,97,0,0,153,154,5,99,0,0,154, - 155,5,107,0,0,155,156,5,45,0,0,156,157,5,114,0,0,157,158,5,101,0, - 0,158,159,5,108,0,0,159,160,5,101,0,0,160,161,5,97,0,0,161,162,5, - 115,0,0,162,163,5,101,0,0,163,26,1,0,0,0,164,165,5,116,0,0,165,166, - 5,114,0,0,166,167,5,97,0,0,167,168,5,99,0,0,168,169,5,107,0,0,169, - 170,5,45,0,0,170,171,5,100,0,0,171,172,5,101,0,0,172,173,5,118,0, - 0,173,174,5,101,0,0,174,175,5,108,0,0,175,176,5,111,0,0,176,177, - 5,112,0,0,177,178,5,109,0,0,178,179,5,101,0,0,179,180,5,110,0,0, - 180,181,5,116,0,0,181,28,1,0,0,0,182,183,5,105,0,0,183,184,5,109, - 0,0,184,185,5,112,0,0,185,186,5,111,0,0,186,187,5,114,0,0,187,188, - 5,116,0,0,188,30,1,0,0,0,189,190,5,123,0,0,190,32,1,0,0,0,191,192, - 5,125,0,0,192,34,1,0,0,0,193,194,5,59,0,0,194,36,1,0,0,0,195,197, - 7,0,0,0,196,195,1,0,0,0,197,198,1,0,0,0,198,196,1,0,0,0,198,199, - 1,0,0,0,199,38,1,0,0,0,200,204,7,1,0,0,201,203,7,2,0,0,202,201,1, - 0,0,0,203,206,1,0,0,0,204,202,1,0,0,0,204,205,1,0,0,0,205,40,1,0, - 0,0,206,204,1,0,0,0,207,212,5,34,0,0,208,211,3,43,21,0,209,211,8, - 3,0,0,210,208,1,0,0,0,210,209,1,0,0,0,211,214,1,0,0,0,212,210,1, - 0,0,0,212,213,1,0,0,0,213,215,1,0,0,0,214,212,1,0,0,0,215,216,5, - 34,0,0,216,42,1,0,0,0,217,225,5,92,0,0,218,226,7,4,0,0,219,220,5, - 117,0,0,220,221,3,45,22,0,221,222,3,45,22,0,222,223,3,45,22,0,223, - 224,3,45,22,0,224,226,1,0,0,0,225,218,1,0,0,0,225,219,1,0,0,0,226, - 44,1,0,0,0,227,228,7,5,0,0,228,46,1,0,0,0,229,230,5,47,0,0,230,231, - 5,47,0,0,231,235,1,0,0,0,232,234,8,6,0,0,233,232,1,0,0,0,234,237, - 1,0,0,0,235,233,1,0,0,0,235,236,1,0,0,0,236,238,1,0,0,0,237,235, - 1,0,0,0,238,239,6,23,0,0,239,48,1,0,0,0,240,241,5,47,0,0,241,242, - 5,42,0,0,242,246,1,0,0,0,243,245,9,0,0,0,244,243,1,0,0,0,245,248, - 1,0,0,0,246,247,1,0,0,0,246,244,1,0,0,0,247,249,1,0,0,0,248,246, - 1,0,0,0,249,250,5,42,0,0,250,251,5,47,0,0,251,252,1,0,0,0,252,253, - 6,24,0,0,253,50,1,0,0,0,254,256,7,7,0,0,255,254,1,0,0,0,256,257, - 1,0,0,0,257,255,1,0,0,0,257,258,1,0,0,0,258,259,1,0,0,0,259,260, - 6,25,0,0,260,52,1,0,0,0,9,0,198,204,210,212,225,235,246,257,1,6, - 0,0 + 19,2,20,7,20,2,21,7,21,2,22,7,22,2,23,7,23,2,24,7,24,2,25,7,25,2, + 26,7,26,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,3, + 1,3,1,3,1,3,1,3,1,3,1,3,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,5,1,5,1,5, + 1,5,1,5,1,5,1,5,1,5,1,5,1,5,1,6,1,6,1,6,1,6,1,6,1,6,1,6,1,6,1,7, + 1,7,1,7,1,7,1,7,1,7,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8, + 1,9,1,9,1,9,1,9,1,9,1,9,1,9,1,10,1,10,1,10,1,10,1,10,1,10,1,10,1, + 11,1,11,1,11,1,11,1,12,1,12,1,12,1,12,1,12,1,12,1,12,1,13,1,13,1, + 13,1,13,1,13,1,13,1,13,1,13,1,13,1,13,1,13,1,13,1,13,1,13,1,14,1, + 14,1,14,1,14,1,14,1,14,1,14,1,14,1,14,1,14,1,14,1,14,1,14,1,14,1, + 14,1,14,1,14,1,14,1,15,1,15,1,15,1,15,1,15,1,15,1,15,1,16,1,16,1, + 17,1,17,1,18,1,18,1,19,4,19,205,8,19,11,19,12,19,206,1,20,1,20,5, + 20,211,8,20,10,20,12,20,214,9,20,1,21,1,21,1,21,5,21,219,8,21,10, + 21,12,21,222,9,21,1,21,1,21,1,22,1,22,1,22,1,22,1,22,1,22,1,22,1, + 22,3,22,234,8,22,1,23,1,23,1,24,1,24,1,24,1,24,5,24,242,8,24,10, + 24,12,24,245,9,24,1,24,1,24,1,25,1,25,1,25,1,25,5,25,253,8,25,10, + 25,12,25,256,9,25,1,25,1,25,1,25,1,25,1,25,1,26,4,26,264,8,26,11, + 26,12,26,265,1,26,1,26,1,254,0,27,1,1,3,2,5,3,7,4,9,5,11,6,13,7, + 15,8,17,9,19,10,21,11,23,12,25,13,27,14,29,15,31,16,33,17,35,18, + 37,19,39,20,41,21,43,22,45,0,47,0,49,23,51,24,53,25,1,0,8,1,0,48, + 57,3,0,65,90,95,95,97,122,4,0,48,57,65,90,95,95,97,122,4,0,10,10, + 13,13,34,34,92,92,8,0,34,34,47,47,92,92,98,98,102,102,110,110,114, + 114,116,116,3,0,48,57,65,70,97,102,2,0,10,10,13,13,3,0,9,10,13,13, + 32,32,274,0,1,1,0,0,0,0,3,1,0,0,0,0,5,1,0,0,0,0,7,1,0,0,0,0,9,1, + 0,0,0,0,11,1,0,0,0,0,13,1,0,0,0,0,15,1,0,0,0,0,17,1,0,0,0,0,19,1, + 0,0,0,0,21,1,0,0,0,0,23,1,0,0,0,0,25,1,0,0,0,0,27,1,0,0,0,0,29,1, + 0,0,0,0,31,1,0,0,0,0,33,1,0,0,0,0,35,1,0,0,0,0,37,1,0,0,0,0,39,1, + 0,0,0,0,41,1,0,0,0,0,43,1,0,0,0,0,49,1,0,0,0,0,51,1,0,0,0,0,53,1, + 0,0,0,1,55,1,0,0,0,3,67,1,0,0,0,5,76,1,0,0,0,7,84,1,0,0,0,9,91,1, + 0,0,0,11,98,1,0,0,0,13,108,1,0,0,0,15,116,1,0,0,0,17,122,1,0,0,0, + 19,133,1,0,0,0,21,140,1,0,0,0,23,147,1,0,0,0,25,151,1,0,0,0,27,158, + 1,0,0,0,29,172,1,0,0,0,31,190,1,0,0,0,33,197,1,0,0,0,35,199,1,0, + 0,0,37,201,1,0,0,0,39,204,1,0,0,0,41,208,1,0,0,0,43,215,1,0,0,0, + 45,225,1,0,0,0,47,235,1,0,0,0,49,237,1,0,0,0,51,248,1,0,0,0,53,263, + 1,0,0,0,55,56,5,113,0,0,56,57,5,117,0,0,57,58,5,105,0,0,58,59,5, + 120,0,0,59,60,5,111,0,0,60,61,5,115,0,0,61,62,5,45,0,0,62,63,5,108, + 0,0,63,64,5,111,0,0,64,65,5,99,0,0,65,66,5,107,0,0,66,2,1,0,0,0, + 67,68,5,102,0,0,68,69,5,114,0,0,69,70,5,97,0,0,70,71,5,103,0,0,71, + 72,5,109,0,0,72,73,5,101,0,0,73,74,5,110,0,0,74,75,5,116,0,0,75, + 4,1,0,0,0,76,77,5,118,0,0,77,78,5,101,0,0,78,79,5,114,0,0,79,80, + 5,115,0,0,80,81,5,105,0,0,81,82,5,111,0,0,82,83,5,110,0,0,83,6,1, + 0,0,0,84,85,5,113,0,0,85,86,5,117,0,0,86,87,5,105,0,0,87,88,5,120, + 0,0,88,89,5,111,0,0,89,90,5,115,0,0,90,8,1,0,0,0,91,92,5,115,0,0, + 92,93,5,111,0,0,93,94,5,117,0,0,94,95,5,114,0,0,95,96,5,99,0,0,96, + 97,5,101,0,0,97,10,1,0,0,0,98,99,5,105,0,0,99,100,5,110,0,0,100, + 101,5,116,0,0,101,102,5,101,0,0,102,103,5,114,0,0,103,104,5,102, + 0,0,104,105,5,97,0,0,105,106,5,99,0,0,106,107,5,101,0,0,107,12,1, + 0,0,0,108,109,5,112,0,0,109,110,5,97,0,0,110,111,5,99,0,0,111,112, + 5,107,0,0,112,113,5,97,0,0,113,114,5,103,0,0,114,115,5,101,0,0,115, + 14,1,0,0,0,116,117,5,98,0,0,117,118,5,117,0,0,118,119,5,105,0,0, + 119,120,5,108,0,0,120,121,5,100,0,0,121,16,1,0,0,0,122,123,5,114, + 0,0,123,124,5,101,0,0,124,125,5,112,0,0,125,126,5,111,0,0,126,127, + 5,115,0,0,127,128,5,105,0,0,128,129,5,116,0,0,129,130,5,111,0,0, + 130,131,5,114,0,0,131,132,5,121,0,0,132,18,1,0,0,0,133,134,5,99, + 0,0,134,135,5,111,0,0,135,136,5,109,0,0,136,137,5,109,0,0,137,138, + 5,105,0,0,138,139,5,116,0,0,139,20,1,0,0,0,140,141,5,112,0,0,141, + 142,5,111,0,0,142,143,5,108,0,0,143,144,5,105,0,0,144,145,5,99,0, + 0,145,146,5,121,0,0,146,22,1,0,0,0,147,148,5,114,0,0,148,149,5,101, + 0,0,149,150,5,102,0,0,150,24,1,0,0,0,151,152,5,112,0,0,152,153,5, + 105,0,0,153,154,5,110,0,0,154,155,5,110,0,0,155,156,5,101,0,0,156, + 157,5,100,0,0,157,26,1,0,0,0,158,159,5,116,0,0,159,160,5,114,0,0, + 160,161,5,97,0,0,161,162,5,99,0,0,162,163,5,107,0,0,163,164,5,45, + 0,0,164,165,5,114,0,0,165,166,5,101,0,0,166,167,5,108,0,0,167,168, + 5,101,0,0,168,169,5,97,0,0,169,170,5,115,0,0,170,171,5,101,0,0,171, + 28,1,0,0,0,172,173,5,116,0,0,173,174,5,114,0,0,174,175,5,97,0,0, + 175,176,5,99,0,0,176,177,5,107,0,0,177,178,5,45,0,0,178,179,5,100, + 0,0,179,180,5,101,0,0,180,181,5,118,0,0,181,182,5,101,0,0,182,183, + 5,108,0,0,183,184,5,111,0,0,184,185,5,112,0,0,185,186,5,109,0,0, + 186,187,5,101,0,0,187,188,5,110,0,0,188,189,5,116,0,0,189,30,1,0, + 0,0,190,191,5,105,0,0,191,192,5,109,0,0,192,193,5,112,0,0,193,194, + 5,111,0,0,194,195,5,114,0,0,195,196,5,116,0,0,196,32,1,0,0,0,197, + 198,5,123,0,0,198,34,1,0,0,0,199,200,5,125,0,0,200,36,1,0,0,0,201, + 202,5,59,0,0,202,38,1,0,0,0,203,205,7,0,0,0,204,203,1,0,0,0,205, + 206,1,0,0,0,206,204,1,0,0,0,206,207,1,0,0,0,207,40,1,0,0,0,208,212, + 7,1,0,0,209,211,7,2,0,0,210,209,1,0,0,0,211,214,1,0,0,0,212,210, + 1,0,0,0,212,213,1,0,0,0,213,42,1,0,0,0,214,212,1,0,0,0,215,220,5, + 34,0,0,216,219,3,45,22,0,217,219,8,3,0,0,218,216,1,0,0,0,218,217, + 1,0,0,0,219,222,1,0,0,0,220,218,1,0,0,0,220,221,1,0,0,0,221,223, + 1,0,0,0,222,220,1,0,0,0,223,224,5,34,0,0,224,44,1,0,0,0,225,233, + 5,92,0,0,226,234,7,4,0,0,227,228,5,117,0,0,228,229,3,47,23,0,229, + 230,3,47,23,0,230,231,3,47,23,0,231,232,3,47,23,0,232,234,1,0,0, + 0,233,226,1,0,0,0,233,227,1,0,0,0,234,46,1,0,0,0,235,236,7,5,0,0, + 236,48,1,0,0,0,237,238,5,47,0,0,238,239,5,47,0,0,239,243,1,0,0,0, + 240,242,8,6,0,0,241,240,1,0,0,0,242,245,1,0,0,0,243,241,1,0,0,0, + 243,244,1,0,0,0,244,246,1,0,0,0,245,243,1,0,0,0,246,247,6,24,0,0, + 247,50,1,0,0,0,248,249,5,47,0,0,249,250,5,42,0,0,250,254,1,0,0,0, + 251,253,9,0,0,0,252,251,1,0,0,0,253,256,1,0,0,0,254,255,1,0,0,0, + 254,252,1,0,0,0,255,257,1,0,0,0,256,254,1,0,0,0,257,258,5,42,0,0, + 258,259,5,47,0,0,259,260,1,0,0,0,260,261,6,25,0,0,261,52,1,0,0,0, + 262,264,7,7,0,0,263,262,1,0,0,0,264,265,1,0,0,0,265,263,1,0,0,0, + 265,266,1,0,0,0,266,267,1,0,0,0,267,268,6,26,0,0,268,54,1,0,0,0, + 9,0,206,212,218,220,233,243,254,265,1,6,0,0 ]; private static __ATN: antlr.ATN; diff --git a/src/resource-lock/generated/QuixosLockParser.ts b/src/resource-lock/generated/QuixosLockParser.ts index 7f413ef..e557640 100644 --- a/src/resource-lock/generated/QuixosLockParser.ts +++ b/src/resource-lock/generated/QuixosLockParser.ts @@ -17,23 +17,24 @@ export class QuixosLockParser extends antlr.Parser { public static readonly SOURCE = 5; public static readonly INTERFACE = 6; public static readonly PACKAGE = 7; - public static readonly REPOSITORY = 8; - public static readonly COMMIT = 9; - public static readonly POLICY = 10; - public static readonly REF = 11; - public static readonly PINNED = 12; - public static readonly TRACK_RELEASE = 13; - public static readonly TRACK_DEVELOPMENT = 14; - public static readonly IMPORT = 15; - public static readonly LBRACE = 16; - public static readonly RBRACE = 17; - public static readonly SEMI = 18; - public static readonly INTEGER = 19; - public static readonly IDENTIFIER = 20; - public static readonly STRING_LITERAL = 21; - public static readonly LINE_COMMENT = 22; - public static readonly BLOCK_COMMENT = 23; - public static readonly WS = 24; + public static readonly BUILD = 8; + public static readonly REPOSITORY = 9; + public static readonly COMMIT = 10; + public static readonly POLICY = 11; + public static readonly REF = 12; + public static readonly PINNED = 13; + public static readonly TRACK_RELEASE = 14; + public static readonly TRACK_DEVELOPMENT = 15; + public static readonly IMPORT = 16; + public static readonly LBRACE = 17; + public static readonly RBRACE = 18; + public static readonly SEMI = 19; + public static readonly INTEGER = 20; + public static readonly IDENTIFIER = 21; + public static readonly STRING_LITERAL = 22; + public static readonly LINE_COMMENT = 23; + public static readonly BLOCK_COMMENT = 24; + public static readonly WS = 25; public static readonly RULE_document = 0; public static readonly RULE_quixosEntry = 1; public static readonly RULE_resourceEntry = 2; @@ -47,17 +48,17 @@ export class QuixosLockParser extends antlr.Parser { public static readonly literalNames = [ null, "'quixos-lock'", "'fragment'", "'version'", "'quixos'", "'source'", - "'interface'", "'package'", "'repository'", "'commit'", "'policy'", - "'ref'", "'pinned'", "'track-release'", "'track-development'", "'import'", - "'{'", "'}'", "';'" + "'interface'", "'package'", "'build'", "'repository'", "'commit'", + "'policy'", "'ref'", "'pinned'", "'track-release'", "'track-development'", + "'import'", "'{'", "'}'", "';'" ]; public static readonly symbolicNames = [ null, "QUIXOS_LOCK", "FRAGMENT", "VERSION", "QUIXOS", "SOURCE", - "INTERFACE", "PACKAGE", "REPOSITORY", "COMMIT", "POLICY", "REF", - "PINNED", "TRACK_RELEASE", "TRACK_DEVELOPMENT", "IMPORT", "LBRACE", - "RBRACE", "SEMI", "INTEGER", "IDENTIFIER", "STRING_LITERAL", "LINE_COMMENT", - "BLOCK_COMMENT", "WS" + "INTERFACE", "PACKAGE", "BUILD", "REPOSITORY", "COMMIT", "POLICY", + "REF", "PINNED", "TRACK_RELEASE", "TRACK_DEVELOPMENT", "IMPORT", + "LBRACE", "RBRACE", "SEMI", "INTEGER", "IDENTIFIER", "STRING_LITERAL", + "LINE_COMMENT", "BLOCK_COMMENT", "WS" ]; public static readonly ruleNames = [ "document", "quixosEntry", "resourceEntry", "importEntry", "resourceKind", @@ -107,7 +108,7 @@ export class QuixosLockParser extends antlr.Parser { this.state = 32; this.errorHandler.sync(this); _la = this.tokenStream.LA(1); - while ((((_la) & ~0x1F) === 0 && ((1 << _la) & 32976) !== 0)) { + while ((((_la) & ~0x1F) === 0 && ((1 << _la) & 66000) !== 0)) { { this.state = 30; this.errorHandler.sync(this); @@ -126,6 +127,7 @@ export class QuixosLockParser extends antlr.Parser { break; case QuixosLockParser.INTERFACE: case QuixosLockParser.PACKAGE: + case QuixosLockParser.BUILD: { this.state = 29; this.resourceEntry(); @@ -250,7 +252,7 @@ export class QuixosLockParser extends antlr.Parser { { this.state = 51; _la = this.tokenStream.LA(1); - if(!(_la === 6 || _la === 7)) { + if(!((((_la) & ~0x1F) === 0 && ((1 << _la) & 448) !== 0))) { this.errorHandler.recoverInline(this); } else { @@ -327,7 +329,7 @@ export class QuixosLockParser extends antlr.Parser { this.state = 73; this.errorHandler.sync(this); _la = this.tokenStream.LA(1); - if (_la === 10) { + if (_la === 11) { { this.state = 66; this.match(QuixosLockParser.POLICY); @@ -376,7 +378,7 @@ export class QuixosLockParser extends antlr.Parser { { this.state = 80; _la = this.tokenStream.LA(1); - if(!((((_la) & ~0x1F) === 0 && ((1 << _la) & 28672) !== 0))) { + if(!((((_la) & ~0x1F) === 0 && ((1 << _la) & 57344) !== 0))) { this.errorHandler.recoverInline(this); } else { @@ -446,31 +448,31 @@ export class QuixosLockParser extends antlr.Parser { } public static readonly _serializedATN: number[] = [ - 4,1,24,87,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7, + 4,1,25,87,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7, 6,2,7,7,7,2,8,7,8,2,9,7,9,1,0,1,0,3,0,23,8,0,1,0,1,0,1,0,1,0,1,0, 1,0,5,0,31,8,0,10,0,12,0,34,9,0,1,0,1,0,1,0,1,1,1,1,1,1,1,1,1,2, 1,2,1,2,1,2,1,2,1,3,1,3,1,3,1,3,1,4,1,4,1,5,1,5,1,5,1,5,1,5,1,5, 1,5,1,5,1,5,1,6,1,6,1,6,1,6,1,6,1,6,1,6,1,6,1,6,1,6,1,6,3,6,74,8, 6,1,6,1,6,1,6,1,6,1,6,1,7,1,7,1,8,1,8,1,9,1,9,1,9,0,0,10,0,2,4,6, - 8,10,12,14,16,18,0,2,1,0,6,7,1,0,12,14,81,0,20,1,0,0,0,2,38,1,0, + 8,10,12,14,16,18,0,2,1,0,6,8,1,0,13,15,81,0,20,1,0,0,0,2,38,1,0, 0,0,4,42,1,0,0,0,6,47,1,0,0,0,8,51,1,0,0,0,10,53,1,0,0,0,12,62,1, 0,0,0,14,80,1,0,0,0,16,82,1,0,0,0,18,84,1,0,0,0,20,22,5,1,0,0,21, 23,5,2,0,0,22,21,1,0,0,0,22,23,1,0,0,0,23,24,1,0,0,0,24,25,5,3,0, - 0,25,26,5,19,0,0,26,32,5,16,0,0,27,31,3,2,1,0,28,31,3,6,3,0,29,31, + 0,25,26,5,20,0,0,26,32,5,17,0,0,27,31,3,2,1,0,28,31,3,6,3,0,29,31, 3,4,2,0,30,27,1,0,0,0,30,28,1,0,0,0,30,29,1,0,0,0,31,34,1,0,0,0, 32,30,1,0,0,0,32,33,1,0,0,0,33,35,1,0,0,0,34,32,1,0,0,0,35,36,5, - 17,0,0,36,37,5,0,0,1,37,1,1,0,0,0,38,39,5,4,0,0,39,40,5,5,0,0,40, + 18,0,0,36,37,5,0,0,1,37,1,1,0,0,0,38,39,5,4,0,0,39,40,5,5,0,0,40, 41,3,12,6,0,41,3,1,0,0,0,42,43,3,8,4,0,43,44,3,16,8,0,44,45,5,5, - 0,0,45,46,3,10,5,0,46,5,1,0,0,0,47,48,5,15,0,0,48,49,3,18,9,0,49, - 50,5,18,0,0,50,7,1,0,0,0,51,52,7,0,0,0,52,9,1,0,0,0,53,54,5,16,0, - 0,54,55,5,8,0,0,55,56,3,18,9,0,56,57,5,18,0,0,57,58,5,9,0,0,58,59, - 3,18,9,0,59,60,5,18,0,0,60,61,5,17,0,0,61,11,1,0,0,0,62,63,5,16, - 0,0,63,64,5,8,0,0,64,65,3,18,9,0,65,73,5,18,0,0,66,67,5,10,0,0,67, - 68,3,14,7,0,68,69,5,18,0,0,69,70,5,11,0,0,70,71,3,18,9,0,71,72,5, - 18,0,0,72,74,1,0,0,0,73,66,1,0,0,0,73,74,1,0,0,0,74,75,1,0,0,0,75, - 76,5,9,0,0,76,77,3,18,9,0,77,78,5,18,0,0,78,79,5,17,0,0,79,13,1, - 0,0,0,80,81,7,1,0,0,81,15,1,0,0,0,82,83,5,20,0,0,83,17,1,0,0,0,84, - 85,5,21,0,0,85,19,1,0,0,0,4,22,30,32,73 + 0,0,45,46,3,10,5,0,46,5,1,0,0,0,47,48,5,16,0,0,48,49,3,18,9,0,49, + 50,5,19,0,0,50,7,1,0,0,0,51,52,7,0,0,0,52,9,1,0,0,0,53,54,5,17,0, + 0,54,55,5,9,0,0,55,56,3,18,9,0,56,57,5,19,0,0,57,58,5,10,0,0,58, + 59,3,18,9,0,59,60,5,19,0,0,60,61,5,18,0,0,61,11,1,0,0,0,62,63,5, + 17,0,0,63,64,5,9,0,0,64,65,3,18,9,0,65,73,5,19,0,0,66,67,5,11,0, + 0,67,68,3,14,7,0,68,69,5,19,0,0,69,70,5,12,0,0,70,71,3,18,9,0,71, + 72,5,19,0,0,72,74,1,0,0,0,73,66,1,0,0,0,73,74,1,0,0,0,74,75,1,0, + 0,0,75,76,5,10,0,0,76,77,3,18,9,0,77,78,5,19,0,0,78,79,5,18,0,0, + 79,13,1,0,0,0,80,81,7,1,0,0,81,15,1,0,0,0,82,83,5,21,0,0,83,17,1, + 0,0,0,84,85,5,22,0,0,85,19,1,0,0,0,4,22,30,32,73 ]; private static __ATN: antlr.ATN; @@ -648,6 +650,9 @@ export class ResourceKindContext extends antlr.ParserRuleContext { public PACKAGE(): antlr.TerminalNode | null { return this.getToken(QuixosLockParser.PACKAGE, 0); } + public BUILD(): antlr.TerminalNode | null { + return this.getToken(QuixosLockParser.BUILD, 0); + } public override get ruleIndex(): number { return QuixosLockParser.RULE_resourceKind; } diff --git a/src/resource-lock/parser.ts b/src/resource-lock/parser.ts index 4e633af..4242635 100644 --- a/src/resource-lock/parser.ts +++ b/src/resource-lock/parser.ts @@ -296,7 +296,11 @@ export const parseQuixosLockDocument = (source: string, fileName = ""): const resources: LockedResource[] = []; const bindings = new Set(); for (const [index, context] of tree.resourceEntry().entries()) { - const kind = context.resourceKind().INTERFACE() ? "interface" : "package"; + const kind = context.resourceKind().INTERFACE() + ? "interface" + : context.resourceKind().BUILD() + ? "build" + : "package"; const binding = context.identifier().getText(); const key = `${kind}\0${binding}`; if (bindings.has(key)) { diff --git a/src/resource-lock/types.ts b/src/resource-lock/types.ts index a7cf809..d397b75 100644 --- a/src/resource-lock/types.ts +++ b/src/resource-lock/types.ts @@ -21,7 +21,7 @@ export type QuixosSource = GitSource & } ); -export type LockedResourceKind = "interface" | "package"; +export type LockedResourceKind = "interface" | "package" | "build"; export type LockedResource = { kind: LockedResourceKind; diff --git a/test/artifact-files.test.ts b/test/artifact-files.test.ts index c77c55b..a8cf42c 100644 --- a/test/artifact-files.test.ts +++ b/test/artifact-files.test.ts @@ -154,3 +154,22 @@ test("transaction process services do not promise generated TypeScript modules", throw Error("No adapter claimed"); }); }); + +test("a remote export group in a mixed package witnesses only its own adapter", async () => { + const { asyncObjectPlan } = await import("./async-fixture.js"); + const { expectedArtifactReceipt } = await import("../src/execution-world/receipts.js"); + const plan = await asyncObjectPlan(); + const fixture = buildArtifactFixture(plan, "async:controller-runtime@1"); + const pkg = plan.definition.packages.find((entry) => entry.revision === fixture.manifest.packageRevisionId)!; + fixture.manifest.implementations = fixture.manifest.implementations.filter( + (entry) => entry.target === "server" && entry.compatibility === "quixos-js-module-v1", + ); + for (const implementation of fixture.manifest.implementations) + implementation.exports = implementation.exports.filter((id) => + pkg.exports.some((entry) => entry.id === id && entry.execution.kind === "remote"), + ); + assert.deepEqual( + expectedArtifactReceipt(plan, fixture.manifest, "a".repeat(64)).receipt.generated.map((file) => file.path), + ["share/quixos/generated/remote.ts"], + ); +}); diff --git a/test/build-dependencies.test.ts b/test/build-dependencies.test.ts new file mode 100644 index 0000000..ccd9f82 --- /dev/null +++ b/test/build-dependencies.test.ts @@ -0,0 +1,76 @@ +import assert from "node:assert/strict"; +import test from "node:test"; +import fs from "node:fs/promises"; +import os from "node:os"; +import path from "node:path"; +import { compileWorkspaceRepository, compileCapabilityResourceRepository } from "../src/capability-language/index.js"; +import { bindingSchema } from "../src/bindings/index.js"; +import { parseQuixosLockDocument } from "../src/resource-lock/index.js"; +import { editStructure } from "../src/capability-language/structural-edits.js"; + +const commit = "a".repeat(40); +const entry = (kind: string, name: string) => + `${kind} ${name} source {repository "https://example.test/${name}.git"; commit "${commit}";}`; +const lock = (entries = "") => + `quixos-lock version 1 {quixos source {repository "https://example.test/quixos.git"; commit "${commit}";} ${entries}}`; + +test("build dependency closures are retained without installing their capability descendants", async (t) => { + const directory = await fs.mkdtemp(path.join(os.tmpdir(), "qx-build-deps-")); + t.after(() => fs.rm(directory, { recursive: true, force: true })); + const write = async (name: string, files: Record) => { + await fs.mkdir(path.join(directory, name)); + for (const [file, text] of Object.entries(files)) await fs.writeFile(path.join(directory, name, file), text); + }; + await write("root", { + "quixos.lock": lock(entry("build", "Library")), + "workspace.qx": `workspace Empty id "empty" revision "empty@1" commit "${commit}" {}`, + }); + await write("Library", { + "quixos.lock": lock(entry("package", "Hidden")), + "types.ts": "export type Label = string;", + }); + await write("Hidden", { + "quixos.lock": lock(entry("interface", "Data")), + "package.qx": 'import interface Data; package Hidden id "hidden" revision "hidden@1" {}', + }); + await write("Data", { "quixos.lock": lock(), "interface.qx": 'interface Data id "data" revision "data@1" {}' }); + const resolveResource = async (source: { repository: string }) => ({ + directory: path.join(directory, new URL(source.repository).pathname.slice(1, -4)), + }); + const compiled = await compileWorkspaceRepository({ rootDirectory: path.join(directory, "root"), resolveResource }); + assert.equal(compiled.resources.length, 3); + assert.deepEqual(compiled.capabilityResources, []); + assert.deepEqual(compiled.workspace.packageImports, []); + assert.deepEqual(compiled.workspace.interfaceImports, []); + assert.deepEqual(bindingSchema(compiled).packages, []); + const library = await compileCapabilityResourceRepository({ + rootDirectory: path.join(directory, "Library"), + kind: "build", + source: { resolver: "git", repository: "https://example.test/Library.git", commit }, + resolveResource, + }); + assert.deepEqual(library.resource, { kind: "build" }); + assert.deepEqual(bindingSchema(library).interfaces, []); + await fs.writeFile(path.join(directory, "Library/quixos.lock"), lock(entry("build", "Library"))); + await assert.rejects( + compileWorkspaceRepository({ rootDirectory: path.join(directory, "root"), resolveResource }), + /dependency cycle/, + ); +}); + +test("build pins retain their kind through parsing and structural updates", () => { + const initial = lock(entry("build", "Library")); + const parsed = parseQuixosLockDocument(initial); + assert.ok(parsed.ok); + assert.equal(parsed.document.resources[0]!.kind, "build"); + const edited = editStructure(initial, { + operation: "dependency", + kind: "build", + name: "Library", + source: { repository: "https://example.test/Library.git", commit: "b".repeat(40) }, + }); + const changed = parseQuixosLockDocument(edited); + assert.ok(changed.ok); + assert.equal(changed.document.resources[0]!.kind, "build"); + assert.equal(changed.document.resources[0]!.source.commit, "b".repeat(40)); +}); diff --git a/test/emit-managed.ts b/test/emit-managed.ts index f5de12c..59c39a7 100644 --- a/test/emit-managed.ts +++ b/test/emit-managed.ts @@ -198,3 +198,24 @@ package Owner id "package:owner" revision "package:owner@1" { } await import("./emit-controllers.js"); + +// Standalone public builder roots must work without opting into the other modes. +for (const kind of ["portable", "service"]) { + const pkg = compileCapabilityResourceSource( + `package Owner id "package:owner" revision "package:owner@1" { + function identity id "identity" : int32 -> record {pid:int32;child:int32;} + execution ${kind === "portable" ? "snapshot targets [browser,server]" : "remote"}; + }`, + { source }, + ); + assert.ok(pkg.ok && pkg.resource.kind === "package", JSON.stringify(pkg.diagnostics)); + const workspace = compileCapabilitySource( + `workspace Simple id "workspace:simple" revision "workspace:simple@1" commit "${source.commit}" {import package Owner;}`, + "workspace.qx", + { packages: new Map([["Owner", pkg.resource.revision]]) }, + ); + assert.ok(workspace.ok, JSON.stringify(workspace.diagnostics)); + const directory = `dist/managed/standalone-${kind}`; + await mkdir(directory, { recursive: true }); + await writeFile(`${directory}/execution-plan.json`, JSON.stringify(compileExecutionPlan(workspace.workspace))); +} diff --git a/test/pin-upgrades.test.ts b/test/pin-upgrades.test.ts index f6e30ef..026a733 100644 --- a/test/pin-upgrades.test.ts +++ b/test/pin-upgrades.test.ts @@ -76,106 +76,112 @@ test( }, ); -test("pin upgrades publish children before parent locks and resume without republishing completed nodes", async (context) => { - const workbench = await fs.mkdtemp(path.join(os.tmpdir(), "qx-upgrade-test-")); - context.after(() => fs.rm(workbench, { recursive: true, force: true })); - const from = "a".repeat(40), - to = "b".repeat(40), - framework = "c".repeat(40); - const sources = [ - { - kind: "workspace" as const, - directory: "root", - source: { repository: "https://example.test/workspace.git", commit: from }, - }, - { - kind: "interface" as const, - directory: "resources/Named", - source: { repository: "https://example.test/named.git", commit: from }, - }, - ]; - const lock = `quixos-lock version 1 { quixos source { repository "https://example.test/quixos.git"; commit "${framework}"; }`; - for (const node of sources) { - const directory = path.join(workbench, node.directory); - await fs.mkdir(directory, { recursive: true }); - await execFile("git", ["-C", directory, "init"]); - await execFile("git", ["-C", directory, "remote", "add", "origin", node.source.repository]); - await fs.writeFile(path.join(directory, ".gitignore"), ".quixos/\n"); +for (const dependencyKind of ["interface", "build"] as const) + test(`${dependencyKind} pin upgrades publish children before parent locks and resume without republishing completed nodes`, async (context) => { + const workbench = await fs.mkdtemp(path.join(os.tmpdir(), "qx-upgrade-test-")); + context.after(() => fs.rm(workbench, { recursive: true, force: true })); + const from = "a".repeat(40), + to = "b".repeat(40), + framework = "c".repeat(40); + const sources = [ + { + kind: "workspace" as const, + directory: "root", + source: { repository: "https://example.test/workspace.git", commit: from }, + }, + { + kind: dependencyKind, + directory: "resources/Named", + source: { repository: "https://example.test/named.git", commit: from }, + }, + ]; + const lock = `quixos-lock version 1 { quixos source { repository "https://example.test/quixos.git"; commit "${framework}"; }`; + for (const node of sources) { + const directory = path.join(workbench, node.directory); + await fs.mkdir(directory, { recursive: true }); + await execFile("git", ["-C", directory, "init"]); + await execFile("git", ["-C", directory, "remote", "add", "origin", node.source.repository]); + await fs.writeFile(path.join(directory, ".gitignore"), ".quixos/\n"); + await fs.writeFile( + path.join(directory, "quixos.lock"), + lock + + (node.kind === "workspace" + ? ` ${dependencyKind} Named source { repository "${sources[1].source.repository}"; commit "${from}"; }` + : "") + + " }", + ); + } await fs.writeFile( - path.join(directory, "quixos.lock"), - lock + - (node.kind === "workspace" - ? ` interface Named source { repository "${sources[1].source.repository}"; commit "${from}"; }` - : "") + - " }", + path.join( + workbench, + dependencyKind === "interface" ? "resources/Named/interface.qx" : "resources/Named/types.ts", + ), + dependencyKind === "interface" + ? 'interface Named id "interface:named" revision "interface:named@1" { value name id "member:name" : string { get id "op:get"; } }' + : "export type Name = string;", ); - } - await fs.writeFile( - path.join(workbench, "resources/Named/interface.qx"), - 'interface Named id "interface:named" revision "interface:named@1" { value name id "member:name" : string { get id "op:get"; } }', - ); - await fs.writeFile( - path.join(workbench, "root/workspace.qx"), - `workspace W id "workspace:w" revision "workspace:w@1" commit "${from}" { import interface Named; atom A id "atom:a"; }`, - ); - const snapshotMap = path.join(workbench, "snapshots.json"); - await fs.writeFile( - snapshotMap, - JSON.stringify({ - resources: [ - { - kind: "interface", - repository: sources[1].source.repository, - commit: to, - directory: path.join(workbench, "resources/Named"), - }, - ], - }), - ); - const oldMap = process.env.QUIXOS_SNAPSHOT_MAP; - process.env.QUIXOS_SNAPSHOT_MAP = snapshotMap; - context.after(() => { - if (oldMap === undefined) delete process.env.QUIXOS_SNAPSHOT_MAP; - else process.env.QUIXOS_SNAPSHOT_MAP = oldMap; + await fs.writeFile( + path.join(workbench, "root/workspace.qx"), + `workspace W id "workspace:w" revision "workspace:w@1" commit "${from}" { ${dependencyKind === "interface" ? "import interface Named;" : ""} atom A id "atom:a"; }`, + ); + const snapshotMap = path.join(workbench, "snapshots.json"); + await fs.writeFile( + snapshotMap, + JSON.stringify({ + resources: [ + { + kind: dependencyKind, + repository: sources[1].source.repository, + commit: to, + directory: path.join(workbench, "resources/Named"), + }, + ], + }), + ); + const oldMap = process.env.QUIXOS_SNAPSHOT_MAP; + process.env.QUIXOS_SNAPSHOT_MAP = snapshotMap; + context.after(() => { + if (oldMap === undefined) delete process.env.QUIXOS_SNAPSHOT_MAP; + else process.env.QUIXOS_SNAPSHOT_MAP = oldMap; + }); + const plan = await planPinUpgrades(workbench, { nodes: sources }); + await fs.mkdir(path.join(workbench, ".quixos"), { recursive: true }); + await fs.writeFile( + path.join(workbench, ".quixos/resource-graph.json"), + JSON.stringify({ resources: [{ ...sources[1], source: { resolver: "git", ...sources[1].source } }] }), + ); + assert.deepEqual( + plan.nodes.map((node) => node.directory), + ["resources/Named", "root"], + ); + let fail = true; + const published: string[] = []; + const effects: UpgradeEffects = { + check: async (node) => { + if (node.kind === "workspace" && fail) throw new Error("refactor required"); + }, + snapshot: async () => to, + publish: async (root) => { + published.push(path.relative(workbench, root)); + }, + }; + await assert.rejects(() => applyPinUpgrades(plan, undefined, effects), /refactor required/); + assert.deepEqual(published, ["resources/Named"]); + assert.match(await fs.readFile(path.join(workbench, "root/quixos.lock"), "utf8"), new RegExp(to)); + const id = (await fs.readdir(path.join(workbench, ".quixos/upgrades"))) + .find((name) => name.endsWith(".json"))! + .slice(0, -5); + fail = false; + await fs.appendFile(path.join(workbench, "root/workspace.qx"), "\n// explicit refactor\n"); + await assert.rejects(() => applyPinUpgrades(plan, id, effects), /accept-edits/); + const result = await applyPinUpgrades(plan, id, effects, { acceptEdits: true }); + assert.equal(result.activated, false); + assert.deepEqual(published, ["resources/Named", "root"]); + const graph = JSON.parse(await fs.readFile(path.join(workbench, ".quixos/resource-graph.json"), "utf8")); + assert.equal(graph.resources.length, 1); + assert.equal(graph.resources[0].source.commit, to); + const next = await planPinUpgrades(workbench, { + nodes: [sources[0], { ...sources[1], source: graph.resources[0].source }], + }); + assert.deepEqual(next.nodes.find((node) => node.kind === "workspace")!.dependencies, ["resources/Named"]); }); - const plan = await planPinUpgrades(workbench, { nodes: sources }); - await fs.mkdir(path.join(workbench, ".quixos"), { recursive: true }); - await fs.writeFile( - path.join(workbench, ".quixos/resource-graph.json"), - JSON.stringify({ resources: [{ ...sources[1], source: { resolver: "git", ...sources[1].source } }] }), - ); - assert.deepEqual( - plan.nodes.map((node) => node.directory), - ["resources/Named", "root"], - ); - let fail = true; - const published: string[] = []; - const effects: UpgradeEffects = { - check: async (node) => { - if (node.kind === "workspace" && fail) throw new Error("refactor required"); - }, - snapshot: async () => to, - publish: async (root) => { - published.push(path.relative(workbench, root)); - }, - }; - await assert.rejects(() => applyPinUpgrades(plan, undefined, effects), /refactor required/); - assert.deepEqual(published, ["resources/Named"]); - assert.match(await fs.readFile(path.join(workbench, "root/quixos.lock"), "utf8"), new RegExp(to)); - const id = (await fs.readdir(path.join(workbench, ".quixos/upgrades"))) - .find((name) => name.endsWith(".json"))! - .slice(0, -5); - fail = false; - await fs.appendFile(path.join(workbench, "root/workspace.qx"), "\n// explicit refactor\n"); - await assert.rejects(() => applyPinUpgrades(plan, id, effects), /accept-edits/); - const result = await applyPinUpgrades(plan, id, effects, { acceptEdits: true }); - assert.equal(result.activated, false); - assert.deepEqual(published, ["resources/Named", "root"]); - const graph = JSON.parse(await fs.readFile(path.join(workbench, ".quixos/resource-graph.json"), "utf8")); - assert.equal(graph.resources.length, 1); - assert.equal(graph.resources[0].source.commit, to); - const next = await planPinUpgrades(workbench, { - nodes: [sources[0], { ...sources[1], source: graph.resources[0].source }], - }); - assert.deepEqual(next.nodes.find((node) => node.kind === "workspace")!.dependencies, ["resources/Named"]); -});