@appthreat/atom-parsetools 1.2.1 → 1.2.2

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.
package/astgen.js CHANGED
@@ -1,17 +1,20 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { join, dirname, relative, resolve } from "path";
3
+ import { join, dirname, relative, resolve, basename } from "path";
4
4
  import { fileURLToPath } from "url";
5
5
  import { parse } from "@babel/parser";
6
6
  import { parse as parseHermes } from "hermes-parser";
7
7
  import tsc from "typescript";
8
+ import { tmpdir } from "os";
8
9
  import {
9
10
  readFileSync,
10
11
  mkdirSync,
11
12
  writeFileSync,
12
13
  accessSync,
13
14
  constants,
14
- existsSync
15
+ existsSync,
16
+ mkdtempSync,
17
+ rmSync
15
18
  } from "fs";
16
19
  import { getAllFiles } from "@appthreat/atom-common";
17
20
 
@@ -294,7 +297,10 @@ const makeBabelOptions = (
294
297
  baseOptions,
295
298
  file,
296
299
  extraPlugins = [],
297
- { enableJsxSyntax = shouldEnableJsxSyntax(file), disallowAmbiguousJSXLike } = {}
300
+ {
301
+ enableJsxSyntax = shouldEnableJsxSyntax(file),
302
+ disallowAmbiguousJSXLike
303
+ } = {}
298
304
  ) => ({
299
305
  ...baseOptions,
300
306
  plugins: mergeBabelPlugins(
@@ -427,9 +433,9 @@ const getAllSrcJSAndTSFiles = (src) => {
427
433
  /**
428
434
  * Convert a single JS/TS file to AST
429
435
  */
430
- const fileToJsAst = (file, projectType) => {
436
+ const fileToJsAst = (file, projectType, tsInstance) => {
431
437
  if (file.endsWith(".vue") || file.endsWith(".svelte")) {
432
- return toVueAst(file);
438
+ return toVueAst(file, tsInstance);
433
439
  }
434
440
  if (file.endsWith(".ejs")) {
435
441
  return toEjsAst(file);
@@ -509,12 +515,209 @@ const codeToJsAst = (file, code, projectType) => {
509
515
  }
510
516
  };
511
517
 
518
+ const vueScriptTagOnlyRegex = /<\/?script[^>]*>/gi;
519
+ const vueScriptBlockRegex = /<script\b[^>]*>[\s\S]*?<\/script>/gi;
520
+ const vueStyleBlockRegex = /<style\b[^>]*>[\s\S]*?<\/style>/gi;
521
+ const vueBrTagRegex = /<\/?br>/gi;
512
522
  const vueCleaningRegex = /<\/*script.*>|<style[\s\S]*style>|<\/*br>/gi;
513
523
  const vueTemplateRegex = /(<template.*>)([\s\S]*)(<\/template>)/gi;
514
524
  const vueCommentRegex = /<!--[\s\S]*?-->/gi;
515
525
  const vueBindRegex = /(:\[)([\s\S]*?)(\])/gi;
516
526
  const vuePropRegex = /\s([.:@])([a-zA-Z]*?=)/gi;
517
527
  const vueOpenImgTag = /(<img)((?!>)[\s\S]+?)( [^/]>)/gi;
528
+ const vueScriptTagRegex = /<script\b[^>]*>([\s\S]*?)<\/script>/gi;
529
+
530
+ const VUE_COMPILER_MACRO_SHIMS = `
531
+ declare function defineProps<T = any>(): T;
532
+ declare function defineEmits<T = any>(): T;
533
+ declare function defineExpose<T = any>(value?: T): void;
534
+ declare function defineSlots<T = any>(): T;
535
+ declare function defineModel<T = any>(
536
+ options?: { required?: boolean; default?: T }
537
+ ): import("vue").Ref<T>;
538
+ declare function defineModel<T = any>(
539
+ name: string,
540
+ options?: { required?: boolean; default?: T }
541
+ ): import("vue").Ref<T>;
542
+ declare function withDefaults<T, D>(props: T, defaults: D): T & D;
543
+
544
+ declare module "vue" {
545
+ export type Ref<T = any> = { value: T };
546
+ export type ComputedRef<T = any> = { readonly value: T };
547
+ export type InjectionKey<T> = symbol & { __type?: T };
548
+ export function ref<T>(value: T): Ref<T>;
549
+ export function ref<T = any>(): Ref<T | undefined>;
550
+ export function shallowRef<T>(value: T): Ref<T>;
551
+ export function computed<T>(getter: () => T): ComputedRef<T>;
552
+ export function inject<T>(key: any, defaultValue?: T): T;
553
+ export function provide<T>(key: any, value: T): void;
554
+ export function watch(...args: any[]): void;
555
+ export function watchEffect(effect: () => void): void;
556
+ export function onMounted(cb: () => void): void;
557
+ export function onUnmounted(cb: () => void): void;
558
+ }
559
+ `;
560
+
561
+ const maskNonNewlineChars = (value) => value.replace(/[^\r\n]/g, " ");
562
+
563
+ const cleanVueCodeForParsing = (code, { includeScripts = true } = {}) => {
564
+ let cleanedCode = code
565
+ .replace(vueCommentRegex, (match) => maskNonNewlineChars(match))
566
+ .replace(vueStyleBlockRegex, (match) => maskNonNewlineChars(match));
567
+
568
+ if (includeScripts) {
569
+ cleanedCode = cleanedCode.replace(vueScriptTagOnlyRegex, (match) => {
570
+ const masked = maskNonNewlineChars(match);
571
+ return masked.length > 0 ? `${masked.slice(1)};` : masked;
572
+ });
573
+ } else {
574
+ cleanedCode = cleanedCode.replace(vueScriptBlockRegex, (match) =>
575
+ maskNonNewlineChars(match)
576
+ );
577
+ }
578
+
579
+ return cleanedCode
580
+ .replace(vueBrTagRegex, (match) => {
581
+ const masked = maskNonNewlineChars(match);
582
+ return masked.length > 0 ? `${masked.slice(1)};` : masked;
583
+ })
584
+ .replace(vueBindRegex, (match, grA, grB, grC) => {
585
+ return maskNonNewlineChars(grA) + grB + maskNonNewlineChars(grC);
586
+ })
587
+ .replace(vuePropRegex, (match, grA, grB) => {
588
+ return " " + grA.replace(/[.:@]/g, " ") + grB.replaceAll(".", "-");
589
+ })
590
+ .replace(vueOpenImgTag, (match, grA, grB, grC) => {
591
+ return grA + grB + grC.replace(" >", "/>");
592
+ })
593
+ .replace(vueTemplateRegex, (match, grA, grB, grC) => {
594
+ return grA + grB.replaceAll("{{", "{ ").replaceAll("}}", " }") + grC;
595
+ });
596
+ };
597
+
598
+ const extractVueScriptContent = (code) => {
599
+ const scriptChunks = [];
600
+ let scriptMatch;
601
+ vueScriptBlockRegex.lastIndex = 0;
602
+ while ((scriptMatch = vueScriptBlockRegex.exec(code)) !== null) {
603
+ const fullMatch = scriptMatch[0] || "";
604
+ const content = fullMatch
605
+ .replace(/^<script\b[^>]*>/i, "")
606
+ .replace(/<\/script>$/i, "");
607
+ if (content.trim().length > 0) {
608
+ scriptChunks.push(content);
609
+ }
610
+ }
611
+ return scriptChunks.join("\n");
612
+ };
613
+
614
+ const buildVueParseCandidates = (code) => {
615
+ const fullCandidate = cleanVueCodeForParsing(code, { includeScripts: true });
616
+ const templateOnlyCandidate = cleanVueCodeForParsing(code, {
617
+ includeScripts: false
618
+ });
619
+ const scriptOnlyCandidate = extractVueScriptContent(code);
620
+ const combinedCandidate = scriptOnlyCandidate
621
+ ? `${scriptOnlyCandidate}\n${templateOnlyCandidate}`
622
+ : templateOnlyCandidate;
623
+
624
+ const candidates = [
625
+ { name: "full", code: fullCandidate },
626
+ { name: "combined", code: combinedCandidate },
627
+ { name: "template-only", code: templateOnlyCandidate },
628
+ { name: "script-only", code: scriptOnlyCandidate }
629
+ ];
630
+
631
+ const seenCandidateCode = new Set();
632
+ return candidates.filter((candidate) => {
633
+ if (!candidate.code || !candidate.code.trim()) {
634
+ return false;
635
+ }
636
+ if (seenCandidateCode.has(candidate.code)) {
637
+ return false;
638
+ }
639
+ seenCandidateCode.add(candidate.code);
640
+ return true;
641
+ });
642
+ };
643
+
644
+ const parseVueAstWithFallback = (file, code) => {
645
+ const candidates = buildVueParseCandidates(code);
646
+ let lastError;
647
+ for (const candidate of candidates) {
648
+ try {
649
+ return codeToJsAst(file, candidate.code, "ts");
650
+ } catch (err) {
651
+ lastError = err;
652
+ }
653
+ }
654
+ throw lastError || new Error(`Unable to parse Vue file: ${file}`);
655
+ };
656
+
657
+ const createVueVirtualTypeSource = (code) => {
658
+ const output = maskNonNewlineChars(code).split("");
659
+ let hasScriptContent = false;
660
+ let scriptMatch;
661
+ vueScriptTagRegex.lastIndex = 0;
662
+ while ((scriptMatch = vueScriptTagRegex.exec(code)) !== null) {
663
+ const fullMatch = scriptMatch[0];
664
+ const scriptContent = scriptMatch[1] || "";
665
+ const contentStart = scriptMatch.index + fullMatch.indexOf(scriptContent);
666
+ if (scriptContent.trim().length > 0) {
667
+ hasScriptContent = true;
668
+ }
669
+ for (let index = 0; index < scriptContent.length; index++) {
670
+ output[contentStart + index] = scriptContent[index];
671
+ }
672
+ }
673
+ return {
674
+ source: output.join(""),
675
+ hasScriptContent
676
+ };
677
+ };
678
+
679
+ const collectVueTypesWithVirtualProgram = (file, virtualSource) => {
680
+ const tempDir = mkdtempSync(join(tmpdir(), "atom-parsetools-vue-"));
681
+ const virtualFile = join(tempDir, `${basename(file)}.ts`);
682
+ const shimFile = join(tempDir, "vue-shims.d.ts");
683
+ try {
684
+ writeFileSync(virtualFile, virtualSource, "utf8");
685
+ writeFileSync(shimFile, VUE_COMPILER_MACRO_SHIMS, "utf8");
686
+ const virtualTs = createTsc([virtualFile, shimFile], tempDir);
687
+ const sourceFile = virtualTs?.program?.getSourceFile(virtualFile);
688
+ if (!virtualTs || !sourceFile) {
689
+ return new Map();
690
+ }
691
+ return virtualTs.collectTypes(sourceFile);
692
+ } catch {
693
+ return new Map();
694
+ } finally {
695
+ rmSync(tempDir, { recursive: true, force: true });
696
+ }
697
+ };
698
+
699
+ const collectVueSeenTypes = (file, code, tsInstance) => {
700
+ let seenTypes;
701
+ if (tsInstance?.program) {
702
+ try {
703
+ const tsSrc = tsInstance.program.getSourceFile(file);
704
+ if (tsSrc) {
705
+ seenTypes = tsInstance.collectTypes(tsSrc);
706
+ }
707
+ } catch {
708
+ // Ignore and continue with virtual source fallback below.
709
+ }
710
+ }
711
+
712
+ if (!seenTypes || seenTypes.size === 0) {
713
+ const virtualSource = createVueVirtualTypeSource(code);
714
+ if (virtualSource.hasScriptContent) {
715
+ seenTypes = collectVueTypesWithVirtualProgram(file, virtualSource.source);
716
+ }
717
+ }
718
+
719
+ return seenTypes;
720
+ };
518
721
 
519
722
  const TSC_FLAGS =
520
723
  tsc.TypeFormatFlags.NoTruncation |
@@ -526,30 +729,43 @@ const TSC_FLAGS =
526
729
  tsc.TypeFormatFlags.NoTypeReduction;
527
730
 
528
731
  /**
529
- * Convert a single vue file to AST
732
+ * Convert a single vue file to AST.
733
+ * When `tsInstance` is present also collect type inference from TSC and return both AST & types.
530
734
  */
531
- const toVueAst = (file) => {
735
+ const toVueAst = (file, tsInstance) => {
532
736
  const code = readFileSync(file, "utf-8");
533
- const cleanedCode = code
534
- .replace(vueCommentRegex, function (match) {
535
- return match.replaceAll(/\S/g, " ");
536
- })
537
- .replace(vueCleaningRegex, function (match) {
538
- return match.replaceAll(/\S/g, " ").substring(1) + ";";
539
- })
540
- .replace(vueBindRegex, function (match, grA, grB, grC) {
541
- return grA.replaceAll(/\S/g, " ") + grB + grC.replaceAll(/\S/g, " ");
542
- })
543
- .replace(vuePropRegex, function (match, grA, grB) {
544
- return " " + grA.replace(/[.:@]/g, " ") + grB.replaceAll(".", "-");
545
- })
546
- .replace(vueOpenImgTag, function (match, grA, grB, grC) {
547
- return grA + grB + grC.replace(" >", "/>");
548
- })
549
- .replace(vueTemplateRegex, function (match, grA, grB, grC) {
550
- return grA + grB.replaceAll("{{", "{ ").replaceAll("}}", " }") + grC;
551
- });
552
- return codeToJsAst(file, cleanedCode, "ts");
737
+ return parseVueAstWithFallback(file, code);
738
+ };
739
+
740
+ const collectSeenTypesForFile = (file, ts, options) => {
741
+ if (!options?.tsTypes) {
742
+ return undefined;
743
+ }
744
+
745
+ if (file.endsWith(".vue")) {
746
+ return collectVueSeenTypes(file, readFileSync(file, "utf-8"), ts);
747
+ }
748
+
749
+ if (!ts?.program) {
750
+ return undefined;
751
+ }
752
+
753
+ try {
754
+ const tsAst = ts.program.getSourceFile(file);
755
+ if (!tsAst) {
756
+ return undefined;
757
+ }
758
+ return ts.collectTypes
759
+ ? ts.collectTypes(tsAst)
760
+ : (() => {
761
+ tsc.forEachChild(tsAst, ts.addType);
762
+ const collectedTypes = new Map(ts.seenTypes);
763
+ ts.seenTypes.clear();
764
+ return collectedTypes;
765
+ })();
766
+ } catch {
767
+ return undefined;
768
+ }
553
769
  };
554
770
 
555
771
  /**
@@ -707,7 +923,7 @@ const DEFAULT_TSC_OPTIONS = {
707
923
 
708
924
  const readJsonFileIfExists = (file) => {
709
925
  try {
710
- if (!existsSync(file)) {
926
+ if (!file || !existsSync(file)) {
711
927
  return undefined;
712
928
  }
713
929
  return JSON.parse(readFileSync(file, "utf8"));
@@ -732,7 +948,10 @@ const findNearestPackageJson = (src) => {
732
948
  };
733
949
 
734
950
  const detectDefaultTscOptions = (srcFiles, src) => {
735
- const packageJson = readJsonFileIfExists(findNearestPackageJson(src));
951
+ const nearPackageJson = findNearestPackageJson(src);
952
+ const packageJson = nearPackageJson
953
+ ? readJsonFileIfExists(nearPackageJson)
954
+ : undefined;
736
955
  const usesNodeNextModuleResolution =
737
956
  packageJson?.type === "module" ||
738
957
  Boolean(packageJson?.exports) ||
@@ -895,7 +1114,10 @@ function createTsc(srcFiles, src) {
895
1114
  return undefined;
896
1115
  }
897
1116
  try {
898
- return safeTypeToString(typeChecker.getTypeFromTypeNode(typeNode), typeNode);
1117
+ return safeTypeToString(
1118
+ typeChecker.getTypeFromTypeNode(typeNode),
1119
+ typeNode
1120
+ );
899
1121
  } catch {
900
1122
  return undefined;
901
1123
  }
@@ -984,7 +1206,6 @@ function createTsc(srcFiles, src) {
984
1206
  return collectedTypes;
985
1207
  }
986
1208
  if (
987
- node !== undefined &&
988
1209
  !tsc.isFunctionDeclaration(node) &&
989
1210
  !tsc.isFunctionExpression(node) &&
990
1211
  !tsc.isArrowFunction(node) &&
@@ -1256,10 +1477,13 @@ function createTsc(srcFiles, src) {
1256
1477
  node.kind === tsc.SyntaxKind.VariableDeclaration &&
1257
1478
  node.name
1258
1479
  ) {
1259
- const explicitDeclaredType = getExplicitTypeAnnotationString(node.type);
1480
+ const explicitDeclaredType = getExplicitTypeAnnotationString(
1481
+ node.type
1482
+ );
1260
1483
  const varType = typeChecker.getTypeAtLocation(node.name);
1261
1484
  typeStr =
1262
- explicitDeclaredType && !isUnresolvedTypeString(explicitDeclaredType)
1485
+ explicitDeclaredType &&
1486
+ !isUnresolvedTypeString(explicitDeclaredType)
1263
1487
  ? explicitDeclaredType
1264
1488
  : safeTypeWithContextToString(varType, node.name);
1265
1489
  if (node.initializer && !explicitDeclaredType) {
@@ -1602,25 +1826,12 @@ const createJSAst = async (options) => {
1602
1826
 
1603
1827
  const processFile = (file, options, ts) => {
1604
1828
  try {
1605
- const ast = fileToJsAst(file, options.type);
1829
+ const ast = fileToJsAst(file, options.type, ts);
1606
1830
  writeAstFile(file, ast, options);
1607
- if (ts) {
1608
- try {
1609
- const tsAst = ts.program.getSourceFile(file);
1610
- if (tsAst) {
1611
- const seenTypes = ts.collectTypes
1612
- ? ts.collectTypes(tsAst)
1613
- : (() => {
1614
- tsc.forEachChild(tsAst, ts.addType);
1615
- const collectedTypes = new Map(ts.seenTypes);
1616
- ts.seenTypes.clear();
1617
- return collectedTypes;
1618
- })();
1619
- writeTypesFile(file, seenTypes, options);
1620
- }
1621
- } catch (err) {
1622
- console.warn("Process file", file, ":", err.message);
1623
- }
1831
+
1832
+ const seenTypes = collectSeenTypesForFile(file, ts, options);
1833
+ if (seenTypes && seenTypes.size > 0) {
1834
+ writeTypesFile(file, seenTypes, options);
1624
1835
  }
1625
1836
  } catch (err) {
1626
1837
  console.error("Failure:", file, err?.message);
package/package.json CHANGED
@@ -1,15 +1,16 @@
1
1
  {
2
2
  "name": "@appthreat/atom-parsetools",
3
- "version": "1.2.1",
3
+ "version": "1.2.2",
4
4
  "description": "Parsing tools that complement the @appthreat/atom project.",
5
5
  "main": "./index.js",
6
6
  "type": "module",
7
7
  "scripts": {
8
8
  "pretty": "prettier --write *.js --trailing-comma=none",
9
- "test": "node test-fixtures/astgen-type-regression.js && node test-fixtures/astgen-json-regression.js && node test-fixtures/evaluate-astgen.js",
9
+ "test": "node test-fixtures/astgen-type-regression.js && node test-fixtures/astgen-json-regression.js && node test-fixtures/astgen-vue-regression.js && node test-fixtures/evaluate-astgen.js",
10
10
  "test:evaluate": "node test-fixtures/evaluate-astgen.js",
11
11
  "test:json": "node test-fixtures/astgen-json-regression.js",
12
- "test:fixtures": "node test-fixtures/test-suite.js"
12
+ "test:fixtures": "node test-fixtures/test-suite.js",
13
+ "test:vue": "node test-fixtures/astgen-vue-regression.js"
13
14
  },
14
15
  "dependencies": {
15
16
  "@appthreat/atom-common": "^1.1.0",
@@ -1,9 +1,9 @@
1
1
  <?php return array(
2
2
  'root' => array(
3
3
  'name' => '__root__',
4
- 'pretty_version' => 'v1.2.1',
5
- 'version' => '1.2.1.0',
6
- 'reference' => 'afc68f061af5b27948f4408573df918fdbda4162',
4
+ 'pretty_version' => 'v1.2.2',
5
+ 'version' => '1.2.2.0',
6
+ 'reference' => 'b9f033619acc028cb38187ef6862197115be0713',
7
7
  'type' => 'library',
8
8
  'install_path' => __DIR__ . '/../../',
9
9
  'aliases' => array(),
@@ -11,9 +11,9 @@
11
11
  ),
12
12
  'versions' => array(
13
13
  '__root__' => array(
14
- 'pretty_version' => 'v1.2.1',
15
- 'version' => '1.2.1.0',
16
- 'reference' => 'afc68f061af5b27948f4408573df918fdbda4162',
14
+ 'pretty_version' => 'v1.2.2',
15
+ 'version' => '1.2.2.0',
16
+ 'reference' => 'b9f033619acc028cb38187ef6862197115be0713',
17
17
  'type' => 'library',
18
18
  'install_path' => __DIR__ . '/../../',
19
19
  'aliases' => array(),
@@ -6,10 +6,10 @@ checking for whether -fvisibility=hidden is accepted as CFLAGS... yes
6
6
  creating Makefile
7
7
 
8
8
  current directory: /home/runner/work/atom-parsetools/atom-parsetools/plugins/rubyastgen/bundle/ruby/4.0.0/gems/prism-1.9.0/ext/prism
9
- make -j5 DESTDIR\= sitearchdir\=./.gem.20260527-2573-bep84q sitelibdir\=./.gem.20260527-2573-bep84q clean
9
+ make -j5 DESTDIR\= sitearchdir\=./.gem.20260529-2620-sigov3 sitelibdir\=./.gem.20260529-2620-sigov3 clean
10
10
 
11
11
  current directory: /home/runner/work/atom-parsetools/atom-parsetools/plugins/rubyastgen/bundle/ruby/4.0.0/gems/prism-1.9.0/ext/prism
12
- make -j5 DESTDIR\= sitearchdir\=./.gem.20260527-2573-bep84q sitelibdir\=./.gem.20260527-2573-bep84q
12
+ make -j5 DESTDIR\= sitearchdir\=./.gem.20260529-2620-sigov3 sitelibdir\=./.gem.20260529-2620-sigov3
13
13
  compiling api_node.c
14
14
  compiling api_pack.c
15
15
  compiling extension.c
@@ -37,8 +37,8 @@ compiling ./../../src/util/pm_strpbrk.c
37
37
  linking shared-object prism/prism.so
38
38
 
39
39
  current directory: /home/runner/work/atom-parsetools/atom-parsetools/plugins/rubyastgen/bundle/ruby/4.0.0/gems/prism-1.9.0/ext/prism
40
- make -j5 DESTDIR\= sitearchdir\=./.gem.20260527-2573-bep84q sitelibdir\=./.gem.20260527-2573-bep84q install
41
- /usr/bin/install -c -m 0755 prism.so ./.gem.20260527-2573-bep84q/prism
40
+ make -j5 DESTDIR\= sitearchdir\=./.gem.20260529-2620-sigov3 sitelibdir\=./.gem.20260529-2620-sigov3 install
41
+ /usr/bin/install -c -m 0755 prism.so ./.gem.20260529-2620-sigov3/prism
42
42
 
43
43
  current directory: /home/runner/work/atom-parsetools/atom-parsetools/plugins/rubyastgen/bundle/ruby/4.0.0/gems/prism-1.9.0/ext/prism
44
- make DESTDIR\= sitearchdir\=./.gem.20260527-2573-bep84q sitelibdir\=./.gem.20260527-2573-bep84q clean
44
+ make DESTDIR\= sitearchdir\=./.gem.20260529-2620-sigov3 sitelibdir\=./.gem.20260529-2620-sigov3 clean
@@ -3,16 +3,16 @@ current directory: /home/runner/work/atom-parsetools/atom-parsetools/plugins/rub
3
3
  creating Makefile
4
4
 
5
5
  current directory: /home/runner/work/atom-parsetools/atom-parsetools/plugins/rubyastgen/bundle/ruby/4.0.0/gems/racc-1.8.1/ext/racc/cparse
6
- make -j5 DESTDIR\= sitearchdir\=./.gem.20260527-2573-dcu8v1 sitelibdir\=./.gem.20260527-2573-dcu8v1 clean
6
+ make -j5 DESTDIR\= sitearchdir\=./.gem.20260529-2620-ugqqux sitelibdir\=./.gem.20260529-2620-ugqqux clean
7
7
 
8
8
  current directory: /home/runner/work/atom-parsetools/atom-parsetools/plugins/rubyastgen/bundle/ruby/4.0.0/gems/racc-1.8.1/ext/racc/cparse
9
- make -j5 DESTDIR\= sitearchdir\=./.gem.20260527-2573-dcu8v1 sitelibdir\=./.gem.20260527-2573-dcu8v1
9
+ make -j5 DESTDIR\= sitearchdir\=./.gem.20260529-2620-ugqqux sitelibdir\=./.gem.20260529-2620-ugqqux
10
10
  compiling cparse.c
11
11
  linking shared-object racc/cparse.so
12
12
 
13
13
  current directory: /home/runner/work/atom-parsetools/atom-parsetools/plugins/rubyastgen/bundle/ruby/4.0.0/gems/racc-1.8.1/ext/racc/cparse
14
- make -j5 DESTDIR\= sitearchdir\=./.gem.20260527-2573-dcu8v1 sitelibdir\=./.gem.20260527-2573-dcu8v1 install
15
- /usr/bin/install -c -m 0755 cparse.so ./.gem.20260527-2573-dcu8v1/racc
14
+ make -j5 DESTDIR\= sitearchdir\=./.gem.20260529-2620-ugqqux sitelibdir\=./.gem.20260529-2620-ugqqux install
15
+ /usr/bin/install -c -m 0755 cparse.so ./.gem.20260529-2620-ugqqux/racc
16
16
 
17
17
  current directory: /home/runner/work/atom-parsetools/atom-parsetools/plugins/rubyastgen/bundle/ruby/4.0.0/gems/racc-1.8.1/ext/racc/cparse
18
- make DESTDIR\= sitearchdir\=./.gem.20260527-2573-dcu8v1 sitelibdir\=./.gem.20260527-2573-dcu8v1 clean
18
+ make DESTDIR\= sitearchdir\=./.gem.20260529-2620-ugqqux sitelibdir\=./.gem.20260529-2620-ugqqux clean