Publish quixos-protocol from b384206b9c01a9ac50030a583d028b71291bc8c5

This commit is contained in:
Quixos Subtree Publisher
2026-09-06 07:07:06 +00:00
15 changed files with 671 additions and 206 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"version": 1, "version": 1,
"sourceRepo": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos.git", "sourceRepo": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos.git",
"sourceCommit": "33266c4ba9e0dd7b6370715522b281807e8b038b", "sourceCommit": "b384206b9c01a9ac50030a583d028b71291bc8c5",
"sourcePath": "quixos-protocol", "sourcePath": "quixos-protocol",
"exportName": "quixos-protocol", "exportName": "quixos-protocol",
"mirrorRemote": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos-protocol.git" "mirrorRemote": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos-protocol.git"
+17 -6
View File
@@ -45,11 +45,20 @@ from v1.
## Repository locks ## Repository locks
Every workspace, interface, and package repository carries a `quixos.lock`. Every workspace, interface, and package repository carries a `quixos.lock`.
This is not a miniature workspace: a resource lock is only a Quixos toolchain A resource lock is not a miniature workspace: it contains only the exact
pin plus a dependency list. It pins exact Git sources for the interfaces and Quixos commit that resource was authored against plus its dependency list.
packages named by that resource's own manifest. The v1 Git source is deliberately only a repository It also pins exact Git sources for interfaces and packages named by that
URL and full commit ID; the publisher-owned reachability tag and Nix fetch resource's own manifest. Resource Git sources are deliberately only a
details are derived from those values. repository URL and full commit ID; the publisher-owned reachability tag and
Nix fetch details are derived from those values.
A workspace root additionally records its Quixos selection policy and ref.
Its `commit` is the exact compatibility baseline shared by the resource graph,
not necessarily the runtime candidate. `pinned` requires the ref, baseline,
and candidate to be one commit. `track-development` lets Central resolve the
named development ref to a newer candidate while preserving the authored
baseline. `track-release` is reserved for compatibility-filtered release-line
advancement and is not implemented yet.
```sh ```sh
quixos-lock-check quixos.lock quixos-lock-check quixos.lock
@@ -58,7 +67,7 @@ quixos-resource-compile \
--repository https://repos.quixos.org/example/package-example.git \ --repository https://repos.quixos.org/example/package-example.git \
--commit 1111111111111111111111111111111111111111 \ --commit 1111111111111111111111111111111111111111 \
--checkout-root /tmp/quixos-resource-dependencies --checkout-root /tmp/quixos-resource-dependencies
qx resource publish qx-workspace resource publish
``` ```
The resource compiler validates the local manifest against the recursively The resource compiler validates the local manifest against the recursively
@@ -74,6 +83,8 @@ A workspace root may split its resource pins into same-repository fragments:
quixos-lock version 1 { quixos-lock version 1 {
quixos source { quixos source {
repository "https://repos.quixos.org/quixos/quixos.git"; repository "https://repos.quixos.org/quixos/quixos.git";
policy track-development;
ref "dev/alice/main";
commit "1111111111111111111111111111111111111111"; commit "1111111111111111111111111111111111111111";
} }
import "locks/web-studio.lock"; import "locks/web-studio.lock";
+20 -1
View File
@@ -6,7 +6,7 @@ document
; ;
quixosEntry quixosEntry
: QUIXOS SOURCE sourceBlock : QUIXOS SOURCE quixosSourceBlock
; ;
resourceEntry resourceEntry
@@ -29,6 +29,20 @@ sourceBlock
RBRACE RBRACE
; ;
quixosSourceBlock
: LBRACE
REPOSITORY stringLiteral SEMI
(POLICY sourcePolicy SEMI REF stringLiteral SEMI)?
COMMIT stringLiteral SEMI
RBRACE
;
sourcePolicy
: PINNED
| TRACK_RELEASE
| TRACK_DEVELOPMENT
;
identifier identifier
: IDENTIFIER : IDENTIFIER
; ;
@@ -46,6 +60,11 @@ INTERFACE: 'interface';
PACKAGE: 'package'; PACKAGE: 'package';
REPOSITORY: 'repository'; REPOSITORY: 'repository';
COMMIT: 'commit'; COMMIT: 'commit';
POLICY: 'policy';
REF: 'ref';
PINNED: 'pinned';
TRACK_RELEASE: 'track-release';
TRACK_DEVELOPMENT: 'track-development';
IMPORT: 'import'; IMPORT: 'import';
LBRACE: '{'; LBRACE: '{';
+6
View File
@@ -190,6 +190,12 @@ const createResourceGraphResolver = (
if (!lockResult.ok) { if (!lockResult.ok) {
throw new Error(diagnosticsMessage(`${locked.kind} ${locked.binding} lock`, lockResult.diagnostics)); throw new Error(diagnosticsMessage(`${locked.kind} ${locked.binding} lock`, lockResult.diagnostics));
} }
if (lockResult.lock.quixos.policy) {
throw new Error(
`${locked.kind} ${locked.binding} lock declares workspace Quixos policy ` +
`${lockResult.lock.quixos.policy}; resource locks may only declare their exact authored-against commit`,
);
}
if (lockResult.lock.quixos.commit.toLowerCase() !== quixosCommit.toLowerCase()) { if (lockResult.lock.quixos.commit.toLowerCase() !== quixosCommit.toLowerCase()) {
throw new Error( throw new Error(
`${locked.kind} ${locked.binding} selects Quixos ${lockResult.lock.quixos.commit}, ` + `${locked.kind} ${locked.binding} selects Quixos ${lockResult.lock.quixos.commit}, ` +
+13 -1
View File
@@ -9,6 +9,11 @@ null
'package' 'package'
'repository' 'repository'
'commit' 'commit'
'policy'
'ref'
'pinned'
'track-release'
'track-development'
'import' 'import'
'{' '{'
'}' '}'
@@ -31,6 +36,11 @@ INTERFACE
PACKAGE PACKAGE
REPOSITORY REPOSITORY
COMMIT COMMIT
POLICY
REF
PINNED
TRACK_RELEASE
TRACK_DEVELOPMENT
IMPORT IMPORT
LBRACE LBRACE
RBRACE RBRACE
@@ -49,9 +59,11 @@ resourceEntry
importEntry importEntry
resourceKind resourceKind
sourceBlock sourceBlock
quixosSourceBlock
sourcePolicy
identifier identifier
stringLiteral stringLiteral
atn: atn:
[4, 1, 19, 63, 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, 1, 0, 1, 0, 3, 0, 19, 8, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 5, 0, 27, 8, 0, 10, 0, 12, 0, 30, 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, 7, 1, 7, 1, 7, 0, 0, 8, 0, 2, 4, 6, 8, 10, 12, 14, 0, 1, 1, 0, 6, 7, 58, 0, 16, 1, 0, 0, 0, 2, 34, 1, 0, 0, 0, 4, 38, 1, 0, 0, 0, 6, 43, 1, 0, 0, 0, 8, 47, 1, 0, 0, 0, 10, 49, 1, 0, 0, 0, 12, 58, 1, 0, 0, 0, 14, 60, 1, 0, 0, 0, 16, 18, 5, 1, 0, 0, 17, 19, 5, 2, 0, 0, 18, 17, 1, 0, 0, 0, 18, 19, 1, 0, 0, 0, 19, 20, 1, 0, 0, 0, 20, 21, 5, 3, 0, 0, 21, 22, 5, 14, 0, 0, 22, 28, 5, 11, 0, 0, 23, 27, 3, 2, 1, 0, 24, 27, 3, 6, 3, 0, 25, 27, 3, 4, 2, 0, 26, 23, 1, 0, 0, 0, 26, 24, 1, 0, 0, 0, 26, 25, 1, 0, 0, 0, 27, 30, 1, 0, 0, 0, 28, 26, 1, 0, 0, 0, 28, 29, 1, 0, 0, 0, 29, 31, 1, 0, 0, 0, 30, 28, 1, 0, 0, 0, 31, 32, 5, 12, 0, 0, 32, 33, 5, 0, 0, 1, 33, 1, 1, 0, 0, 0, 34, 35, 5, 4, 0, 0, 35, 36, 5, 5, 0, 0, 36, 37, 3, 10, 5, 0, 37, 3, 1, 0, 0, 0, 38, 39, 3, 8, 4, 0, 39, 40, 3, 12, 6, 0, 40, 41, 5, 5, 0, 0, 41, 42, 3, 10, 5, 0, 42, 5, 1, 0, 0, 0, 43, 44, 5, 10, 0, 0, 44, 45, 3, 14, 7, 0, 45, 46, 5, 13, 0, 0, 46, 7, 1, 0, 0, 0, 47, 48, 7, 0, 0, 0, 48, 9, 1, 0, 0, 0, 49, 50, 5, 11, 0, 0, 50, 51, 5, 8, 0, 0, 51, 52, 3, 14, 7, 0, 52, 53, 5, 13, 0, 0, 53, 54, 5, 9, 0, 0, 54, 55, 3, 14, 7, 0, 55, 56, 5, 13, 0, 0, 56, 57, 5, 12, 0, 0, 57, 11, 1, 0, 0, 0, 58, 59, 5, 15, 0, 0, 59, 13, 1, 0, 0, 0, 60, 61, 5, 16, 0, 0, 61, 15, 1, 0, 0, 0, 3, 18, 26, 28] [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]
+24 -14
View File
@@ -7,16 +7,21 @@ INTERFACE=6
PACKAGE=7 PACKAGE=7
REPOSITORY=8 REPOSITORY=8
COMMIT=9 COMMIT=9
IMPORT=10 POLICY=10
LBRACE=11 REF=11
RBRACE=12 PINNED=12
SEMI=13 TRACK_RELEASE=13
INTEGER=14 TRACK_DEVELOPMENT=14
IDENTIFIER=15 IMPORT=15
STRING_LITERAL=16 LBRACE=16
LINE_COMMENT=17 RBRACE=17
BLOCK_COMMENT=18 SEMI=18
WS=19 INTEGER=19
IDENTIFIER=20
STRING_LITERAL=21
LINE_COMMENT=22
BLOCK_COMMENT=23
WS=24
'quixos-lock'=1 'quixos-lock'=1
'fragment'=2 'fragment'=2
'version'=3 'version'=3
@@ -26,7 +31,12 @@ WS=19
'package'=7 'package'=7
'repository'=8 'repository'=8
'commit'=9 'commit'=9
'import'=10 'policy'=10
'{'=11 'ref'=11
'}'=12 'pinned'=12
';'=13 'track-release'=13
'track-development'=14
'import'=15
'{'=16
'}'=17
';'=18
File diff suppressed because one or more lines are too long
@@ -7,16 +7,21 @@ INTERFACE=6
PACKAGE=7 PACKAGE=7
REPOSITORY=8 REPOSITORY=8
COMMIT=9 COMMIT=9
IMPORT=10 POLICY=10
LBRACE=11 REF=11
RBRACE=12 PINNED=12
SEMI=13 TRACK_RELEASE=13
INTEGER=14 TRACK_DEVELOPMENT=14
IDENTIFIER=15 IMPORT=15
STRING_LITERAL=16 LBRACE=16
LINE_COMMENT=17 RBRACE=17
BLOCK_COMMENT=18 SEMI=18
WS=19 INTEGER=19
IDENTIFIER=20
STRING_LITERAL=21
LINE_COMMENT=22
BLOCK_COMMENT=23
WS=24
'quixos-lock'=1 'quixos-lock'=1
'fragment'=2 'fragment'=2
'version'=3 'version'=3
@@ -26,7 +31,12 @@ WS=19
'package'=7 'package'=7
'repository'=8 'repository'=8
'commit'=9 'commit'=9
'import'=10 'policy'=10
'{'=11 'ref'=11
'}'=12 'pinned'=12
';'=13 'track-release'=13
'track-development'=14
'import'=15
'{'=16
'}'=17
';'=18
+114 -84
View File
@@ -13,16 +13,21 @@ export class QuixosLockLexer extends antlr.Lexer {
public static readonly PACKAGE = 7; public static readonly PACKAGE = 7;
public static readonly REPOSITORY = 8; public static readonly REPOSITORY = 8;
public static readonly COMMIT = 9; public static readonly COMMIT = 9;
public static readonly IMPORT = 10; public static readonly POLICY = 10;
public static readonly LBRACE = 11; public static readonly REF = 11;
public static readonly RBRACE = 12; public static readonly PINNED = 12;
public static readonly SEMI = 13; public static readonly TRACK_RELEASE = 13;
public static readonly INTEGER = 14; public static readonly TRACK_DEVELOPMENT = 14;
public static readonly IDENTIFIER = 15; public static readonly IMPORT = 15;
public static readonly STRING_LITERAL = 16; public static readonly LBRACE = 16;
public static readonly LINE_COMMENT = 17; public static readonly RBRACE = 17;
public static readonly BLOCK_COMMENT = 18; public static readonly SEMI = 18;
public static readonly WS = 19; 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 channelNames = [ public static readonly channelNames = [
"DEFAULT_TOKEN_CHANNEL", "HIDDEN" "DEFAULT_TOKEN_CHANNEL", "HIDDEN"
@@ -30,13 +35,15 @@ export class QuixosLockLexer extends antlr.Lexer {
public static readonly literalNames = [ public static readonly literalNames = [
null, "'quixos-lock'", "'fragment'", "'version'", "'quixos'", "'source'", null, "'quixos-lock'", "'fragment'", "'version'", "'quixos'", "'source'",
"'interface'", "'package'", "'repository'", "'commit'", "'import'", "'interface'", "'package'", "'repository'", "'commit'", "'policy'",
"'ref'", "'pinned'", "'track-release'", "'track-development'", "'import'",
"'{'", "'}'", "';'" "'{'", "'}'", "';'"
]; ];
public static readonly symbolicNames = [ public static readonly symbolicNames = [
null, "QUIXOS_LOCK", "FRAGMENT", "VERSION", "QUIXOS", "SOURCE", null, "QUIXOS_LOCK", "FRAGMENT", "VERSION", "QUIXOS", "SOURCE",
"INTERFACE", "PACKAGE", "REPOSITORY", "COMMIT", "IMPORT", "LBRACE", "INTERFACE", "PACKAGE", "REPOSITORY", "COMMIT", "POLICY", "REF",
"PINNED", "TRACK_RELEASE", "TRACK_DEVELOPMENT", "IMPORT", "LBRACE",
"RBRACE", "SEMI", "INTEGER", "IDENTIFIER", "STRING_LITERAL", "LINE_COMMENT", "RBRACE", "SEMI", "INTEGER", "IDENTIFIER", "STRING_LITERAL", "LINE_COMMENT",
"BLOCK_COMMENT", "WS" "BLOCK_COMMENT", "WS"
]; ];
@@ -47,9 +54,10 @@ export class QuixosLockLexer extends antlr.Lexer {
public static readonly ruleNames = [ public static readonly ruleNames = [
"QUIXOS_LOCK", "FRAGMENT", "VERSION", "QUIXOS", "SOURCE", "INTERFACE", "QUIXOS_LOCK", "FRAGMENT", "VERSION", "QUIXOS", "SOURCE", "INTERFACE",
"PACKAGE", "REPOSITORY", "COMMIT", "IMPORT", "LBRACE", "RBRACE", "PACKAGE", "REPOSITORY", "COMMIT", "POLICY", "REF", "PINNED", "TRACK_RELEASE",
"SEMI", "INTEGER", "IDENTIFIER", "STRING_LITERAL", "ESC", "HEX", "TRACK_DEVELOPMENT", "IMPORT", "LBRACE", "RBRACE", "SEMI", "INTEGER",
"LINE_COMMENT", "BLOCK_COMMENT", "WS", "IDENTIFIER", "STRING_LITERAL", "ESC", "HEX", "LINE_COMMENT", "BLOCK_COMMENT",
"WS",
]; ];
@@ -71,77 +79,99 @@ export class QuixosLockLexer extends antlr.Lexer {
public get modeNames(): string[] { return QuixosLockLexer.modeNames; } public get modeNames(): string[] { return QuixosLockLexer.modeNames; }
public static readonly _serializedATN: number[] = [ public static readonly _serializedATN: number[] = [
4,0,19,201,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,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, 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, 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,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, 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,
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, 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,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,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,
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, 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,
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, 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,
1,8,1,8,1,9,1,9,1,9,1,9,1,9,1,9,1,9,1,10,1,10,1,11,1,11,1,12,1,12, 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,
1,13,4,13,137,8,13,11,13,12,13,138,1,14,1,14,5,14,143,8,14,10,14, 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,
12,14,146,9,14,1,15,1,15,1,15,5,15,151,8,15,10,15,12,15,154,9,15, 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,
1,15,1,15,1,16,1,16,1,16,1,16,1,16,1,16,1,16,1,16,3,16,166,8,16, 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,
1,17,1,17,1,18,1,18,1,18,1,18,5,18,174,8,18,10,18,12,18,177,9,18, 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,
1,18,1,18,1,19,1,19,1,19,1,19,5,19,185,8,19,10,19,12,19,188,9,19, 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,
1,19,1,19,1,19,1,19,1,19,1,20,4,20,196,8,20,11,20,12,20,197,1,20, 18,12,18,198,1,19,1,19,5,19,203,8,19,10,19,12,19,206,9,19,1,20,1,
1,20,1,186,0,21,1,1,3,2,5,3,7,4,9,5,11,6,13,7,15,8,17,9,19,10,21, 20,1,20,5,20,211,8,20,10,20,12,20,214,9,20,1,20,1,20,1,21,1,21,1,
11,23,12,25,13,27,14,29,15,31,16,33,0,35,0,37,17,39,18,41,19,1,0, 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,
8,1,0,48,57,3,0,65,90,95,95,97,122,4,0,48,57,65,90,95,95,97,122, 23,1,23,5,23,234,8,23,10,23,12,23,237,9,23,1,23,1,23,1,24,1,24,1,
4,0,10,10,13,13,34,34,92,92,8,0,34,34,47,47,92,92,98,98,102,102, 24,1,24,5,24,245,8,24,10,24,12,24,248,9,24,1,24,1,24,1,24,1,24,1,
110,110,114,114,116,116,3,0,48,57,65,70,97,102,2,0,10,10,13,13,3, 24,1,25,4,25,256,8,25,11,25,12,25,257,1,25,1,25,1,246,0,26,1,1,3,
0,9,10,13,13,32,32,206,0,1,1,0,0,0,0,3,1,0,0,0,0,5,1,0,0,0,0,7,1, 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,
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, 29,15,31,16,33,17,35,18,37,19,39,20,41,21,43,0,45,0,47,22,49,23,
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, 51,24,1,0,8,1,0,48,57,3,0,65,90,95,95,97,122,4,0,48,57,65,90,95,
0,0,0,0,29,1,0,0,0,0,31,1,0,0,0,0,37,1,0,0,0,0,39,1,0,0,0,0,41,1, 95,97,122,4,0,10,10,13,13,34,34,92,92,8,0,34,34,47,47,92,92,98,98,
0,0,0,1,43,1,0,0,0,3,55,1,0,0,0,5,64,1,0,0,0,7,72,1,0,0,0,9,79,1, 102,102,110,110,114,114,116,116,3,0,48,57,65,70,97,102,2,0,10,10,
0,0,0,11,86,1,0,0,0,13,96,1,0,0,0,15,104,1,0,0,0,17,115,1,0,0,0, 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,
19,122,1,0,0,0,21,129,1,0,0,0,23,131,1,0,0,0,25,133,1,0,0,0,27,136, 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,
1,0,0,0,29,140,1,0,0,0,31,147,1,0,0,0,33,157,1,0,0,0,35,167,1,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,0,37,169,1,0,0,0,39,180,1,0,0,0,41,195,1,0,0,0,43,44,5,113,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,
44,45,5,117,0,0,45,46,5,105,0,0,46,47,5,120,0,0,47,48,5,111,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,
48,49,5,115,0,0,49,50,5,45,0,0,50,51,5,108,0,0,51,52,5,111,0,0,52, 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,
53,5,99,0,0,53,54,5,107,0,0,54,2,1,0,0,0,55,56,5,102,0,0,56,57,5, 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,
114,0,0,57,58,5,97,0,0,58,59,5,103,0,0,59,60,5,109,0,0,60,61,5,101, 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,61,62,5,110,0,0,62,63,5,116,0,0,63,4,1,0,0,0,64,65,5,118,0,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,
65,66,5,101,0,0,66,67,5,114,0,0,67,68,5,115,0,0,68,69,5,105,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,
69,70,5,111,0,0,70,71,5,110,0,0,71,6,1,0,0,0,72,73,5,113,0,0,73, 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,
74,5,117,0,0,74,75,5,105,0,0,75,76,5,120,0,0,76,77,5,111,0,0,77, 0,0,53,54,5,113,0,0,54,55,5,117,0,0,55,56,5,105,0,0,56,57,5,120,
78,5,115,0,0,78,8,1,0,0,0,79,80,5,115,0,0,80,81,5,111,0,0,81,82, 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,
5,117,0,0,82,83,5,114,0,0,83,84,5,99,0,0,84,85,5,101,0,0,85,10,1, 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,
0,0,0,86,87,5,105,0,0,87,88,5,110,0,0,88,89,5,116,0,0,89,90,5,101, 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,
0,0,90,91,5,114,0,0,91,92,5,102,0,0,92,93,5,97,0,0,93,94,5,99,0, 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,94,95,5,101,0,0,95,12,1,0,0,0,96,97,5,112,0,0,97,98,5,97,0,0,98, 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,
99,5,99,0,0,99,100,5,107,0,0,100,101,5,97,0,0,101,102,5,103,0,0, 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,
102,103,5,101,0,0,103,14,1,0,0,0,104,105,5,114,0,0,105,106,5,101, 82,83,5,113,0,0,83,84,5,117,0,0,84,85,5,105,0,0,85,86,5,120,0,0,
0,0,106,107,5,112,0,0,107,108,5,111,0,0,108,109,5,115,0,0,109,110, 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,
5,105,0,0,110,111,5,116,0,0,111,112,5,111,0,0,112,113,5,114,0,0, 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,
113,114,5,121,0,0,114,16,1,0,0,0,115,116,5,99,0,0,116,117,5,111, 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,
0,0,117,118,5,109,0,0,118,119,5,109,0,0,119,120,5,105,0,0,120,121, 116,0,0,99,100,5,101,0,0,100,101,5,114,0,0,101,102,5,102,0,0,102,
5,116,0,0,121,18,1,0,0,0,122,123,5,105,0,0,123,124,5,109,0,0,124, 103,5,97,0,0,103,104,5,99,0,0,104,105,5,101,0,0,105,12,1,0,0,0,106,
125,5,112,0,0,125,126,5,111,0,0,126,127,5,114,0,0,127,128,5,116, 107,5,112,0,0,107,108,5,97,0,0,108,109,5,99,0,0,109,110,5,107,0,
0,0,128,20,1,0,0,0,129,130,5,123,0,0,130,22,1,0,0,0,131,132,5,125, 0,110,111,5,97,0,0,111,112,5,103,0,0,112,113,5,101,0,0,113,14,1,
0,0,132,24,1,0,0,0,133,134,5,59,0,0,134,26,1,0,0,0,135,137,7,0,0, 0,0,0,114,115,5,114,0,0,115,116,5,101,0,0,116,117,5,112,0,0,117,
0,136,135,1,0,0,0,137,138,1,0,0,0,138,136,1,0,0,0,138,139,1,0,0, 118,5,111,0,0,118,119,5,115,0,0,119,120,5,105,0,0,120,121,5,116,
0,139,28,1,0,0,0,140,144,7,1,0,0,141,143,7,2,0,0,142,141,1,0,0,0, 0,0,121,122,5,111,0,0,122,123,5,114,0,0,123,124,5,121,0,0,124,16,
143,146,1,0,0,0,144,142,1,0,0,0,144,145,1,0,0,0,145,30,1,0,0,0,146, 1,0,0,0,125,126,5,99,0,0,126,127,5,111,0,0,127,128,5,109,0,0,128,
144,1,0,0,0,147,152,5,34,0,0,148,151,3,33,16,0,149,151,8,3,0,0,150, 129,5,109,0,0,129,130,5,105,0,0,130,131,5,116,0,0,131,18,1,0,0,0,
148,1,0,0,0,150,149,1,0,0,0,151,154,1,0,0,0,152,150,1,0,0,0,152, 132,133,5,112,0,0,133,134,5,111,0,0,134,135,5,108,0,0,135,136,5,
153,1,0,0,0,153,155,1,0,0,0,154,152,1,0,0,0,155,156,5,34,0,0,156, 105,0,0,136,137,5,99,0,0,137,138,5,121,0,0,138,20,1,0,0,0,139,140,
32,1,0,0,0,157,165,5,92,0,0,158,166,7,4,0,0,159,160,5,117,0,0,160, 5,114,0,0,140,141,5,101,0,0,141,142,5,102,0,0,142,22,1,0,0,0,143,
161,3,35,17,0,161,162,3,35,17,0,162,163,3,35,17,0,163,164,3,35,17, 144,5,112,0,0,144,145,5,105,0,0,145,146,5,110,0,0,146,147,5,110,
0,164,166,1,0,0,0,165,158,1,0,0,0,165,159,1,0,0,0,166,34,1,0,0,0, 0,0,147,148,5,101,0,0,148,149,5,100,0,0,149,24,1,0,0,0,150,151,5,
167,168,7,5,0,0,168,36,1,0,0,0,169,170,5,47,0,0,170,171,5,47,0,0, 116,0,0,151,152,5,114,0,0,152,153,5,97,0,0,153,154,5,99,0,0,154,
171,175,1,0,0,0,172,174,8,6,0,0,173,172,1,0,0,0,174,177,1,0,0,0, 155,5,107,0,0,155,156,5,45,0,0,156,157,5,114,0,0,157,158,5,101,0,
175,173,1,0,0,0,175,176,1,0,0,0,176,178,1,0,0,0,177,175,1,0,0,0, 0,158,159,5,108,0,0,159,160,5,101,0,0,160,161,5,97,0,0,161,162,5,
178,179,6,18,0,0,179,38,1,0,0,0,180,181,5,47,0,0,181,182,5,42,0, 115,0,0,162,163,5,101,0,0,163,26,1,0,0,0,164,165,5,116,0,0,165,166,
0,182,186,1,0,0,0,183,185,9,0,0,0,184,183,1,0,0,0,185,188,1,0,0, 5,114,0,0,166,167,5,97,0,0,167,168,5,99,0,0,168,169,5,107,0,0,169,
0,186,187,1,0,0,0,186,184,1,0,0,0,187,189,1,0,0,0,188,186,1,0,0, 170,5,45,0,0,170,171,5,100,0,0,171,172,5,101,0,0,172,173,5,118,0,
0,189,190,5,42,0,0,190,191,5,47,0,0,191,192,1,0,0,0,192,193,6,19, 0,173,174,5,101,0,0,174,175,5,108,0,0,175,176,5,111,0,0,176,177,
0,0,193,40,1,0,0,0,194,196,7,7,0,0,195,194,1,0,0,0,196,197,1,0,0, 5,112,0,0,177,178,5,109,0,0,178,179,5,101,0,0,179,180,5,110,0,0,
0,197,195,1,0,0,0,197,198,1,0,0,0,198,199,1,0,0,0,199,200,6,20,0, 180,181,5,116,0,0,181,28,1,0,0,0,182,183,5,105,0,0,183,184,5,109,
0,200,42,1,0,0,0,9,0,138,144,150,152,165,175,186,197,1,6,0,0 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
]; ];
private static __ATN: antlr.ATN; private static __ATN: antlr.ATN;
+265 -77
View File
@@ -19,40 +19,50 @@ export class QuixosLockParser extends antlr.Parser {
public static readonly PACKAGE = 7; public static readonly PACKAGE = 7;
public static readonly REPOSITORY = 8; public static readonly REPOSITORY = 8;
public static readonly COMMIT = 9; public static readonly COMMIT = 9;
public static readonly IMPORT = 10; public static readonly POLICY = 10;
public static readonly LBRACE = 11; public static readonly REF = 11;
public static readonly RBRACE = 12; public static readonly PINNED = 12;
public static readonly SEMI = 13; public static readonly TRACK_RELEASE = 13;
public static readonly INTEGER = 14; public static readonly TRACK_DEVELOPMENT = 14;
public static readonly IDENTIFIER = 15; public static readonly IMPORT = 15;
public static readonly STRING_LITERAL = 16; public static readonly LBRACE = 16;
public static readonly LINE_COMMENT = 17; public static readonly RBRACE = 17;
public static readonly BLOCK_COMMENT = 18; public static readonly SEMI = 18;
public static readonly WS = 19; 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 RULE_document = 0; public static readonly RULE_document = 0;
public static readonly RULE_quixosEntry = 1; public static readonly RULE_quixosEntry = 1;
public static readonly RULE_resourceEntry = 2; public static readonly RULE_resourceEntry = 2;
public static readonly RULE_importEntry = 3; public static readonly RULE_importEntry = 3;
public static readonly RULE_resourceKind = 4; public static readonly RULE_resourceKind = 4;
public static readonly RULE_sourceBlock = 5; public static readonly RULE_sourceBlock = 5;
public static readonly RULE_identifier = 6; public static readonly RULE_quixosSourceBlock = 6;
public static readonly RULE_stringLiteral = 7; public static readonly RULE_sourcePolicy = 7;
public static readonly RULE_identifier = 8;
public static readonly RULE_stringLiteral = 9;
public static readonly literalNames = [ public static readonly literalNames = [
null, "'quixos-lock'", "'fragment'", "'version'", "'quixos'", "'source'", null, "'quixos-lock'", "'fragment'", "'version'", "'quixos'", "'source'",
"'interface'", "'package'", "'repository'", "'commit'", "'import'", "'interface'", "'package'", "'repository'", "'commit'", "'policy'",
"'ref'", "'pinned'", "'track-release'", "'track-development'", "'import'",
"'{'", "'}'", "';'" "'{'", "'}'", "';'"
]; ];
public static readonly symbolicNames = [ public static readonly symbolicNames = [
null, "QUIXOS_LOCK", "FRAGMENT", "VERSION", "QUIXOS", "SOURCE", null, "QUIXOS_LOCK", "FRAGMENT", "VERSION", "QUIXOS", "SOURCE",
"INTERFACE", "PACKAGE", "REPOSITORY", "COMMIT", "IMPORT", "LBRACE", "INTERFACE", "PACKAGE", "REPOSITORY", "COMMIT", "POLICY", "REF",
"PINNED", "TRACK_RELEASE", "TRACK_DEVELOPMENT", "IMPORT", "LBRACE",
"RBRACE", "SEMI", "INTEGER", "IDENTIFIER", "STRING_LITERAL", "LINE_COMMENT", "RBRACE", "SEMI", "INTEGER", "IDENTIFIER", "STRING_LITERAL", "LINE_COMMENT",
"BLOCK_COMMENT", "WS" "BLOCK_COMMENT", "WS"
]; ];
public static readonly ruleNames = [ public static readonly ruleNames = [
"document", "quixosEntry", "resourceEntry", "importEntry", "resourceKind", "document", "quixosEntry", "resourceEntry", "importEntry", "resourceKind",
"sourceBlock", "identifier", "stringLiteral", "sourceBlock", "quixosSourceBlock", "sourcePolicy", "identifier",
"stringLiteral",
]; ];
public get grammarFileName(): string { return "QuixosLock.g4"; } public get grammarFileName(): string { return "QuixosLock.g4"; }
@@ -76,48 +86,48 @@ export class QuixosLockParser extends antlr.Parser {
try { try {
this.enterOuterAlt(localContext, 1); this.enterOuterAlt(localContext, 1);
{ {
this.state = 16; this.state = 20;
this.match(QuixosLockParser.QUIXOS_LOCK); this.match(QuixosLockParser.QUIXOS_LOCK);
this.state = 18; this.state = 22;
this.errorHandler.sync(this); this.errorHandler.sync(this);
_la = this.tokenStream.LA(1); _la = this.tokenStream.LA(1);
if (_la === 2) { if (_la === 2) {
{ {
this.state = 17; this.state = 21;
this.match(QuixosLockParser.FRAGMENT); this.match(QuixosLockParser.FRAGMENT);
} }
} }
this.state = 20; this.state = 24;
this.match(QuixosLockParser.VERSION); this.match(QuixosLockParser.VERSION);
this.state = 21; this.state = 25;
this.match(QuixosLockParser.INTEGER); this.match(QuixosLockParser.INTEGER);
this.state = 22; this.state = 26;
this.match(QuixosLockParser.LBRACE); this.match(QuixosLockParser.LBRACE);
this.state = 28; this.state = 32;
this.errorHandler.sync(this); this.errorHandler.sync(this);
_la = this.tokenStream.LA(1); _la = this.tokenStream.LA(1);
while ((((_la) & ~0x1F) === 0 && ((1 << _la) & 1232) !== 0)) { while ((((_la) & ~0x1F) === 0 && ((1 << _la) & 32976) !== 0)) {
{ {
this.state = 26; this.state = 30;
this.errorHandler.sync(this); this.errorHandler.sync(this);
switch (this.tokenStream.LA(1)) { switch (this.tokenStream.LA(1)) {
case QuixosLockParser.QUIXOS: case QuixosLockParser.QUIXOS:
{ {
this.state = 23; this.state = 27;
this.quixosEntry(); this.quixosEntry();
} }
break; break;
case QuixosLockParser.IMPORT: case QuixosLockParser.IMPORT:
{ {
this.state = 24; this.state = 28;
this.importEntry(); this.importEntry();
} }
break; break;
case QuixosLockParser.INTERFACE: case QuixosLockParser.INTERFACE:
case QuixosLockParser.PACKAGE: case QuixosLockParser.PACKAGE:
{ {
this.state = 25; this.state = 29;
this.resourceEntry(); this.resourceEntry();
} }
break; break;
@@ -125,13 +135,13 @@ export class QuixosLockParser extends antlr.Parser {
throw new antlr.NoViableAltException(this); throw new antlr.NoViableAltException(this);
} }
} }
this.state = 30; this.state = 34;
this.errorHandler.sync(this); this.errorHandler.sync(this);
_la = this.tokenStream.LA(1); _la = this.tokenStream.LA(1);
} }
this.state = 31; this.state = 35;
this.match(QuixosLockParser.RBRACE); this.match(QuixosLockParser.RBRACE);
this.state = 32; this.state = 36;
this.match(QuixosLockParser.EOF); this.match(QuixosLockParser.EOF);
} }
} }
@@ -154,12 +164,12 @@ export class QuixosLockParser extends antlr.Parser {
try { try {
this.enterOuterAlt(localContext, 1); this.enterOuterAlt(localContext, 1);
{ {
this.state = 34; this.state = 38;
this.match(QuixosLockParser.QUIXOS); this.match(QuixosLockParser.QUIXOS);
this.state = 35; this.state = 39;
this.match(QuixosLockParser.SOURCE); this.match(QuixosLockParser.SOURCE);
this.state = 36; this.state = 40;
this.sourceBlock(); this.quixosSourceBlock();
} }
} }
catch (re) { catch (re) {
@@ -181,13 +191,13 @@ export class QuixosLockParser extends antlr.Parser {
try { try {
this.enterOuterAlt(localContext, 1); this.enterOuterAlt(localContext, 1);
{ {
this.state = 38; this.state = 42;
this.resourceKind(); this.resourceKind();
this.state = 39; this.state = 43;
this.identifier(); this.identifier();
this.state = 40; this.state = 44;
this.match(QuixosLockParser.SOURCE); this.match(QuixosLockParser.SOURCE);
this.state = 41; this.state = 45;
this.sourceBlock(); this.sourceBlock();
} }
} }
@@ -210,11 +220,11 @@ export class QuixosLockParser extends antlr.Parser {
try { try {
this.enterOuterAlt(localContext, 1); this.enterOuterAlt(localContext, 1);
{ {
this.state = 43; this.state = 47;
this.match(QuixosLockParser.IMPORT); this.match(QuixosLockParser.IMPORT);
this.state = 44; this.state = 48;
this.stringLiteral(); this.stringLiteral();
this.state = 45; this.state = 49;
this.match(QuixosLockParser.SEMI); this.match(QuixosLockParser.SEMI);
} }
} }
@@ -238,7 +248,7 @@ export class QuixosLockParser extends antlr.Parser {
try { try {
this.enterOuterAlt(localContext, 1); this.enterOuterAlt(localContext, 1);
{ {
this.state = 47; this.state = 51;
_la = this.tokenStream.LA(1); _la = this.tokenStream.LA(1);
if(!(_la === 6 || _la === 7)) { if(!(_la === 6 || _la === 7)) {
this.errorHandler.recoverInline(this); this.errorHandler.recoverInline(this);
@@ -268,21 +278,21 @@ export class QuixosLockParser extends antlr.Parser {
try { try {
this.enterOuterAlt(localContext, 1); this.enterOuterAlt(localContext, 1);
{ {
this.state = 49;
this.match(QuixosLockParser.LBRACE);
this.state = 50;
this.match(QuixosLockParser.REPOSITORY);
this.state = 51;
this.stringLiteral();
this.state = 52;
this.match(QuixosLockParser.SEMI);
this.state = 53; this.state = 53;
this.match(QuixosLockParser.COMMIT); this.match(QuixosLockParser.LBRACE);
this.state = 54; this.state = 54;
this.stringLiteral(); this.match(QuixosLockParser.REPOSITORY);
this.state = 55; this.state = 55;
this.match(QuixosLockParser.SEMI); this.stringLiteral();
this.state = 56; this.state = 56;
this.match(QuixosLockParser.SEMI);
this.state = 57;
this.match(QuixosLockParser.COMMIT);
this.state = 58;
this.stringLiteral();
this.state = 59;
this.match(QuixosLockParser.SEMI);
this.state = 60;
this.match(QuixosLockParser.RBRACE); this.match(QuixosLockParser.RBRACE);
} }
} }
@@ -299,13 +309,102 @@ export class QuixosLockParser extends antlr.Parser {
} }
return localContext; return localContext;
} }
public quixosSourceBlock(): QuixosSourceBlockContext {
let localContext = new QuixosSourceBlockContext(this.context, this.state);
this.enterRule(localContext, 12, QuixosLockParser.RULE_quixosSourceBlock);
let _la: number;
try {
this.enterOuterAlt(localContext, 1);
{
this.state = 62;
this.match(QuixosLockParser.LBRACE);
this.state = 63;
this.match(QuixosLockParser.REPOSITORY);
this.state = 64;
this.stringLiteral();
this.state = 65;
this.match(QuixosLockParser.SEMI);
this.state = 73;
this.errorHandler.sync(this);
_la = this.tokenStream.LA(1);
if (_la === 10) {
{
this.state = 66;
this.match(QuixosLockParser.POLICY);
this.state = 67;
this.sourcePolicy();
this.state = 68;
this.match(QuixosLockParser.SEMI);
this.state = 69;
this.match(QuixosLockParser.REF);
this.state = 70;
this.stringLiteral();
this.state = 71;
this.match(QuixosLockParser.SEMI);
}
}
this.state = 75;
this.match(QuixosLockParser.COMMIT);
this.state = 76;
this.stringLiteral();
this.state = 77;
this.match(QuixosLockParser.SEMI);
this.state = 78;
this.match(QuixosLockParser.RBRACE);
}
}
catch (re) {
if (re instanceof antlr.RecognitionException) {
this.errorHandler.reportError(this, re);
this.errorHandler.recover(this, re);
} else {
throw re;
}
}
finally {
this.exitRule();
}
return localContext;
}
public sourcePolicy(): SourcePolicyContext {
let localContext = new SourcePolicyContext(this.context, this.state);
this.enterRule(localContext, 14, QuixosLockParser.RULE_sourcePolicy);
let _la: number;
try {
this.enterOuterAlt(localContext, 1);
{
this.state = 80;
_la = this.tokenStream.LA(1);
if(!((((_la) & ~0x1F) === 0 && ((1 << _la) & 28672) !== 0))) {
this.errorHandler.recoverInline(this);
}
else {
this.errorHandler.reportMatch(this);
this.consume();
}
}
}
catch (re) {
if (re instanceof antlr.RecognitionException) {
this.errorHandler.reportError(this, re);
this.errorHandler.recover(this, re);
} else {
throw re;
}
}
finally {
this.exitRule();
}
return localContext;
}
public identifier(): IdentifierContext { public identifier(): IdentifierContext {
let localContext = new IdentifierContext(this.context, this.state); let localContext = new IdentifierContext(this.context, this.state);
this.enterRule(localContext, 12, QuixosLockParser.RULE_identifier); this.enterRule(localContext, 16, QuixosLockParser.RULE_identifier);
try { try {
this.enterOuterAlt(localContext, 1); this.enterOuterAlt(localContext, 1);
{ {
this.state = 58; this.state = 82;
this.match(QuixosLockParser.IDENTIFIER); this.match(QuixosLockParser.IDENTIFIER);
} }
} }
@@ -324,11 +423,11 @@ export class QuixosLockParser extends antlr.Parser {
} }
public stringLiteral(): StringLiteralContext { public stringLiteral(): StringLiteralContext {
let localContext = new StringLiteralContext(this.context, this.state); let localContext = new StringLiteralContext(this.context, this.state);
this.enterRule(localContext, 14, QuixosLockParser.RULE_stringLiteral); this.enterRule(localContext, 18, QuixosLockParser.RULE_stringLiteral);
try { try {
this.enterOuterAlt(localContext, 1); this.enterOuterAlt(localContext, 1);
{ {
this.state = 60; this.state = 84;
this.match(QuixosLockParser.STRING_LITERAL); this.match(QuixosLockParser.STRING_LITERAL);
} }
} }
@@ -347,24 +446,31 @@ export class QuixosLockParser extends antlr.Parser {
} }
public static readonly _serializedATN: number[] = [ public static readonly _serializedATN: number[] = [
4,1,19,63,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,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,1,0,1,0,3,0,19,8,0,1,0,1,0,1,0,1,0,1,0,1,0,5,0,27,8,0, 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,
10,0,12,0,30,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,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,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,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,6,1,7,1,7,1,7,0,0,8,0,2,4,6,8,10,12,14,0,1,1,0,6,7,58,0,16,1,0, 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,
0,0,2,34,1,0,0,0,4,38,1,0,0,0,6,43,1,0,0,0,8,47,1,0,0,0,10,49,1, 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,
0,0,0,12,58,1,0,0,0,14,60,1,0,0,0,16,18,5,1,0,0,17,19,5,2,0,0,18, 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,
17,1,0,0,0,18,19,1,0,0,0,19,20,1,0,0,0,20,21,5,3,0,0,21,22,5,14, 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,22,28,5,11,0,0,23,27,3,2,1,0,24,27,3,6,3,0,25,27,3,4,2,0,26, 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,1,0,0,0,26,24,1,0,0,0,26,25,1,0,0,0,27,30,1,0,0,0,28,26,1,0,0, 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,28,29,1,0,0,0,29,31,1,0,0,0,30,28,1,0,0,0,31,32,5,12,0,0,32,33, 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,
5,0,0,1,33,1,1,0,0,0,34,35,5,4,0,0,35,36,5,5,0,0,36,37,3,10,5,0, 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,
37,3,1,0,0,0,38,39,3,8,4,0,39,40,3,12,6,0,40,41,5,5,0,0,41,42,3, 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,
10,5,0,42,5,1,0,0,0,43,44,5,10,0,0,44,45,3,14,7,0,45,46,5,13,0,0, 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,
46,7,1,0,0,0,47,48,7,0,0,0,48,9,1,0,0,0,49,50,5,11,0,0,50,51,5,8, 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,51,52,3,14,7,0,52,53,5,13,0,0,53,54,5,9,0,0,54,55,3,14,7,0,55, 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,
56,5,13,0,0,56,57,5,12,0,0,57,11,1,0,0,0,58,59,5,15,0,0,59,13,1, 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,0,0,60,61,5,16,0,0,61,15,1,0,0,0,3,18,26,28 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
]; ];
private static __ATN: antlr.ATN; private static __ATN: antlr.ATN;
@@ -461,8 +567,8 @@ export class QuixosEntryContext extends antlr.ParserRuleContext {
public SOURCE(): antlr.TerminalNode { public SOURCE(): antlr.TerminalNode {
return this.getToken(QuixosLockParser.SOURCE, 0)!; return this.getToken(QuixosLockParser.SOURCE, 0)!;
} }
public sourceBlock(): SourceBlockContext { public quixosSourceBlock(): QuixosSourceBlockContext {
return this.getRuleContext(0, SourceBlockContext)!; return this.getRuleContext(0, QuixosSourceBlockContext)!;
} }
public override get ruleIndex(): number { public override get ruleIndex(): number {
return QuixosLockParser.RULE_quixosEntry; return QuixosLockParser.RULE_quixosEntry;
@@ -602,6 +708,88 @@ export class SourceBlockContext extends antlr.ParserRuleContext {
} }
export class QuixosSourceBlockContext extends antlr.ParserRuleContext {
public constructor(parent: antlr.ParserRuleContext | null, invokingState: number) {
super(parent, invokingState);
}
public LBRACE(): antlr.TerminalNode {
return this.getToken(QuixosLockParser.LBRACE, 0)!;
}
public REPOSITORY(): antlr.TerminalNode {
return this.getToken(QuixosLockParser.REPOSITORY, 0)!;
}
public stringLiteral(): StringLiteralContext[];
public stringLiteral(i: number): StringLiteralContext | null;
public stringLiteral(i?: number): StringLiteralContext[] | StringLiteralContext | null {
if (i === undefined) {
return this.getRuleContexts(StringLiteralContext);
}
return this.getRuleContext(i, StringLiteralContext);
}
public SEMI(): antlr.TerminalNode[];
public SEMI(i: number): antlr.TerminalNode | null;
public SEMI(i?: number): antlr.TerminalNode | null | antlr.TerminalNode[] {
if (i === undefined) {
return this.getTokens(QuixosLockParser.SEMI);
} else {
return this.getToken(QuixosLockParser.SEMI, i);
}
}
public COMMIT(): antlr.TerminalNode {
return this.getToken(QuixosLockParser.COMMIT, 0)!;
}
public RBRACE(): antlr.TerminalNode {
return this.getToken(QuixosLockParser.RBRACE, 0)!;
}
public POLICY(): antlr.TerminalNode | null {
return this.getToken(QuixosLockParser.POLICY, 0);
}
public sourcePolicy(): SourcePolicyContext | null {
return this.getRuleContext(0, SourcePolicyContext);
}
public REF(): antlr.TerminalNode | null {
return this.getToken(QuixosLockParser.REF, 0);
}
public override get ruleIndex(): number {
return QuixosLockParser.RULE_quixosSourceBlock;
}
public override accept<Result>(visitor: QuixosLockVisitor<Result>): Result | null {
if (visitor.visitQuixosSourceBlock) {
return visitor.visitQuixosSourceBlock(this);
} else {
return visitor.visitChildren(this);
}
}
}
export class SourcePolicyContext extends antlr.ParserRuleContext {
public constructor(parent: antlr.ParserRuleContext | null, invokingState: number) {
super(parent, invokingState);
}
public PINNED(): antlr.TerminalNode | null {
return this.getToken(QuixosLockParser.PINNED, 0);
}
public TRACK_RELEASE(): antlr.TerminalNode | null {
return this.getToken(QuixosLockParser.TRACK_RELEASE, 0);
}
public TRACK_DEVELOPMENT(): antlr.TerminalNode | null {
return this.getToken(QuixosLockParser.TRACK_DEVELOPMENT, 0);
}
public override get ruleIndex(): number {
return QuixosLockParser.RULE_sourcePolicy;
}
public override accept<Result>(visitor: QuixosLockVisitor<Result>): Result | null {
if (visitor.visitSourcePolicy) {
return visitor.visitSourcePolicy(this);
} else {
return visitor.visitChildren(this);
}
}
}
export class IdentifierContext extends antlr.ParserRuleContext { export class IdentifierContext extends antlr.ParserRuleContext {
public constructor(parent: antlr.ParserRuleContext | null, invokingState: number) { public constructor(parent: antlr.ParserRuleContext | null, invokingState: number) {
super(parent, invokingState); super(parent, invokingState);
@@ -8,6 +8,8 @@ import { ResourceEntryContext } from "./QuixosLockParser.js";
import { ImportEntryContext } from "./QuixosLockParser.js"; import { ImportEntryContext } from "./QuixosLockParser.js";
import { ResourceKindContext } from "./QuixosLockParser.js"; import { ResourceKindContext } from "./QuixosLockParser.js";
import { SourceBlockContext } from "./QuixosLockParser.js"; import { SourceBlockContext } from "./QuixosLockParser.js";
import { QuixosSourceBlockContext } from "./QuixosLockParser.js";
import { SourcePolicyContext } from "./QuixosLockParser.js";
import { IdentifierContext } from "./QuixosLockParser.js"; import { IdentifierContext } from "./QuixosLockParser.js";
import { StringLiteralContext } from "./QuixosLockParser.js"; import { StringLiteralContext } from "./QuixosLockParser.js";
@@ -56,6 +58,18 @@ export class QuixosLockVisitor<Result> extends AbstractParseTreeVisitor<Result>
* @return the visitor result * @return the visitor result
*/ */
visitSourceBlock?: (ctx: SourceBlockContext) => Result; visitSourceBlock?: (ctx: SourceBlockContext) => Result;
/**
* Visit a parse tree produced by `QuixosLockParser.quixosSourceBlock`.
* @param ctx the parse tree
* @return the visitor result
*/
visitQuixosSourceBlock?: (ctx: QuixosSourceBlockContext) => Result;
/**
* Visit a parse tree produced by `QuixosLockParser.sourcePolicy`.
* @param ctx the parse tree
* @return the visitor result
*/
visitSourcePolicy?: (ctx: SourcePolicyContext) => Result;
/** /**
* Visit a parse tree produced by `QuixosLockParser.identifier`. * Visit a parse tree produced by `QuixosLockParser.identifier`.
* @param ctx the parse tree * @param ctx the parse tree
+87 -5
View File
@@ -10,6 +10,7 @@ import {
import { QuixosLockLexer } from "./generated/QuixosLockLexer.js"; import { QuixosLockLexer } from "./generated/QuixosLockLexer.js";
import { import {
QuixosLockParser, QuixosLockParser,
type QuixosSourceBlockContext,
type SourceBlockContext, type SourceBlockContext,
} from "./generated/QuixosLockParser.js"; } from "./generated/QuixosLockParser.js";
import type { import type {
@@ -17,6 +18,7 @@ import type {
LockedResource, LockedResource,
QuixosLockDocument, QuixosLockDocument,
QuixosRepositoryLock, QuixosRepositoryLock,
QuixosSource,
} from "./types.js"; } from "./types.js";
export type QuixosLockDiagnostic = { export type QuixosLockDiagnostic = {
@@ -73,6 +75,26 @@ const lowerSource = (context: SourceBlockContext): GitSource => ({
commit: stringValue(context.stringLiteral(1)!).toLowerCase(), commit: stringValue(context.stringLiteral(1)!).toLowerCase(),
}); });
const lowerQuixosSource = (context: QuixosSourceBlockContext): QuixosSource => {
const source = {
resolver: "git" as const,
repository: stringValue(context.stringLiteral(0)!),
commit: stringValue(context.stringLiteral(context.stringLiteral().length - 1)!).toLowerCase(),
};
const policyContext = context.sourcePolicy();
if (!policyContext) return source;
const policy = policyContext.PINNED()
? "pinned"
: policyContext.TRACK_RELEASE()
? "track-release"
: "track-development";
return {
...source,
policy,
ref: stringValue(context.stringLiteral(1)!),
};
};
const issue = ( const issue = (
diagnostics: QuixosLockDiagnostic[], diagnostics: QuixosLockDiagnostic[],
fileName: string, fileName: string,
@@ -176,6 +198,55 @@ const validateSource = (
} }
}; };
const validateQuixosSource = (
source: QuixosSource,
fileName: string,
diagnostics: QuixosLockDiagnostic[],
) => {
validateSource(source, "quixos", fileName, diagnostics);
if (!source.policy) return;
const forbiddenRefCharacters = new Set("~^:?*[\\");
const invalidRef = !source.ref
|| [...source.ref].some((character) => {
const code = character.charCodeAt(0);
return code <= 0x20 || code === 0x7f || forbiddenRefCharacters.has(character);
})
|| source.ref.startsWith("/")
|| source.ref.endsWith("/")
|| source.ref.endsWith(".")
|| source.ref.includes("..")
|| source.ref.includes("@{")
|| source.ref.includes("//");
if (invalidRef) {
issue(
diagnostics,
fileName,
"invalid-quixos-ref",
"quixos.ref must be a non-empty Git ref without whitespace or Git ref metacharacters",
"quixos.ref",
);
}
if (source.policy === "pinned") {
if (!/^([0-9a-f]{40}|[0-9a-f]{64})$/.test(source.ref)) {
issue(
diagnostics,
fileName,
"pinned-quixos-ref-not-commit",
"A pinned Quixos source must use an exact commit as its ref",
"quixos.ref",
);
} else if (source.ref.toLowerCase() !== source.commit) {
issue(
diagnostics,
fileName,
"pinned-quixos-commit-mismatch",
"A pinned Quixos source ref and resolved commit must be identical",
"quixos.commit",
);
}
}
};
export const parseQuixosLockDocument = ( export const parseQuixosLockDocument = (
source: string, source: string,
fileName = "<memory>", fileName = "<memory>",
@@ -204,7 +275,7 @@ export const parseQuixosLockDocument = (
const fragment = Boolean(tree.FRAGMENT()); const fragment = Boolean(tree.FRAGMENT());
const quixosEntries = tree.quixosEntry(); const quixosEntries = tree.quixosEntry();
let quixos: GitSource | undefined; let quixos: QuixosSource | undefined;
if (fragment && quixosEntries.length) { if (fragment && quixosEntries.length) {
issue( issue(
diagnostics, diagnostics,
@@ -222,8 +293,8 @@ export const parseQuixosLockDocument = (
"quixos", "quixos",
); );
} else if (!fragment) { } else if (!fragment) {
quixos = lowerSource(quixosEntries[0]!.sourceBlock()); quixos = lowerQuixosSource(quixosEntries[0]!.quixosSourceBlock());
validateSource(quixos, "quixos", fileName, diagnostics); validateQuixosSource(quixos, fileName, diagnostics);
} }
const imports = tree.importEntry().map((context, index) => { const imports = tree.importEntry().map((context, index) => {
@@ -334,11 +405,22 @@ const sourceLines = (source: GitSource, indentation: string): string[] => [
`${indentation}commit ${quoted(source.commit.toLowerCase())};`, `${indentation}commit ${quoted(source.commit.toLowerCase())};`,
]; ];
const quixosSourceLines = (source: QuixosSource, indentation: string): string[] => [
`${indentation}repository ${quoted(source.repository)};`,
...(source.policy
? [
`${indentation}policy ${source.policy};`,
`${indentation}ref ${quoted(source.ref)};`,
]
: []),
`${indentation}commit ${quoted(source.commit.toLowerCase())};`,
];
export const formatQuixosLock = (lock: QuixosRepositoryLock): string => { export const formatQuixosLock = (lock: QuixosRepositoryLock): string => {
const lines = [ const lines = [
"quixos-lock version 1 {", "quixos-lock version 1 {",
" quixos source {", " quixos source {",
...sourceLines(lock.quixos, " "), ...quixosSourceLines(lock.quixos, " "),
" }", " }",
]; ];
for (const resource of lock.resources) { for (const resource of lock.resources) {
@@ -360,7 +442,7 @@ export const formatQuixosLockDocument = (document: QuixosLockDocument): string =
if (document.kind === "root") { if (document.kind === "root") {
lines.push( lines.push(
" quixos source {", " quixos source {",
...sourceLines(document.quixos, " "), ...quixosSourceLines(document.quixos, " "),
" }", " }",
); );
} }
+15 -2
View File
@@ -4,6 +4,19 @@ export type GitSource = {
commit: string; commit: string;
}; };
export type QuixosSourcePolicy = "pinned" | "track-release" | "track-development";
// Resource repositories only need the exact Quixos commit they were authored
// against. A workspace root additionally declares how a runtime may advance
// that exact baseline.
export type QuixosSource = GitSource & ({
policy: QuixosSourcePolicy;
ref: string;
} | {
policy?: undefined;
ref?: undefined;
});
export type LockedResourceKind = "interface" | "package"; export type LockedResourceKind = "interface" | "package";
export type LockedResource = { export type LockedResource = {
@@ -15,7 +28,7 @@ export type LockedResource = {
export type QuixosLockRootDocument = { export type QuixosLockRootDocument = {
kind: "root"; kind: "root";
formatVersion: 1; formatVersion: 1;
quixos: GitSource; quixos: QuixosSource;
imports: string[]; imports: string[];
resources: LockedResource[]; resources: LockedResource[];
}; };
@@ -33,7 +46,7 @@ export type QuixosLockDocument =
export type QuixosRepositoryLock = { export type QuixosRepositoryLock = {
formatVersion: 1; formatVersion: 1;
quixos: GitSource; quixos: QuixosSource;
resources: LockedResource[]; resources: LockedResource[];
sourceFiles?: string[]; sourceFiles?: string[];
}; };
+28
View File
@@ -97,6 +97,34 @@ package Runtime id "package:runtime" revision "package:runtime@1" {
assert.equal(resource.directResources.size, 1); assert.equal(resource.directResources.size, 1);
}); });
test("resource repositories cannot own workspace Quixos selection policy", async (context) => {
const directory = await mkdtemp(path.join(os.tmpdir(), "quixos-resource-policy-"));
context.after(() => rm(directory, { recursive: true, force: true }));
await writeFile(path.join(directory, "quixos.lock"), `quixos-lock version 1 {
quixos source {
repository "https://example.test/quixos.git";
policy track-development;
ref "dev/alice/main";
commit "${quixosCommit}";
}
}`);
await writeFile(path.join(directory, "package.qx"), `package Runtime id "package:runtime" revision "package:runtime@1" { }\n`);
await assert.rejects(
compileCapabilityResourceRepository({
rootDirectory: directory,
kind: "package",
source: {
resolver: "git",
repository: "https://example.test/package-runtime.git",
commit: packageCommit,
},
resolveResource: async () => ({ directory }),
}),
/resource locks may only declare their exact authored-against commit/,
);
});
test("resource manifests cannot hide lock dependencies", async (context) => { test("resource manifests cannot hide lock dependencies", async (context) => {
const directory = await mkdtemp(path.join(os.tmpdir(), "quixos-assembly-mismatch-")); const directory = await mkdtemp(path.join(os.tmpdir(), "quixos-assembly-mismatch-"));
context.after(() => rm(directory, { recursive: true, force: true })); context.after(() => rm(directory, { recursive: true, force: true }));
+27
View File
@@ -20,6 +20,8 @@ const packageCommit = "3".repeat(64);
const fixture = `quixos-lock version 1 { const fixture = `quixos-lock version 1 {
quixos source { quixos source {
repository "https://gitea.example/quixos/quixos.git"; repository "https://gitea.example/quixos/quixos.git";
policy track-development;
ref "dev/alice/main";
commit "${quixosCommit}"; commit "${quixosCommit}";
} }
@@ -41,6 +43,8 @@ test("parses and canonically formats a Git-only repository lock", () => {
if (!parsed.ok) return; if (!parsed.ok) return;
assert.equal(parsed.lock.formatVersion, 1); assert.equal(parsed.lock.formatVersion, 1);
assert.equal(parsed.lock.quixos.commit, quixosCommit); assert.equal(parsed.lock.quixos.commit, quixosCommit);
assert.equal(parsed.lock.quixos.policy, "track-development");
assert.equal(parsed.lock.quixos.ref, "dev/alice/main");
assert.deepEqual( assert.deepEqual(
parsed.lock.resources.map(({ kind, binding }) => ({ kind, binding })), parsed.lock.resources.map(({ kind, binding }) => ({ kind, binding })),
[ [
@@ -55,6 +59,29 @@ test("parses and canonically formats a Git-only repository lock", () => {
}); });
}); });
test("validates pinned Quixos selections without imposing policy on resource locks", () => {
const mismatch = parseQuixosLockDocument(`quixos-lock version 1 {
quixos source {
repository "https://gitea.example/quixos/quixos.git";
policy pinned;
ref "${namedCommit}";
commit "${quixosCommit}";
}
}`);
assert.equal(mismatch.ok, false);
if (!mismatch.ok) {
assert.equal(mismatch.diagnostics[0]?.code, "pinned-quixos-commit-mismatch");
}
const resourceBaseline = parseQuixosLockDocument(`quixos-lock version 1 {
quixos source {
repository "https://gitea.example/quixos/quixos.git";
commit "${quixosCommit}";
}
}`);
assert.equal(resourceBaseline.ok, true);
});
test("derives immutable retention and Nix inputs without storing extra identity", () => { test("derives immutable retention and Nix inputs without storing extra identity", () => {
const source = { const source = {
resolver: "git" as const, resolver: "git" as const,