Compare commits

...

2 Commits

Author SHA1 Message Date
Quixos Subtree Publisher fd6fee133d Publish quixos-protocol from b384206b9c01a9ac50030a583d028b71291bc8c5 2026-09-06 07:07:06 +00:00
timothy f5ced64533 Build workspace agent, capability graph, and versioned cutovers 2026-09-06 00:07:06 -07:00
15 changed files with 671 additions and 206 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
{
"version": 1,
"sourceRepo": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos.git",
"sourceCommit": "33266c4ba9e0dd7b6370715522b281807e8b038b",
"sourceCommit": "b384206b9c01a9ac50030a583d028b71291bc8c5",
"sourcePath": "quixos-protocol",
"exportName": "quixos-protocol",
"mirrorRemote": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos-protocol.git"
+17 -6
View File
@@ -45,11 +45,20 @@ from v1.
## Repository locks
Every workspace, interface, and package repository carries a `quixos.lock`.
This is not a miniature workspace: a resource lock is only a Quixos toolchain
pin plus a dependency list. It pins exact Git sources for the interfaces and
packages named by that resource's own manifest. The v1 Git source is deliberately only a repository
URL and full commit ID; the publisher-owned reachability tag and Nix fetch
details are derived from those values.
A resource lock is not a miniature workspace: it contains only the exact
Quixos commit that resource was authored against plus its dependency list.
It also pins exact Git sources for interfaces and packages named by that
resource's own manifest. Resource Git sources are deliberately only a
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
quixos-lock-check quixos.lock
@@ -58,7 +67,7 @@ quixos-resource-compile \
--repository https://repos.quixos.org/example/package-example.git \
--commit 1111111111111111111111111111111111111111 \
--checkout-root /tmp/quixos-resource-dependencies
qx resource publish
qx-workspace resource publish
```
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 source {
repository "https://repos.quixos.org/quixos/quixos.git";
policy track-development;
ref "dev/alice/main";
commit "1111111111111111111111111111111111111111";
}
import "locks/web-studio.lock";
+20 -1
View File
@@ -6,7 +6,7 @@ document
;
quixosEntry
: QUIXOS SOURCE sourceBlock
: QUIXOS SOURCE quixosSourceBlock
;
resourceEntry
@@ -29,6 +29,20 @@ sourceBlock
RBRACE
;
quixosSourceBlock
: LBRACE
REPOSITORY stringLiteral SEMI
(POLICY sourcePolicy SEMI REF stringLiteral SEMI)?
COMMIT stringLiteral SEMI
RBRACE
;
sourcePolicy
: PINNED
| TRACK_RELEASE
| TRACK_DEVELOPMENT
;
identifier
: IDENTIFIER
;
@@ -46,6 +60,11 @@ INTERFACE: 'interface';
PACKAGE: 'package';
REPOSITORY: 'repository';
COMMIT: 'commit';
POLICY: 'policy';
REF: 'ref';
PINNED: 'pinned';
TRACK_RELEASE: 'track-release';
TRACK_DEVELOPMENT: 'track-development';
IMPORT: 'import';
LBRACE: '{';
+6
View File
@@ -190,6 +190,12 @@ const createResourceGraphResolver = (
if (!lockResult.ok) {
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()) {
throw new Error(
`${locked.kind} ${locked.binding} selects Quixos ${lockResult.lock.quixos.commit}, ` +
+13 -1
View File
@@ -9,6 +9,11 @@ null
'package'
'repository'
'commit'
'policy'
'ref'
'pinned'
'track-release'
'track-development'
'import'
'{'
'}'
@@ -31,6 +36,11 @@ INTERFACE
PACKAGE
REPOSITORY
COMMIT
POLICY
REF
PINNED
TRACK_RELEASE
TRACK_DEVELOPMENT
IMPORT
LBRACE
RBRACE
@@ -49,9 +59,11 @@ resourceEntry
importEntry
resourceKind
sourceBlock
quixosSourceBlock
sourcePolicy
identifier
stringLiteral
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
REPOSITORY=8
COMMIT=9
IMPORT=10
LBRACE=11
RBRACE=12
SEMI=13
INTEGER=14
IDENTIFIER=15
STRING_LITERAL=16
LINE_COMMENT=17
BLOCK_COMMENT=18
WS=19
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
'quixos-lock'=1
'fragment'=2
'version'=3
@@ -26,7 +31,12 @@ WS=19
'package'=7
'repository'=8
'commit'=9
'import'=10
'{'=11
'}'=12
';'=13
'policy'=10
'ref'=11
'pinned'=12
'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
REPOSITORY=8
COMMIT=9
IMPORT=10
LBRACE=11
RBRACE=12
SEMI=13
INTEGER=14
IDENTIFIER=15
STRING_LITERAL=16
LINE_COMMENT=17
BLOCK_COMMENT=18
WS=19
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
'quixos-lock'=1
'fragment'=2
'version'=3
@@ -26,7 +31,12 @@ WS=19
'package'=7
'repository'=8
'commit'=9
'import'=10
'{'=11
'}'=12
';'=13
'policy'=10
'ref'=11
'pinned'=12
'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 REPOSITORY = 8;
public static readonly COMMIT = 9;
public static readonly IMPORT = 10;
public static readonly LBRACE = 11;
public static readonly RBRACE = 12;
public static readonly SEMI = 13;
public static readonly INTEGER = 14;
public static readonly IDENTIFIER = 15;
public static readonly STRING_LITERAL = 16;
public static readonly LINE_COMMENT = 17;
public static readonly BLOCK_COMMENT = 18;
public static readonly WS = 19;
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 channelNames = [
"DEFAULT_TOKEN_CHANNEL", "HIDDEN"
@@ -30,13 +35,15 @@ export class QuixosLockLexer extends antlr.Lexer {
public static readonly literalNames = [
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 = [
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",
"BLOCK_COMMENT", "WS"
];
@@ -47,9 +54,10 @@ export class QuixosLockLexer extends antlr.Lexer {
public static readonly ruleNames = [
"QUIXOS_LOCK", "FRAGMENT", "VERSION", "QUIXOS", "SOURCE", "INTERFACE",
"PACKAGE", "REPOSITORY", "COMMIT", "IMPORT", "LBRACE", "RBRACE",
"SEMI", "INTEGER", "IDENTIFIER", "STRING_LITERAL", "ESC", "HEX",
"LINE_COMMENT", "BLOCK_COMMENT", "WS",
"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",
];
@@ -71,77 +79,99 @@ export class QuixosLockLexer extends antlr.Lexer {
public get modeNames(): string[] { return QuixosLockLexer.modeNames; }
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,
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,
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,11,1,11,1,12,1,12,
1,13,4,13,137,8,13,11,13,12,13,138,1,14,1,14,5,14,143,8,14,10,14,
12,14,146,9,14,1,15,1,15,1,15,5,15,151,8,15,10,15,12,15,154,9,15,
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,
1,17,1,17,1,18,1,18,1,18,1,18,5,18,174,8,18,10,18,12,18,177,9,18,
1,18,1,18,1,19,1,19,1,19,1,19,5,19,185,8,19,10,19,12,19,188,9,19,
1,19,1,19,1,19,1,19,1,19,1,20,4,20,196,8,20,11,20,12,20,197,1,20,
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,
11,23,12,25,13,27,14,29,15,31,16,33,0,35,0,37,17,39,18,41,19,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,206,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,37,1,0,0,0,0,39,1,0,0,0,0,41,1,
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,
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,
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,
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,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,
44,45,5,117,0,0,45,46,5,105,0,0,46,47,5,120,0,0,47,48,5,111,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,
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,
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,
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,
65,66,5,101,0,0,66,67,5,114,0,0,67,68,5,115,0,0,68,69,5,105,0,0,
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,
74,5,117,0,0,74,75,5,105,0,0,75,76,5,120,0,0,76,77,5,111,0,0,77,
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,
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,0,0,86,87,5,105,0,0,87,88,5,110,0,0,88,89,5,116,0,0,89,90,5,101,
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,
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,
99,5,99,0,0,99,100,5,107,0,0,100,101,5,97,0,0,101,102,5,103,0,0,
102,103,5,101,0,0,103,14,1,0,0,0,104,105,5,114,0,0,105,106,5,101,
0,0,106,107,5,112,0,0,107,108,5,111,0,0,108,109,5,115,0,0,109,110,
5,105,0,0,110,111,5,116,0,0,111,112,5,111,0,0,112,113,5,114,0,0,
113,114,5,121,0,0,114,16,1,0,0,0,115,116,5,99,0,0,116,117,5,111,
0,0,117,118,5,109,0,0,118,119,5,109,0,0,119,120,5,105,0,0,120,121,
5,116,0,0,121,18,1,0,0,0,122,123,5,105,0,0,123,124,5,109,0,0,124,
125,5,112,0,0,125,126,5,111,0,0,126,127,5,114,0,0,127,128,5,116,
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,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,136,135,1,0,0,0,137,138,1,0,0,0,138,136,1,0,0,0,138,139,1,0,0,
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,
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,
144,1,0,0,0,147,152,5,34,0,0,148,151,3,33,16,0,149,151,8,3,0,0,150,
148,1,0,0,0,150,149,1,0,0,0,151,154,1,0,0,0,152,150,1,0,0,0,152,
153,1,0,0,0,153,155,1,0,0,0,154,152,1,0,0,0,155,156,5,34,0,0,156,
32,1,0,0,0,157,165,5,92,0,0,158,166,7,4,0,0,159,160,5,117,0,0,160,
161,3,35,17,0,161,162,3,35,17,0,162,163,3,35,17,0,163,164,3,35,17,
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,
167,168,7,5,0,0,168,36,1,0,0,0,169,170,5,47,0,0,170,171,5,47,0,0,
171,175,1,0,0,0,172,174,8,6,0,0,173,172,1,0,0,0,174,177,1,0,0,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,
178,179,6,18,0,0,179,38,1,0,0,0,180,181,5,47,0,0,181,182,5,42,0,
0,182,186,1,0,0,0,183,185,9,0,0,0,184,183,1,0,0,0,185,188,1,0,0,
0,186,187,1,0,0,0,186,184,1,0,0,0,187,189,1,0,0,0,188,186,1,0,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,0,193,40,1,0,0,0,194,196,7,7,0,0,195,194,1,0,0,0,196,197,1,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,
0,200,42,1,0,0,0,9,0,138,144,150,152,165,175,186,197,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,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
];
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 REPOSITORY = 8;
public static readonly COMMIT = 9;
public static readonly IMPORT = 10;
public static readonly LBRACE = 11;
public static readonly RBRACE = 12;
public static readonly SEMI = 13;
public static readonly INTEGER = 14;
public static readonly IDENTIFIER = 15;
public static readonly STRING_LITERAL = 16;
public static readonly LINE_COMMENT = 17;
public static readonly BLOCK_COMMENT = 18;
public static readonly WS = 19;
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 RULE_document = 0;
public static readonly RULE_quixosEntry = 1;
public static readonly RULE_resourceEntry = 2;
public static readonly RULE_importEntry = 3;
public static readonly RULE_resourceKind = 4;
public static readonly RULE_sourceBlock = 5;
public static readonly RULE_identifier = 6;
public static readonly RULE_stringLiteral = 7;
public static readonly RULE_quixosSourceBlock = 6;
public static readonly RULE_sourcePolicy = 7;
public static readonly RULE_identifier = 8;
public static readonly RULE_stringLiteral = 9;
public static readonly literalNames = [
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 = [
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",
"BLOCK_COMMENT", "WS"
];
public static readonly ruleNames = [
"document", "quixosEntry", "resourceEntry", "importEntry", "resourceKind",
"sourceBlock", "identifier", "stringLiteral",
"sourceBlock", "quixosSourceBlock", "sourcePolicy", "identifier",
"stringLiteral",
];
public get grammarFileName(): string { return "QuixosLock.g4"; }
@@ -76,48 +86,48 @@ export class QuixosLockParser extends antlr.Parser {
try {
this.enterOuterAlt(localContext, 1);
{
this.state = 16;
this.state = 20;
this.match(QuixosLockParser.QUIXOS_LOCK);
this.state = 18;
this.state = 22;
this.errorHandler.sync(this);
_la = this.tokenStream.LA(1);
if (_la === 2) {
{
this.state = 17;
this.state = 21;
this.match(QuixosLockParser.FRAGMENT);
}
}
this.state = 20;
this.state = 24;
this.match(QuixosLockParser.VERSION);
this.state = 21;
this.state = 25;
this.match(QuixosLockParser.INTEGER);
this.state = 22;
this.state = 26;
this.match(QuixosLockParser.LBRACE);
this.state = 28;
this.state = 32;
this.errorHandler.sync(this);
_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);
switch (this.tokenStream.LA(1)) {
case QuixosLockParser.QUIXOS:
{
this.state = 23;
this.state = 27;
this.quixosEntry();
}
break;
case QuixosLockParser.IMPORT:
{
this.state = 24;
this.state = 28;
this.importEntry();
}
break;
case QuixosLockParser.INTERFACE:
case QuixosLockParser.PACKAGE:
{
this.state = 25;
this.state = 29;
this.resourceEntry();
}
break;
@@ -125,13 +135,13 @@ export class QuixosLockParser extends antlr.Parser {
throw new antlr.NoViableAltException(this);
}
}
this.state = 30;
this.state = 34;
this.errorHandler.sync(this);
_la = this.tokenStream.LA(1);
}
this.state = 31;
this.state = 35;
this.match(QuixosLockParser.RBRACE);
this.state = 32;
this.state = 36;
this.match(QuixosLockParser.EOF);
}
}
@@ -154,12 +164,12 @@ export class QuixosLockParser extends antlr.Parser {
try {
this.enterOuterAlt(localContext, 1);
{
this.state = 34;
this.state = 38;
this.match(QuixosLockParser.QUIXOS);
this.state = 35;
this.state = 39;
this.match(QuixosLockParser.SOURCE);
this.state = 36;
this.sourceBlock();
this.state = 40;
this.quixosSourceBlock();
}
}
catch (re) {
@@ -181,13 +191,13 @@ export class QuixosLockParser extends antlr.Parser {
try {
this.enterOuterAlt(localContext, 1);
{
this.state = 38;
this.state = 42;
this.resourceKind();
this.state = 39;
this.state = 43;
this.identifier();
this.state = 40;
this.state = 44;
this.match(QuixosLockParser.SOURCE);
this.state = 41;
this.state = 45;
this.sourceBlock();
}
}
@@ -210,11 +220,11 @@ export class QuixosLockParser extends antlr.Parser {
try {
this.enterOuterAlt(localContext, 1);
{
this.state = 43;
this.state = 47;
this.match(QuixosLockParser.IMPORT);
this.state = 44;
this.state = 48;
this.stringLiteral();
this.state = 45;
this.state = 49;
this.match(QuixosLockParser.SEMI);
}
}
@@ -238,7 +248,7 @@ export class QuixosLockParser extends antlr.Parser {
try {
this.enterOuterAlt(localContext, 1);
{
this.state = 47;
this.state = 51;
_la = this.tokenStream.LA(1);
if(!(_la === 6 || _la === 7)) {
this.errorHandler.recoverInline(this);
@@ -268,21 +278,21 @@ export class QuixosLockParser extends antlr.Parser {
try {
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.match(QuixosLockParser.COMMIT);
this.match(QuixosLockParser.LBRACE);
this.state = 54;
this.stringLiteral();
this.match(QuixosLockParser.REPOSITORY);
this.state = 55;
this.match(QuixosLockParser.SEMI);
this.stringLiteral();
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);
}
}
@@ -299,13 +309,102 @@ export class QuixosLockParser extends antlr.Parser {
}
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 {
let localContext = new IdentifierContext(this.context, this.state);
this.enterRule(localContext, 12, QuixosLockParser.RULE_identifier);
this.enterRule(localContext, 16, QuixosLockParser.RULE_identifier);
try {
this.enterOuterAlt(localContext, 1);
{
this.state = 58;
this.state = 82;
this.match(QuixosLockParser.IDENTIFIER);
}
}
@@ -324,11 +423,11 @@ export class QuixosLockParser extends antlr.Parser {
}
public stringLiteral(): StringLiteralContext {
let localContext = new StringLiteralContext(this.context, this.state);
this.enterRule(localContext, 14, QuixosLockParser.RULE_stringLiteral);
this.enterRule(localContext, 18, QuixosLockParser.RULE_stringLiteral);
try {
this.enterOuterAlt(localContext, 1);
{
this.state = 60;
this.state = 84;
this.match(QuixosLockParser.STRING_LITERAL);
}
}
@@ -347,24 +446,31 @@ export class QuixosLockParser extends antlr.Parser {
}
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,
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
];
private static __ATN: antlr.ATN;
@@ -461,8 +567,8 @@ export class QuixosEntryContext extends antlr.ParserRuleContext {
public SOURCE(): antlr.TerminalNode {
return this.getToken(QuixosLockParser.SOURCE, 0)!;
}
public sourceBlock(): SourceBlockContext {
return this.getRuleContext(0, SourceBlockContext)!;
public quixosSourceBlock(): QuixosSourceBlockContext {
return this.getRuleContext(0, QuixosSourceBlockContext)!;
}
public override get ruleIndex(): number {
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 {
public constructor(parent: antlr.ParserRuleContext | null, invokingState: number) {
super(parent, invokingState);
@@ -8,6 +8,8 @@ import { ResourceEntryContext } from "./QuixosLockParser.js";
import { ImportEntryContext } from "./QuixosLockParser.js";
import { ResourceKindContext } from "./QuixosLockParser.js";
import { SourceBlockContext } from "./QuixosLockParser.js";
import { QuixosSourceBlockContext } from "./QuixosLockParser.js";
import { SourcePolicyContext } from "./QuixosLockParser.js";
import { IdentifierContext } from "./QuixosLockParser.js";
import { StringLiteralContext } from "./QuixosLockParser.js";
@@ -56,6 +58,18 @@ export class QuixosLockVisitor<Result> extends AbstractParseTreeVisitor<Result>
* @return the visitor 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`.
* @param ctx the parse tree
+87 -5
View File
@@ -10,6 +10,7 @@ import {
import { QuixosLockLexer } from "./generated/QuixosLockLexer.js";
import {
QuixosLockParser,
type QuixosSourceBlockContext,
type SourceBlockContext,
} from "./generated/QuixosLockParser.js";
import type {
@@ -17,6 +18,7 @@ import type {
LockedResource,
QuixosLockDocument,
QuixosRepositoryLock,
QuixosSource,
} from "./types.js";
export type QuixosLockDiagnostic = {
@@ -73,6 +75,26 @@ const lowerSource = (context: SourceBlockContext): GitSource => ({
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 = (
diagnostics: QuixosLockDiagnostic[],
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 = (
source: string,
fileName = "<memory>",
@@ -204,7 +275,7 @@ export const parseQuixosLockDocument = (
const fragment = Boolean(tree.FRAGMENT());
const quixosEntries = tree.quixosEntry();
let quixos: GitSource | undefined;
let quixos: QuixosSource | undefined;
if (fragment && quixosEntries.length) {
issue(
diagnostics,
@@ -222,8 +293,8 @@ export const parseQuixosLockDocument = (
"quixos",
);
} else if (!fragment) {
quixos = lowerSource(quixosEntries[0]!.sourceBlock());
validateSource(quixos, "quixos", fileName, diagnostics);
quixos = lowerQuixosSource(quixosEntries[0]!.quixosSourceBlock());
validateQuixosSource(quixos, fileName, diagnostics);
}
const imports = tree.importEntry().map((context, index) => {
@@ -334,11 +405,22 @@ const sourceLines = (source: GitSource, indentation: string): string[] => [
`${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 => {
const lines = [
"quixos-lock version 1 {",
" quixos source {",
...sourceLines(lock.quixos, " "),
...quixosSourceLines(lock.quixos, " "),
" }",
];
for (const resource of lock.resources) {
@@ -360,7 +442,7 @@ export const formatQuixosLockDocument = (document: QuixosLockDocument): string =
if (document.kind === "root") {
lines.push(
" quixos source {",
...sourceLines(document.quixos, " "),
...quixosSourceLines(document.quixos, " "),
" }",
);
}
+15 -2
View File
@@ -4,6 +4,19 @@ export type GitSource = {
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 LockedResource = {
@@ -15,7 +28,7 @@ export type LockedResource = {
export type QuixosLockRootDocument = {
kind: "root";
formatVersion: 1;
quixos: GitSource;
quixos: QuixosSource;
imports: string[];
resources: LockedResource[];
};
@@ -33,7 +46,7 @@ export type QuixosLockDocument =
export type QuixosRepositoryLock = {
formatVersion: 1;
quixos: GitSource;
quixos: QuixosSource;
resources: LockedResource[];
sourceFiles?: string[];
};
+28
View File
@@ -97,6 +97,34 @@ package Runtime id "package:runtime" revision "package:runtime@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) => {
const directory = await mkdtemp(path.join(os.tmpdir(), "quixos-assembly-mismatch-"));
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 {
quixos source {
repository "https://gitea.example/quixos/quixos.git";
policy track-development;
ref "dev/alice/main";
commit "${quixosCommit}";
}
@@ -41,6 +43,8 @@ test("parses and canonically formats a Git-only repository lock", () => {
if (!parsed.ok) return;
assert.equal(parsed.lock.formatVersion, 1);
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(
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", () => {
const source = {
resolver: "git" as const,