skir 0.0.6 → 0.0.8

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 (55) hide show
  1. package/dist/command_line_parser.d.ts +2 -2
  2. package/dist/command_line_parser.d.ts.map +1 -1
  3. package/dist/command_line_parser.js +105 -36
  4. package/dist/command_line_parser.js.map +1 -1
  5. package/dist/command_line_parser.test.js +166 -39
  6. package/dist/command_line_parser.test.js.map +1 -1
  7. package/dist/compiler.js +51 -54
  8. package/dist/compiler.js.map +1 -1
  9. package/dist/config.d.ts +2 -2
  10. package/dist/config.d.ts.map +1 -1
  11. package/dist/config.js +3 -5
  12. package/dist/config.js.map +1 -1
  13. package/dist/config_parser.d.ts +6 -0
  14. package/dist/config_parser.d.ts.map +1 -1
  15. package/dist/config_parser.js +55 -31
  16. package/dist/config_parser.js.map +1 -1
  17. package/dist/config_parser.test.js +53 -20
  18. package/dist/config_parser.test.js.map +1 -1
  19. package/dist/error_renderer.d.ts +1 -0
  20. package/dist/error_renderer.d.ts.map +1 -1
  21. package/dist/error_renderer.js +6 -3
  22. package/dist/error_renderer.js.map +1 -1
  23. package/dist/exit_error.d.ts +8 -0
  24. package/dist/exit_error.d.ts.map +1 -0
  25. package/dist/exit_error.js +8 -0
  26. package/dist/exit_error.js.map +1 -0
  27. package/dist/io.d.ts +2 -0
  28. package/dist/io.d.ts.map +1 -1
  29. package/dist/io.js +22 -3
  30. package/dist/io.js.map +1 -1
  31. package/dist/module_collector.d.ts.map +1 -1
  32. package/dist/module_collector.js +12 -7
  33. package/dist/module_collector.js.map +1 -1
  34. package/dist/module_set.js +4 -4
  35. package/dist/parser.js +6 -6
  36. package/dist/project_initializer.d.ts.map +1 -1
  37. package/dist/project_initializer.js +97 -15
  38. package/dist/project_initializer.js.map +1 -1
  39. package/dist/snapshotter.d.ts +9 -2
  40. package/dist/snapshotter.d.ts.map +1 -1
  41. package/dist/snapshotter.js +35 -17
  42. package/dist/snapshotter.js.map +1 -1
  43. package/package.json +8 -6
  44. package/src/command_line_parser.ts +134 -42
  45. package/src/compiler.ts +65 -60
  46. package/src/config.ts +4 -6
  47. package/src/config_parser.ts +66 -32
  48. package/src/error_renderer.ts +11 -3
  49. package/src/exit_error.ts +6 -0
  50. package/src/io.ts +22 -3
  51. package/src/module_collector.ts +21 -7
  52. package/src/module_set.ts +4 -4
  53. package/src/parser.ts +6 -6
  54. package/src/project_initializer.ts +97 -15
  55. package/src/snapshotter.ts +49 -30
@@ -1,11 +1,12 @@
1
- import * as fs from "fs";
2
- import * as paths from "path";
1
+ import * as FileSystem from "fs";
2
+ import * as Paths from "path";
3
+ import { rewritePathForRendering } from "./io.js";
3
4
 
4
5
  export function initializeProject(rootDir: string): void {
5
- const skirYmlPath = paths.join(rootDir, "skir.yml");
6
+ const skirYmlPath = Paths.join(rootDir, "skir.yml");
6
7
 
7
8
  // Check if skir.yml already exists
8
- if (fs.existsSync(skirYmlPath)) {
9
+ if (FileSystem.existsSync(skirYmlPath)) {
9
10
  console.log(
10
11
  "A skir.yml file already exists in this directory. Skipping project initialization.",
11
12
  );
@@ -13,28 +14,109 @@ export function initializeProject(rootDir: string): void {
13
14
  }
14
15
 
15
16
  // Create skir.yml file
16
- fs.writeFileSync(skirYmlPath, SKIR_YML_CONTENT, "utf-8");
17
+ FileSystem.writeFileSync(skirYmlPath, SKIR_YML_CONTENT, "utf-8");
17
18
 
18
19
  // Check if skir-src directory exists
19
- const skirSrcDir = paths.join(rootDir, "skir-src");
20
- if (!fs.existsSync(skirSrcDir)) {
20
+ const skirSrcDir = Paths.join(rootDir, "skir-src");
21
+ if (!FileSystem.existsSync(skirSrcDir)) {
21
22
  // Create skir-src directory
22
- fs.mkdirSync(skirSrcDir, { recursive: true });
23
+ FileSystem.mkdirSync(skirSrcDir, { recursive: true });
23
24
 
24
25
  // Create hello_world.skir file
25
- const helloWorldPath = paths.join(skirSrcDir, "hello_world.skir");
26
- fs.writeFileSync(helloWorldPath, HELLO_WORLD_SKIR_CONTENT, "utf-8");
26
+ const helloWorldPath = Paths.join(skirSrcDir, "hello_world.skir");
27
+ FileSystem.writeFileSync(helloWorldPath, HELLO_WORLD_SKIR_CONTENT, "utf-8");
27
28
  }
28
29
 
29
- console.log(`Done. Please edit: ${paths.resolve(skirYmlPath)}`);
30
+ console.log(`Done. Please edit: ${rewritePathForRendering(skirYmlPath)}`);
30
31
  }
31
32
 
32
- const SKIR_YML_CONTENT = `srcDir: skir-src
33
+ const SKIR_YML_CONTENT = `# Configuration file for Skir code generator
34
+ #
35
+ # Documentation: https://skir.build/
36
+ #
37
+ # Cheat sheet:
38
+ # npx skir gen Generate code from .skir files
39
+ # npx skir gen --watch Watch for changes and regenerate automatically
40
+ # npx skir format Format all .skir files
41
+ # npx skir snapshot Take a snapshot of the source directory, verify no
42
+ # breaking changes since last snapshot
33
43
 
44
+ # Directory containing .skir files
45
+ srcDir: skir-src
46
+
47
+ # Uncomment and configure the generators for your target language(s).
34
48
  generators:
35
- - mod: skir-python-gen
36
- skiroutDir: ./skirout
37
- config: {}
49
+ # # --------------------------------------------------------------------------
50
+ # # C++ code generator
51
+ # # Home: https://github.com/gepheum/skir-cc-gen
52
+ # # To install runtime dependencies, follow instructions in repository README
53
+ # # --------------------------------------------------------------------------
54
+ # - mod: skir-cc-gen
55
+ # outDir: ./skirout
56
+ # config:
57
+ # # Set to true if you use GoogleTest
58
+ # writeGoogleTestHeaders: false
59
+
60
+ # # --------------------------------------------------------------------------
61
+ # # Dart code generator
62
+ # # Home: https://github.com/gepheum/skir-dart-gen
63
+ # # To install runtime dependencies: dart pub add skir_client
64
+ # # --------------------------------------------------------------------------
65
+ # - mod: skir-dart-gen
66
+ # outDir: ./skirout
67
+ # config: {}
68
+
69
+ # # --------------------------------------------------------------------------
70
+ # # Java code generator
71
+ # # Home: https://github.com/gepheum/skir-java-gen
72
+ # # Add the following line to your build.gradle dependencies:
73
+ # # implementation("build.skir:skir-client:latest.release")
74
+ # # --------------------------------------------------------------------------
75
+ # - mod: skir-java-gen
76
+ # outDir: ./src/main/java/skirout
77
+ # config: {}
78
+ # # Alternatively:
79
+ # # outDir: ./src/main/java/skirout/my/project
80
+ # # config:
81
+ # # packagePrefix: "my.project."
82
+
83
+ # # --------------------------------------------------------------------------
84
+ # # Kotlin code generator
85
+ # # Home: https://github.com/gepheum/skir-kotlin-gen
86
+ # # Add the following line to your build.gradle dependencies:
87
+ # # implementation("build.skir:skir-client:latest.release")
88
+ # # --------------------------------------------------------------------------
89
+ # - mod: skir-kotlin-gen
90
+ # outDir: ./src/main/kotlin/skirout
91
+ # config: {}
92
+ # # Alternatively:
93
+ # # outDir: ./src/main/kotlin/skirout/my/project
94
+ # # config:
95
+ # # packagePrefix: "my.project."
96
+
97
+ # # --------------------------------------------------------------------------
98
+ # # Python code generator
99
+ # # Home: https://github.com/gepheum/skir-python-gen
100
+ # # To install runtime dependencies: pip install skir-client
101
+ # # --------------------------------------------------------------------------
102
+ # - mod: skir-python-gen
103
+ # outDir: ./skirout
104
+ # config: {}
105
+ # # Alternatively:
106
+ # # outDir: ./my/project/skirout
107
+ # # config:
108
+ # # packagePrefix: "my.project."
109
+
110
+ # # --------------------------------------------------------------------------
111
+ # # TypeScript/JavaScript code generator
112
+ # # Home: https://github.com/gepheum/skir-typescript-gen
113
+ # # To install runtime dependencies: npm i skir-client
114
+ # # --------------------------------------------------------------------------
115
+ # - mod: skir-typescript-gen
116
+ # outDir: ./src/skirout
117
+ # config:
118
+ # # Use ".js" for ES modules, "" for CommonJS
119
+ # importPathExtension: ".js"
38
120
  `;
39
121
 
40
122
  const HELLO_WORLD_SKIR_CONTENT = `/// A point in 2D space.
@@ -8,29 +8,34 @@ import {
8
8
  renderBreakingChanges,
9
9
  renderErrors,
10
10
  } from "./error_renderer.js";
11
+ import { rewritePathForRendering } from "./io.js";
11
12
  import { collectModules } from "./module_collector.js";
12
13
  import { ModuleSet } from "./module_set.js";
13
14
 
14
15
  export async function takeSnapshot(args: {
15
16
  rootDir: string;
16
17
  srcDir: string;
17
- check: boolean;
18
- }): Promise<void> {
18
+ subcommand: "ci" | "dry-run" | undefined;
19
+ }): Promise<boolean> {
19
20
  const newModuleSet = await collectModules(args.srcDir);
20
21
  if (newModuleSet.errors.length) {
21
22
  renderErrors(newModuleSet.errors);
22
- process.exit(1);
23
+ return false;
23
24
  }
24
25
  const snapshotPath = join(args.rootDir, "skir-snapshot.json");
25
- const oldModuleSet = await readLastSnapshot(join(args.rootDir, snapshotPath));
26
+ const oldModuleSet = await readLastSnapshot(snapshotPath);
26
27
  if (!(oldModuleSet instanceof ModuleSet)) {
27
- console.error(makeRed(`Corrupted snapshot file: ${snapshotPath}`));
28
+ console.error(
29
+ makeRed(
30
+ `Corrupted snapshot file: ${rewritePathForRendering(snapshotPath)}`,
31
+ ),
32
+ );
28
33
  console.error(`Error: ${oldModuleSet.error.toString()}`);
29
34
  console.log(
30
35
  "If the snapshot file cannot be restored to a valid state, delete it and run again. " +
31
36
  "Breaking changes from recent commits will not be detected, but a valid snapshot will be created for future comparisons.",
32
37
  );
33
- process.exit(1);
38
+ return false;
34
39
  }
35
40
  const breakingChanges = checkBackwardCompatibility({
36
41
  before: oldModuleSet,
@@ -41,51 +46,65 @@ export async function takeSnapshot(args: {
41
46
  before: oldModuleSet,
42
47
  after: newModuleSet,
43
48
  });
44
- process.exit(1);
49
+ return false;
45
50
  }
46
51
  const now = new Date();
47
52
  const newSnapshot = makeSnapshot(newModuleSet, now);
48
53
  if (sameModules(newSnapshot, makeSnapshot(oldModuleSet, now))) {
49
54
  console.log("No changes detected since last snapshot.");
50
- return;
55
+ return true;
51
56
  }
52
- if (args.check) {
53
- console.error(
54
- makeRed(
55
- `Modules have changed since the last snapshot. ` +
56
- `Run the command without 'check' to take a new snapshot.`,
57
- ),
58
- );
59
- process.exit(1);
57
+ if (args.subcommand === "ci") {
58
+ console.error(makeRed("Modules have changed since the last snapshot."));
59
+ console.log("Run 'npx skir snapshot' to take a new snapshot.");
60
+ return false;
61
+ } else if (args.subcommand === "dry-run") {
62
+ console.log(makeGreen("Changes detected since last snapshot."));
63
+ console.log("No breaking changes found.");
64
+ return true;
60
65
  }
61
66
  await writeFile(snapshotPath, JSON.stringify(newSnapshot, null, 2), "utf-8");
62
67
  console.log("Snapshot taken. No breaking changes detected.");
68
+ return true;
63
69
  }
64
70
 
65
- async function readLastSnapshot(snapshotPath: string): Promise<
66
- | ModuleSet
67
- | {
68
- kind: "corrupted";
69
- error: any;
71
+ interface CorruptedError {
72
+ kind: "corrupted";
73
+ error: any;
74
+ }
75
+
76
+ async function readLastSnapshot(
77
+ snapshotPath: string,
78
+ ): Promise<ModuleSet | CorruptedError> {
79
+ let textContent: string;
80
+ try {
81
+ textContent = await readFile(snapshotPath, "utf-8");
82
+ } catch (error) {
83
+ const isNotFoundError =
84
+ error instanceof Error && "code" in error && error.code === "ENOENT";
85
+ if (isNotFoundError) {
86
+ return ModuleSet.fromMap(new Map<string, string>());
87
+ } else {
88
+ // Rethrow I/O error
89
+ throw error;
70
90
  }
71
- > {
91
+ }
92
+ return snapshotFileContentToModuleSet(textContent);
93
+ }
94
+
95
+ export function snapshotFileContentToModuleSet(
96
+ fileContent: string,
97
+ ): ModuleSet | CorruptedError {
72
98
  let snapshot: Snapshot;
73
99
  try {
74
- const textContent = await readFile(snapshotPath, "utf-8");
75
- snapshot = JSON.parse(textContent);
100
+ snapshot = JSON.parse(fileContent);
76
101
  } catch (error) {
77
102
  if (error instanceof SyntaxError) {
78
103
  return {
79
104
  kind: "corrupted",
80
105
  error: error,
81
106
  };
82
- }
83
- const isNotFoundError =
84
- error instanceof Error && "code" in error && error.code === "ENOENT";
85
- if (isNotFoundError) {
86
- return ModuleSet.fromMap(new Map<string, string>());
87
107
  } else {
88
- // Rethrow I/O error
89
108
  throw error;
90
109
  }
91
110
  }