@intentius/chant-lexicon-docker 0.124.21 → 0.124.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/dist/codegen/docs.d.ts.map +1 -1
  2. package/dist/codegen/generate.d.ts.map +1 -1
  3. package/dist/dockerfile-order.d.ts +13 -0
  4. package/dist/dockerfile-order.d.ts.map +1 -0
  5. package/dist/generated/index.d.ts +121 -0
  6. package/dist/generated/index.d.ts.map +1 -1
  7. package/dist/import/adapter.d.ts.map +1 -1
  8. package/dist/import/parser.d.ts +23 -0
  9. package/dist/import/parser.d.ts.map +1 -1
  10. package/dist/integrity.json +17 -8
  11. package/dist/lint/audit-catalog.d.ts.map +1 -1
  12. package/dist/lint/audit-lineage.d.ts.map +1 -1
  13. package/dist/lint/post-synth/add-url-checksum.d.ts +9 -0
  14. package/dist/lint/post-synth/add-url-checksum.d.ts.map +1 -0
  15. package/dist/lint/post-synth/apt-update-alone.d.ts +10 -0
  16. package/dist/lint/post-synth/apt-update-alone.d.ts.map +1 -0
  17. package/dist/lint/post-synth/cache-busting-copy.d.ts +11 -0
  18. package/dist/lint/post-synth/cache-busting-copy.d.ts.map +1 -0
  19. package/dist/lint/post-synth/copy-from-stage.d.ts +10 -0
  20. package/dist/lint/post-synth/copy-from-stage.d.ts.map +1 -0
  21. package/dist/lint/post-synth/docker-helpers.d.ts +35 -0
  22. package/dist/lint/post-synth/docker-helpers.d.ts.map +1 -1
  23. package/dist/lint/post-synth/index.d.ts.map +1 -1
  24. package/dist/lint/post-synth/no-root-user.d.ts +3 -2
  25. package/dist/lint/post-synth/no-root-user.d.ts.map +1 -1
  26. package/dist/lint/post-synth/relative-workdir.d.ts +10 -0
  27. package/dist/lint/post-synth/relative-workdir.d.ts.map +1 -0
  28. package/dist/lint/post-synth/repeated-cmd.d.ts +9 -0
  29. package/dist/lint/post-synth/repeated-cmd.d.ts.map +1 -0
  30. package/dist/lint/post-synth/root-after-user.d.ts +10 -0
  31. package/dist/lint/post-synth/root-after-user.d.ts.map +1 -0
  32. package/dist/lint/post-synth/unused-global-arg.d.ts +10 -0
  33. package/dist/lint/post-synth/unused-global-arg.d.ts.map +1 -0
  34. package/dist/lint/rules/index.d.ts +1 -0
  35. package/dist/lint/rules/index.d.ts.map +1 -1
  36. package/dist/lint/rules/per-kind-order.d.ts +15 -0
  37. package/dist/lint/rules/per-kind-order.d.ts.map +1 -0
  38. package/dist/manifest.json +1 -1
  39. package/dist/meta.json +6 -0
  40. package/dist/okf/index.md +10 -1
  41. package/dist/okf/rules/DKRD012.md +2 -2
  42. package/dist/okf/rules/DKRD013.md +11 -0
  43. package/dist/okf/rules/DKRD014.md +11 -0
  44. package/dist/okf/rules/DKRD015.md +11 -0
  45. package/dist/okf/rules/DKRD016.md +11 -0
  46. package/dist/okf/rules/DKRD017.md +11 -0
  47. package/dist/okf/rules/DKRD018.md +11 -0
  48. package/dist/okf/rules/DKRD019.md +11 -0
  49. package/dist/okf/rules/DKRD020.md +11 -0
  50. package/dist/okf/rules/DKRS002.md +15 -0
  51. package/dist/okf/types/Dockerfile.md +4 -1
  52. package/dist/plugin.d.ts.map +1 -1
  53. package/dist/rules/add-url-checksum.ts +38 -0
  54. package/dist/rules/apt-update-alone.ts +39 -0
  55. package/dist/rules/cache-busting-copy.ts +64 -0
  56. package/dist/rules/copy-from-stage.ts +54 -0
  57. package/dist/rules/docker-helpers.ts +80 -0
  58. package/dist/rules/no-root-user.ts +19 -17
  59. package/dist/rules/per-kind-order.ts +130 -0
  60. package/dist/rules/relative-workdir.ts +38 -0
  61. package/dist/rules/repeated-cmd.ts +35 -0
  62. package/dist/rules/root-after-user.ts +44 -0
  63. package/dist/rules/unused-global-arg.ts +38 -0
  64. package/dist/serializer.d.ts.map +1 -1
  65. package/dist/skills/chant-docker-patterns.md +91 -22
  66. package/dist/skills/chant-docker.md +42 -16
  67. package/dist/spec/parse-engine.d.ts +9 -0
  68. package/dist/spec/parse-engine.d.ts.map +1 -1
  69. package/dist/types/index.d.ts +81 -0
  70. package/package.json +3 -3
  71. package/src/codegen/__snapshots__/okf.test.ts.snap +155 -4
  72. package/src/codegen/docs.ts +14 -0
  73. package/src/codegen/generate.ts +77 -19
  74. package/src/dockerfile-order.ts +20 -0
  75. package/src/docs-examples.test.ts +141 -0
  76. package/src/generated/index.d.ts +81 -0
  77. package/src/generated/index.ts +117 -0
  78. package/src/generated/lexicon-docker.json +6 -0
  79. package/src/import/adapter.ts +8 -2
  80. package/src/import/generator.ts +49 -33
  81. package/src/import/parser.ts +82 -13
  82. package/src/import/roundtrip.test.ts +105 -0
  83. package/src/lint/audit-catalog.ts +9 -1
  84. package/src/lint/audit-lineage.ts +14 -0
  85. package/src/lint/post-synth/add-url-checksum.ts +38 -0
  86. package/src/lint/post-synth/apt-update-alone.ts +39 -0
  87. package/src/lint/post-synth/cache-busting-copy.ts +64 -0
  88. package/src/lint/post-synth/copy-from-stage.ts +54 -0
  89. package/src/lint/post-synth/docker-helpers.ts +80 -0
  90. package/src/lint/post-synth/index.ts +16 -0
  91. package/src/lint/post-synth/no-root-user.ts +19 -17
  92. package/src/lint/post-synth/post-synth.test.ts +149 -0
  93. package/src/lint/post-synth/relative-workdir.ts +38 -0
  94. package/src/lint/post-synth/repeated-cmd.ts +35 -0
  95. package/src/lint/post-synth/root-after-user.ts +44 -0
  96. package/src/lint/post-synth/unused-global-arg.ts +38 -0
  97. package/src/lint/rules/index.ts +1 -0
  98. package/src/lint/rules/per-kind-order.ts +130 -0
  99. package/src/lint/rules/rules.test.ts +88 -0
  100. package/src/plugin.test.ts +4 -0
  101. package/src/plugin.ts +2 -1
  102. package/src/serializer.test.ts +112 -0
  103. package/src/serializer.ts +58 -11
  104. package/src/skills/chant-docker-patterns.md +91 -22
  105. package/src/skills/chant-docker.md +42 -16
  106. package/src/spec/parse-engine.ts +17 -5
@@ -1 +1 @@
1
- {"version":3,"file":"docs.d.ts","sourceRoot":"","sources":["../../src/codegen/docs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AA4HH,wBAAsB,YAAY,CAAC,IAAI,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAoB9E"}
1
+ {"version":3,"file":"docs.d.ts","sourceRoot":"","sources":["../../src/codegen/docs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAyIH,wBAAsB,YAAY,CAAC,IAAI,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAqB9E"}
@@ -1 +1 @@
1
- {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/codegen/generate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjD,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,wBAAsB,QAAQ,CAAC,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAwB/G;AA2FD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,oBAAoB,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAWvF"}
1
+ {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/codegen/generate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAWH,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjD,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,wBAAsB,QAAQ,CAAC,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAwB/G;AAoJD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,oBAAoB,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAWvF"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * The order a Dockerfile stage's per-kind fields (`run`, `copy`, `user`, ...)
3
+ * are written in when the stage has no `steps`. It never changes, so a
4
+ * Dockerfile declared with per-kind fields builds the same output it always
5
+ * has; `steps` is how a stage controls its own order.
6
+ */
7
+ export declare const PER_KIND_ORDER: readonly ["arg", "env", "workdir", "user", "run", "copy", "add", "expose", "volume", "label", "entrypoint", "cmd", "healthcheck"];
8
+ export type PerKindField = (typeof PER_KIND_ORDER)[number];
9
+ /** The step keys whose array value is written in JSON exec form. */
10
+ export declare const EXEC_FORM_STEPS: ReadonlySet<string>;
11
+ /** Every instruction a step can name. FROM is the stage's own field. */
12
+ export declare const STEP_INSTRUCTIONS: ReadonlySet<string>;
13
+ //# sourceMappingURL=dockerfile-order.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dockerfile-order.d.ts","sourceRoot":"","sources":["../src/dockerfile-order.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,eAAO,MAAM,cAAc,YACzB,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EACrD,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,aAAa,CACvD,CAAC;AAEX,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAE3D,oEAAoE;AACpE,eAAO,MAAM,eAAe,EAAE,WAAW,CAAC,MAAM,CAAkD,CAAC;AAEnG,wEAAwE;AACxE,eAAO,MAAM,iBAAiB,EAAE,WAAW,CAAC,MAAM,CAEhD,CAAC"}
@@ -4,4 +4,125 @@ export declare const Network: new (props: Record<string, unknown>, attributes?:
4
4
  export declare const DockerConfig: new (props: Record<string, unknown>, attributes?: Record<string, unknown>) => import("@intentius/chant").Declarable & Record<string, string>;
5
5
  export declare const DockerSecret: new (props: Record<string, unknown>, attributes?: Record<string, unknown>) => import("@intentius/chant").Declarable & Record<string, string>;
6
6
  export declare const Dockerfile: new (props: Record<string, unknown>, attributes?: Record<string, unknown>) => import("@intentius/chant").Declarable & Record<string, string>;
7
+ /** The Dockerfile instructions a step can name. FROM is the stage's own `from` field. */
8
+ export type DockerfileInstructionName = "arg" | "env" | "run" | "copy" | "add" | "workdir" | "user" | "expose" | "volume" | "label" | "entrypoint" | "cmd" | "healthcheck" | "shell" | "stopsignal" | "onbuild";
9
+ type DockerfileStepOf<K extends DockerfileInstructionName, V> = {
10
+ [P in K]: V;
11
+ } & {
12
+ [P in Exclude<DockerfileInstructionName, K>]?: never;
13
+ };
14
+ /**
15
+ * One Dockerfile instruction, named by its single key: `{ run: "npm ci" }` is `RUN npm ci`.
16
+ * A string[] value (run, cmd, entrypoint, shell) is written in JSON exec form.
17
+ */
18
+ export type DockerfileStep =
19
+ /** ARG: Build-time argument */
20
+ DockerfileStepOf<"arg", string>
21
+ /** ENV: Environment variable */
22
+ | DockerfileStepOf<"env", string>
23
+ /** RUN: Run a command during build */
24
+ | DockerfileStepOf<"run", string | string[]>
25
+ /** COPY: Copy files from build context */
26
+ | DockerfileStepOf<"copy", string>
27
+ /** ADD: Add files (supports URLs and archives) */
28
+ | DockerfileStepOf<"add", string>
29
+ /** WORKDIR: Set working directory */
30
+ | DockerfileStepOf<"workdir", string>
31
+ /** USER: Set user for subsequent instructions */
32
+ | DockerfileStepOf<"user", string>
33
+ /** EXPOSE: Document exposed ports */
34
+ | DockerfileStepOf<"expose", string | number>
35
+ /** VOLUME: Create mount points */
36
+ | DockerfileStepOf<"volume", string>
37
+ /** LABEL: Add metadata labels */
38
+ | DockerfileStepOf<"label", string>
39
+ /** ENTRYPOINT: Set the entrypoint executable */
40
+ | DockerfileStepOf<"entrypoint", string | string[]>
41
+ /** CMD: Default command arguments */
42
+ | DockerfileStepOf<"cmd", string | string[]>
43
+ /** HEALTHCHECK: Health check instruction */
44
+ | DockerfileStepOf<"healthcheck", string>
45
+ /** SHELL: Set the shell for shell-form commands (JSON array form) */
46
+ | DockerfileStepOf<"shell", string | string[]>
47
+ /** STOPSIGNAL: Signal sent to stop the container */
48
+ | DockerfileStepOf<"stopsignal", string>
49
+ /** ONBUILD: Instruction to run when the image is used as a base */
50
+ | DockerfileStepOf<"onbuild", string>;
51
+ /**
52
+ * One build stage: FROM, then its instructions.
53
+ * Without `steps`, the per-kind fields are written in a fixed order: ARG, ENV, WORKDIR, USER, RUN, COPY, ADD, EXPOSE, VOLUME, LABEL, ENTRYPOINT, CMD, HEALTHCHECK.
54
+ */
55
+ export interface DockerfileStage {
56
+ from: string;
57
+ as?: string;
58
+ /** Instructions after FROM, written exactly in this order. Can't be combined with the per-kind fields. */
59
+ steps?: DockerfileStep[];
60
+ /** ARG as a per-kind field, written in the fixed order. Use `steps` to choose the order. */
61
+ arg?: string[];
62
+ /** ENV as a per-kind field, written in the fixed order. Use `steps` to choose the order. */
63
+ env?: string[];
64
+ /** RUN as a per-kind field, written in the fixed order. Use `steps` to choose the order. */
65
+ run?: string[];
66
+ /** COPY as a per-kind field, written in the fixed order. Use `steps` to choose the order. */
67
+ copy?: string[];
68
+ /** ADD as a per-kind field, written in the fixed order. Use `steps` to choose the order. */
69
+ add?: string[];
70
+ /** WORKDIR as a per-kind field, written in the fixed order. Use `steps` to choose the order. */
71
+ workdir?: string;
72
+ /** USER as a per-kind field, written in the fixed order. Use `steps` to choose the order. */
73
+ user?: string;
74
+ /** EXPOSE as a per-kind field, written in the fixed order. Use `steps` to choose the order. */
75
+ expose?: string[];
76
+ /** VOLUME as a per-kind field, written in the fixed order. Use `steps` to choose the order. */
77
+ volume?: string[];
78
+ /** LABEL as a per-kind field, written in the fixed order. Use `steps` to choose the order. */
79
+ label?: string[];
80
+ /** ENTRYPOINT as a per-kind field, written in the fixed order. Use `steps` to choose the order. */
81
+ entrypoint?: string;
82
+ /** CMD as a per-kind field, written in the fixed order. Use `steps` to choose the order. */
83
+ cmd?: string;
84
+ /** HEALTHCHECK as a per-kind field, written in the fixed order. Use `steps` to choose the order. */
85
+ healthcheck?: string;
86
+ }
87
+ /**
88
+ * A Dockerfile: `stages` for a multi-stage build, or `from` and the stage fields for one stage.
89
+ * Without `steps`, the per-kind fields are written in a fixed order: ARG, ENV, WORKDIR, USER, RUN, COPY, ADD, EXPOSE, VOLUME, LABEL, ENTRYPOINT, CMD, HEALTHCHECK.
90
+ */
91
+ export interface DockerfileProps {
92
+ name?: string;
93
+ /** ARG instructions written before the first FROM, e.g. `["NODE_VERSION=20"]`. */
94
+ globalArgs?: string[];
95
+ from?: string;
96
+ as?: string;
97
+ stages?: DockerfileStage[];
98
+ /** Instructions after FROM, written exactly in this order. Can't be combined with the per-kind fields. */
99
+ steps?: DockerfileStep[];
100
+ /** ARG as a per-kind field, written in the fixed order. Use `steps` to choose the order. */
101
+ arg?: string[];
102
+ /** ENV as a per-kind field, written in the fixed order. Use `steps` to choose the order. */
103
+ env?: string[];
104
+ /** RUN as a per-kind field, written in the fixed order. Use `steps` to choose the order. */
105
+ run?: string[];
106
+ /** COPY as a per-kind field, written in the fixed order. Use `steps` to choose the order. */
107
+ copy?: string[];
108
+ /** ADD as a per-kind field, written in the fixed order. Use `steps` to choose the order. */
109
+ add?: string[];
110
+ /** WORKDIR as a per-kind field, written in the fixed order. Use `steps` to choose the order. */
111
+ workdir?: string;
112
+ /** USER as a per-kind field, written in the fixed order. Use `steps` to choose the order. */
113
+ user?: string;
114
+ /** EXPOSE as a per-kind field, written in the fixed order. Use `steps` to choose the order. */
115
+ expose?: string[];
116
+ /** VOLUME as a per-kind field, written in the fixed order. Use `steps` to choose the order. */
117
+ volume?: string[];
118
+ /** LABEL as a per-kind field, written in the fixed order. Use `steps` to choose the order. */
119
+ label?: string[];
120
+ /** ENTRYPOINT as a per-kind field, written in the fixed order. Use `steps` to choose the order. */
121
+ entrypoint?: string;
122
+ /** CMD as a per-kind field, written in the fixed order. Use `steps` to choose the order. */
123
+ cmd?: string;
124
+ /** HEALTHCHECK as a per-kind field, written in the fixed order. Use `steps` to choose the order. */
125
+ healthcheck?: string;
126
+ }
127
+ export {};
7
128
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/generated/index.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,OAAO,8IAA2D,CAAC;AAChF,eAAO,MAAM,MAAM,8IAA0D,CAAC;AAC9E,eAAO,MAAM,OAAO,8IAA2D,CAAC;AAChF,eAAO,MAAM,YAAY,8IAA0D,CAAC;AACpF,eAAO,MAAM,YAAY,8IAA0D,CAAC;AAEpF,eAAO,MAAM,UAAU,8IAAqD,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/generated/index.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/import/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAc,MAAM,gCAAgC,CAAC;AAC7F,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAgD5F;;;GAGG;AACH,qBAAa,oBAAqB,YAAW,cAAc;IACzD,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,CAMjC;CACF;AAED;;;GAGG;AACH,qBAAa,uBAAwB,YAAW,mBAAmB;IACjE,QAAQ,CAAC,EAAE,EAAE,UAAU,GAAG,aAAa,EAAE,CAIxC;CACF"}
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/import/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAc,MAAM,gCAAgC,CAAC;AAC7F,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAiD5F;;;GAGG;AACH,qBAAa,oBAAqB,YAAW,cAAc;IACzD,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,CAWjC;CACF;AAED;;;GAGG;AACH,qBAAa,uBAAwB,YAAW,mBAAmB;IACjE,QAAQ,CAAC,EAAE,EAAE,UAAU,GAAG,aAAa,EAAE,CAIxC;CACF"}
@@ -30,6 +30,11 @@ export interface SecretIR {
30
30
  export interface DockerfileStage {
31
31
  from: string;
32
32
  as?: string;
33
+ /**
34
+ * The stage's instructions after FROM, in source order. `instruction` is
35
+ * the upper-case keyword; `value` is the rest of the instruction as
36
+ * written, line continuations and heredoc bodies included.
37
+ */
33
38
  instructions: Array<{
34
39
  instruction: string;
35
40
  value: string;
@@ -38,6 +43,8 @@ export interface DockerfileStage {
38
43
  export interface DockerfileIR {
39
44
  kind: "dockerfile";
40
45
  name: string;
46
+ /** ARG values declared before the first FROM. */
47
+ globalArgs?: string[];
41
48
  stages: DockerfileStage[];
42
49
  }
43
50
  export type DockerIR = ServiceIR | VolumeIR | NetworkIR | ConfigIR | SecretIR | DockerfileIR;
@@ -52,10 +59,26 @@ export interface ParseResult {
52
59
  export declare class DockerParser {
53
60
  parse(content: string): ParseResult;
54
61
  }
62
+ /** One logical Dockerfile instruction: its upper-case keyword and the rest as written. */
63
+ export interface DockerfileInstruction {
64
+ instruction: string;
65
+ value: string;
66
+ }
67
+ /**
68
+ * Split Dockerfile content into logical instructions, in order. Comment
69
+ * and blank lines are dropped (also inside a continued instruction, as
70
+ * Docker does). A line ending in a backslash continues onto the next line,
71
+ * and a heredoc (`RUN <<EOF` ... `EOF`) runs to its terminator; both are
72
+ * kept in the value exactly as written, so writing the value back gives
73
+ * the same instruction.
74
+ */
75
+ export declare function splitDockerfileInstructions(content: string): DockerfileInstruction[];
55
76
  /**
56
77
  * Parser for Dockerfile content.
57
78
  */
58
79
  export declare class DockerfileParser {
59
80
  parse(name: string, content: string): DockerfileIR;
60
81
  }
82
+ /** Whether content reads as a Dockerfile: its first instruction is FROM or ARG, or it starts with a parser directive. */
83
+ export declare function looksLikeDockerfile(content: string): boolean;
61
84
  //# sourceMappingURL=parser.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/import/parser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,KAAK,CAAC;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC7D;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,eAAe,EAAE,CAAC;CAC3B;AAED,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,YAAY,CAAC;AAE7F,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,QAAQ,EAAE,CAAC;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AA0BD;;;GAGG;AACH,qBAAa,YAAY;IACvB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,CAoElC;CACF;AAED;;GAEG;AACH,qBAAa,gBAAgB;IAC3B,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,YAAY,CA4BjD;CACF"}
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/import/parser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ;;;;OAIG;IACH,YAAY,EAAE,KAAK,CAAC;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC7D;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,MAAM,EAAE,eAAe,EAAE,CAAC;CAC3B;AAED,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,YAAY,CAAC;AAE7F,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,QAAQ,EAAE,CAAC;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AA0BD;;;GAGG;AACH,qBAAa,YAAY;IACvB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,CAoElC;CACF;AAED,0FAA0F;AAC1F,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,MAAM,GAAG,qBAAqB,EAAE,CAuCpF;AAED;;GAEG;AACH,qBAAa,gBAAgB;IAC3B,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,YAAY,CAuBjD;CACF;AAED,yHAAyH;AACzH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAS5D"}
@@ -1,19 +1,28 @@
1
1
  {
2
2
  "algorithm": "sha256",
3
3
  "artifacts": {
4
- "manifest.json": "ec3263940092e78fa3bafc821e793efa8b616fd2e2e60c3fbebb40e3b34c9a9e",
5
- "meta.json": "2996be8fdb14f3f935e1e1441fed8f69af7b6aeeefb14dac96301cc41eba8046",
6
- "types/index.d.ts": "7b2e6f784b7dbecbbe7924fa1aec7e2520ac0547069311253a006bc2267a5646",
4
+ "manifest.json": "fe4bc2268e250cd125728ad9d16e6dc5d39c3c59492bf14406ca097127d6603e",
5
+ "meta.json": "2b751db9716bb5191ea508d4b4c02d9db4e78ebae5e8bce7d40ff0751ea368d6",
6
+ "types/index.d.ts": "516ed0b52a0c5c7ff828e19a1bcc19759a4a0f293a62fda763407f6970ab0e38",
7
7
  "rules/no-latest-tag.ts": "2281be0457c02e782fbafe015f65ff5fd2b008ef0f879226e9b548a3ea65399b",
8
+ "rules/per-kind-order.ts": "50622c849e9e76e312c4ca7abd97858f74641e0d7f673d2de47b055f7f6b6c6b",
9
+ "rules/add-url-checksum.ts": "b317a30103f65a9dc658cc858aeca797f96f4c34f76525c88e4618dcb4a5cd05",
8
10
  "rules/apt-no-recommends.ts": "579ea54435b1cbd59088994aaaf7b249a42064facd74b62163b302fe31e769e0",
9
- "rules/docker-helpers.ts": "c76ea1294b630df086a23b24c0435c9daac8cdf21dd371a8aabf74e9984e6b13",
11
+ "rules/apt-update-alone.ts": "d684a6eb45642ca3968c90fef28f71795672fb600d5aecc4b9e33d48792f75e2",
12
+ "rules/cache-busting-copy.ts": "4552fba29caa2d8dcf78041ebdd9793b775ef585ff9499d4f2e58c412fb2be4c",
13
+ "rules/copy-from-stage.ts": "2c11889c75e6ccafca538e65a6df0c1eae34eed484908ddf0b8bf39a937f2f0e",
14
+ "rules/docker-helpers.ts": "64ab4abca082b05c9cfab669f258085ffeb3a9a523d19a639630545ae2e971db",
10
15
  "rules/no-latest-image.ts": "3e49602822e0645173a961b9c0686b669e846957486781a881693dbe04790b88",
11
- "rules/no-root-user.ts": "fb47adc8523e07a8307253dcffeeccd7528e655bf737ef7e313e76a3df2c9a2d",
16
+ "rules/no-root-user.ts": "bf3ab4b87423652cd4c5d4f8a2d01ecda94d62a0ca8e8abddb82313a5dd16d9f",
12
17
  "rules/prefer-copy.ts": "b422a77b94023f7356d6b6326b6552c459cfbd282468f38214e19a105a59b742",
18
+ "rules/relative-workdir.ts": "3b81b51d3b170e2203e8ab25c15ef2ee7b37a07eaa3eda31bb5bfa3e27e98e62",
19
+ "rules/repeated-cmd.ts": "5a178852c55335314a95cffc4b503f65cac185188979bb6c4e581d072e737219",
20
+ "rules/root-after-user.ts": "5f107d899fb59a5d95d7661393e2fc94ac8d98399bf1e07af4286a748eec111b",
13
21
  "rules/ssh-port-exposed.ts": "1df86b498787cbcc5ac8995c7099956576d9d105b4da71b0c225790be585c4c9",
22
+ "rules/unused-global-arg.ts": "f3aefedee383194350bfb92beca75d6f88c4fc6bb35cd09b96dfa388d151032b",
14
23
  "rules/unused-volume.ts": "ffcfc731782a4443a2eb34b1c0f6230b094c18c6ad104e4b81074bb799a3ce40",
15
- "skills/chant-docker.md": "3ff0708e3c76e245f202948949c768464563af2b60cc9aa2ca52f494ef8357f1",
16
- "skills/chant-docker-patterns.md": "ad1b0196d8150b2df579a699ff107f604340c799c04f3460ebf65003e287b12a"
24
+ "skills/chant-docker.md": "1b029363668f457598f5cc2b49ebbf1e671218d93b002281c218c55ad41a57b9",
25
+ "skills/chant-docker-patterns.md": "c96c15412c651d97948bec946b40942fed6f2ba611ca51830e752f932bd9b10b"
17
26
  },
18
- "composite": "abf5286a1bff6c66444cfb50946490688657fb162e1dce7c401773d2d7710fa6"
27
+ "composite": "13f5008ad8ed466fe333e26b8c5e41d923f3cd7b811a7d49ccc9c2cab18bb902"
19
28
  }
@@ -1 +1 @@
1
- {"version":3,"file":"audit-catalog.d.ts","sourceRoot":"","sources":["../../src/lint/audit-catalog.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAA+B,KAAK,QAAQ,EAAgC,MAAM,gCAAgC,CAAC;AAK1H,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAOvD,CAAC"}
1
+ {"version":3,"file":"audit-catalog.d.ts","sourceRoot":"","sources":["../../src/lint/audit-catalog.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAA+B,KAAK,QAAQ,EAAgC,MAAM,gCAAgC,CAAC;AAK1H,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAevD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"audit-lineage.d.ts","sourceRoot":"","sources":["../../src/lint/audit-lineage.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAE9D,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,CAwBxD,CAAC"}
1
+ {"version":3,"file":"audit-lineage.d.ts","sourceRoot":"","sources":["../../src/lint/audit-lineage.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAE9D,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,CAsCxD,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * DKRD019: ADD of a remote URL without --checksum
3
+ *
4
+ * ADD fetches an http(s) URL at build time and trusts whatever comes back.
5
+ * `ADD --checksum=sha256:...` makes the build fail when the content changes.
6
+ */
7
+ import type { PostSynthCheck } from "@intentius/chant/lint/post-synth";
8
+ export declare const dkrd019: PostSynthCheck;
9
+ //# sourceMappingURL=add-url-checksum.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add-url-checksum.d.ts","sourceRoot":"","sources":["../../../src/lint/post-synth/add-url-checksum.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAyC,MAAM,kCAAkC,CAAC;AAG9G,eAAO,MAAM,OAAO,EAAE,cA2BrB,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * DKRD020: apt-get update in its own RUN
3
+ *
4
+ * A RUN that only runs `apt-get update` is cached as its own layer, so a
5
+ * later `apt-get install` in another RUN can install from a stale package
6
+ * index. Update and install in the same RUN.
7
+ */
8
+ import type { PostSynthCheck } from "@intentius/chant/lint/post-synth";
9
+ export declare const dkrd020: PostSynthCheck;
10
+ //# sourceMappingURL=apt-update-alone.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apt-update-alone.d.ts","sourceRoot":"","sources":["../../../src/lint/post-synth/apt-update-alone.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAyC,MAAM,kCAAkC,CAAC;AAM9G,eAAO,MAAM,OAAO,EAAE,cAwBrB,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * DKRD013: Whole build context copied before installing dependencies
3
+ *
4
+ * `COPY . .` followed by a dependency install (npm ci, pip install -r,
5
+ * go mod download, ...) in the same stage invalidates the install layer on
6
+ * every source change. Copy the dependency manifests first, install, then
7
+ * copy the rest.
8
+ */
9
+ import type { PostSynthCheck } from "@intentius/chant/lint/post-synth";
10
+ export declare const dkrd013: PostSynthCheck;
11
+ //# sourceMappingURL=cache-busting-copy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache-busting-copy.d.ts","sourceRoot":"","sources":["../../../src/lint/post-synth/cache-busting-copy.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAyC,MAAM,kCAAkC,CAAC;AA8B9G,eAAO,MAAM,OAAO,EAAE,cAwBrB,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * DKRD016: COPY --from names no earlier stage
3
+ *
4
+ * `COPY --from=<name>` reads from an earlier stage with that name (or
5
+ * index). A name that only a later stage has, or that no stage has, is
6
+ * pulled as an image instead, which is almost never what was meant.
7
+ */
8
+ import type { PostSynthCheck } from "@intentius/chant/lint/post-synth";
9
+ export declare const dkrd016: PostSynthCheck;
10
+ //# sourceMappingURL=copy-from-stage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"copy-from-stage.d.ts","sourceRoot":"","sources":["../../../src/lint/post-synth/copy-from-stage.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAyC,MAAM,kCAAkC,CAAC;AAQ9G,eAAO,MAAM,OAAO,EAAE,cAqCrB,CAAC"}
@@ -29,4 +29,39 @@ export declare function isLatestOrUntagged(image: string): boolean;
29
29
  * Get Dockerfile content from SerializerResult files map.
30
30
  */
31
31
  export declare function extractDockerfiles(output: unknown): Map<string, string>;
32
+ export interface DockerfileInstr {
33
+ /** Upper-case keyword, e.g. "RUN". */
34
+ instruction: string;
35
+ /** The rest of the instruction as written. */
36
+ value: string;
37
+ }
38
+ export interface ParsedStage {
39
+ /** 0-based position among the stages. */
40
+ index: number;
41
+ /** The FROM image (or earlier stage) without `--platform` and `AS`. */
42
+ from: string;
43
+ as?: string;
44
+ instructions: DockerfileInstr[];
45
+ }
46
+ export interface ParsedDockerfile {
47
+ /** ARG instructions before the first FROM. */
48
+ globalArgs: DockerfileInstr[];
49
+ stages: ParsedStage[];
50
+ }
51
+ /** A Dockerfile's global ARGs and stages, each stage's instructions in order. */
52
+ export declare function parseDockerfileStages(content: string): ParsedDockerfile;
53
+ /** How a stage is named in a message: `stage "build"` or `stage 2`. */
54
+ export declare function stageLabel(stage: ParsedStage): string;
55
+ /** The first line of an instruction, for a message. */
56
+ export declare function instrText(instr: DockerfileInstr): string;
57
+ /** Whether a USER value is root (by name or uid 0, with or without a group). */
58
+ export declare function isRootUser(value: string): boolean;
59
+ /** Every generated Dockerfile in a build's outputs, parsed. */
60
+ export declare function eachDockerfile(outputs: Map<string, unknown>): Array<{
61
+ fileName: string;
62
+ content: string;
63
+ parsed: ParsedDockerfile;
64
+ }>;
65
+ /** A RUN value with its line continuations joined, for matching commands. */
66
+ export declare function commandText(instr: DockerfileInstr): string;
32
67
  //# sourceMappingURL=docker-helpers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"docker-helpers.d.ts","sourceRoot":"","sources":["../../../src/lint/post-synth/docker-helpers.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAEpE,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,KAAK,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAClD,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CA8CxE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAgB7D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAMzD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,OAAO,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAYvE"}
1
+ {"version":3,"file":"docker-helpers.d.ts","sourceRoot":"","sources":["../../../src/lint/post-synth/docker-helpers.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAGpE,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,KAAK,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAClD,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CA8CxE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAgB7D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAMzD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,OAAO,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAYvE;AAID,MAAM,WAAW,eAAe;IAC9B,sCAAsC;IACtC,WAAW,EAAE,MAAM,CAAC;IACpB,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,yCAAyC;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,eAAe,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,gBAAgB;IAC/B,8CAA8C;IAC9C,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB;AAED,iFAAiF;AACjF,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,CAmBvE;AAED,uEAAuE;AACvE,wBAAgB,UAAU,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAErD;AAED,uDAAuD;AACvD,wBAAgB,SAAS,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAGxD;AAED,gFAAgF;AAChF,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAGjD;AAED,+DAA+D;AAC/D,wBAAgB,cAAc,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,KAAK,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAA;CAAE,CAAC,CAQpI;AAED,6EAA6E;AAC7E,wBAAgB,WAAW,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAE1D"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lint/post-synth/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAQvE,eAAO,MAAM,eAAe,EAAE,cAAc,EAO3C,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lint/post-synth/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAgBvE,eAAO,MAAM,eAAe,EAAE,cAAc,EAe3C,CAAC"}
@@ -1,8 +1,9 @@
1
1
  /**
2
2
  * DKRD012: No Root User
3
3
  *
4
- * Warns when a Dockerfile has no USER instruction,
5
- * meaning the container runs as root by default.
4
+ * Warns when the container would run as root: the final stage has no USER
5
+ * instruction, or its last USER is root. USER in an earlier stage does not
6
+ * carry into the final image.
6
7
  */
7
8
  import type { PostSynthCheck } from "@intentius/chant/lint/post-synth";
8
9
  export declare const dkrd012: PostSynthCheck;
@@ -1 +1 @@
1
- {"version":3,"file":"no-root-user.d.ts","sourceRoot":"","sources":["../../../src/lint/post-synth/no-root-user.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAyC,MAAM,kCAAkC,CAAC;AAG9G,eAAO,MAAM,OAAO,EAAE,cAyBrB,CAAC"}
1
+ {"version":3,"file":"no-root-user.d.ts","sourceRoot":"","sources":["../../../src/lint/post-synth/no-root-user.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAyC,MAAM,kCAAkC,CAAC;AAG9G,eAAO,MAAM,OAAO,EAAE,cA0BrB,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * DKRD018: Relative WORKDIR
3
+ *
4
+ * A relative WORKDIR resolves against whatever directory the base image
5
+ * left, which can change with the image. Use an absolute path, at least for
6
+ * the first WORKDIR of a stage.
7
+ */
8
+ import type { PostSynthCheck } from "@intentius/chant/lint/post-synth";
9
+ export declare const dkrd018: PostSynthCheck;
10
+ //# sourceMappingURL=relative-workdir.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relative-workdir.d.ts","sourceRoot":"","sources":["../../../src/lint/post-synth/relative-workdir.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAyC,MAAM,kCAAkC,CAAC;AAG9G,eAAO,MAAM,OAAO,EAAE,cA0BrB,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * DKRD015: More than one CMD or ENTRYPOINT in a stage
3
+ *
4
+ * Only the last CMD and the last ENTRYPOINT of a stage take effect; the
5
+ * earlier ones are silently ignored.
6
+ */
7
+ import type { PostSynthCheck } from "@intentius/chant/lint/post-synth";
8
+ export declare const dkrd015: PostSynthCheck;
9
+ //# sourceMappingURL=repeated-cmd.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repeated-cmd.d.ts","sourceRoot":"","sources":["../../../src/lint/post-synth/repeated-cmd.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAyC,MAAM,kCAAkC,CAAC;AAG9G,eAAO,MAAM,OAAO,EAAE,cAwBrB,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * DKRD014: Root-only command after a non-root USER
3
+ *
4
+ * A RUN that installs packages or manages users and ownership (apt-get,
5
+ * apk add, useradd, chown, ...) fails or misbehaves after USER switches to
6
+ * an unprivileged user. Run root setup first, then switch USER.
7
+ */
8
+ import type { PostSynthCheck } from "@intentius/chant/lint/post-synth";
9
+ export declare const dkrd014: PostSynthCheck;
10
+ //# sourceMappingURL=root-after-user.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"root-after-user.d.ts","sourceRoot":"","sources":["../../../src/lint/post-synth/root-after-user.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAyC,MAAM,kCAAkC,CAAC;AAK9G,eAAO,MAAM,OAAO,EAAE,cA8BrB,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * DKRD017: ARG before FROM that nothing uses
3
+ *
4
+ * An ARG declared before the first FROM is only visible to FROM lines, and
5
+ * to stages that declare it again (`ARG NAME`). One that neither uses does
6
+ * nothing.
7
+ */
8
+ import type { PostSynthCheck } from "@intentius/chant/lint/post-synth";
9
+ export declare const dkrd017: PostSynthCheck;
10
+ //# sourceMappingURL=unused-global-arg.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unused-global-arg.d.ts","sourceRoot":"","sources":["../../../src/lint/post-synth/unused-global-arg.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAyC,MAAM,kCAAkC,CAAC;AAG9G,eAAO,MAAM,OAAO,EAAE,cA0BrB,CAAC"}
@@ -2,4 +2,5 @@
2
2
  * All imperative lint rules for the Docker lexicon.
3
3
  */
4
4
  export { noLatestTagRule } from "./no-latest-tag.js";
5
+ export { perKindOrderRule } from "./per-kind-order.js";
5
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lint/rules/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lint/rules/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * DKRS002: Per-kind Dockerfile fields written in a different order
3
+ *
4
+ * A Dockerfile stage without `steps` writes its per-kind fields (`run`,
5
+ * `copy`, `user`, ...) in a fixed order: ARG, ENV, WORKDIR, USER, RUN, COPY,
6
+ * ADD, EXPOSE, VOLUME, LABEL, ENTRYPOINT, CMD, HEALTHCHECK. When the fields
7
+ * are declared in another order (`copy` before `run`, `run` before `user`)
8
+ * the generated Dockerfile does not run them in the order they read in.
9
+ *
10
+ * The fix rewrites the fields as `steps` in the fixed order, so the
11
+ * generated Dockerfile stays the same, with a comment to reorder them.
12
+ */
13
+ import type { LintRule } from "@intentius/chant/lint/rule";
14
+ export declare const perKindOrderRule: LintRule;
15
+ //# sourceMappingURL=per-kind-order.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"per-kind-order.d.ts","sourceRoot":"","sources":["../../../src/lint/rules/per-kind-order.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAwC,MAAM,4BAA4B,CAAC;AA2GjG,eAAO,MAAM,gBAAgB,EAAE,QAS9B,CAAC"}
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "docker",
3
- "version": "0.124.21",
3
+ "version": "0.124.22",
4
4
  "chantVersion": ">=0.1.0",
5
5
  "namespace": "Docker",
6
6
  "intrinsics": [
package/dist/meta.json CHANGED
@@ -220,6 +220,12 @@
220
220
  },
221
221
  "healthcheck": {
222
222
  "description": "Health check instruction"
223
+ },
224
+ "globalArgs": {
225
+ "description": "ARG instructions written before the first FROM"
226
+ },
227
+ "steps": {
228
+ "description": "Instructions after FROM, written in the order given; one instruction per step"
223
229
  }
224
230
  }
225
231
  }
package/dist/okf/index.md CHANGED
@@ -18,5 +18,14 @@ okf_version: '0.2'
18
18
  * [DKRD003](/rules/DKRD003.md) - Service exposes SSH port (22) externally — this is a security risk
19
19
  * [DKRD010](/rules/DKRD010.md) - apt-get install without --no-install-recommends adds unnecessary packages
20
20
  * [DKRD011](/rules/DKRD011.md) - Prefer COPY over ADD when not fetching URLs or extracting archives
21
- * [DKRD012](/rules/DKRD012.md) - Dockerfile has no USER instruction — container runs as root
21
+ * [DKRD012](/rules/DKRD012.md) - Dockerfile's final stage has no USER instruction, or ends on USER root — container runs as root
22
+ * [DKRD013](/rules/DKRD013.md) - Whole build context copied before a dependency install — every source change re-runs the install
23
+ * [DKRD014](/rules/DKRD014.md) - RUN needs root but comes after USER switched to a non-root user
24
+ * [DKRD015](/rules/DKRD015.md) - More than one CMD or ENTRYPOINT in a stage — only the last one takes effect
25
+ * [DKRD016](/rules/DKRD016.md) - COPY --from names a stage that is not defined before it
26
+ * [DKRD017](/rules/DKRD017.md) - ARG before the first FROM is not used by any FROM or stage
27
+ * [DKRD018](/rules/DKRD018.md) - Relative WORKDIR before any absolute WORKDIR in the stage
28
+ * [DKRD019](/rules/DKRD019.md) - ADD fetches a remote URL without --checksum
29
+ * [DKRD020](/rules/DKRD020.md) - apt-get update in a different RUN from apt-get install — the install can use a stale package index
22
30
  * [DKRS001](/rules/DKRS001.md) - No Latest Tag
31
+ * [DKRS002](/rules/DKRS002.md) - Per-kind Dockerfile fields written in a different order
@@ -1,14 +1,14 @@
1
1
  ---
2
2
  type: post-synth-check
3
3
  title: DKRD012
4
- description: Dockerfile has no USER instruction — container runs as root
4
+ description: Dockerfile's final stage has no USER instruction, or ends on USER root — container runs as root
5
5
  id: DKRD012
6
6
  severity: error
7
7
  category: post-synth
8
8
  lexicon: docker
9
9
  docs: https://intentius.io/chant/lexicons/docker/rules/
10
10
  ---
11
- Dockerfile has no USER instruction — container runs as root
11
+ Dockerfile's final stage has no USER instruction, or ends on USER root — container runs as root
12
12
 
13
13
  ## Applies to
14
14
 
@@ -0,0 +1,11 @@
1
+ ---
2
+ type: post-synth-check
3
+ title: DKRD013
4
+ description: Whole build context copied before a dependency install — every source change re-runs the install
5
+ id: DKRD013
6
+ severity: error
7
+ category: post-synth
8
+ lexicon: docker
9
+ docs: https://intentius.io/chant/lexicons/docker/rules/
10
+ ---
11
+ Whole build context copied before a dependency install — every source change re-runs the install
@@ -0,0 +1,11 @@
1
+ ---
2
+ type: post-synth-check
3
+ title: DKRD014
4
+ description: RUN needs root but comes after USER switched to a non-root user
5
+ id: DKRD014
6
+ severity: error
7
+ category: post-synth
8
+ lexicon: docker
9
+ docs: https://intentius.io/chant/lexicons/docker/rules/
10
+ ---
11
+ RUN needs root but comes after USER switched to a non-root user
@@ -0,0 +1,11 @@
1
+ ---
2
+ type: post-synth-check
3
+ title: DKRD015
4
+ description: More than one CMD or ENTRYPOINT in a stage — only the last one takes effect
5
+ id: DKRD015
6
+ severity: error
7
+ category: post-synth
8
+ lexicon: docker
9
+ docs: https://intentius.io/chant/lexicons/docker/rules/
10
+ ---
11
+ More than one CMD or ENTRYPOINT in a stage — only the last one takes effect