@shd101wyy/yo 0.1.16 → 0.1.18

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@shd101wyy/yo",
3
3
  "displayName": "Yo",
4
- "version": "0.1.16",
4
+ "version": "0.1.18",
5
5
  "main": "./out/cjs/index.cjs",
6
6
  "module": "./out/esm/index.mjs",
7
7
  "types": "./out/types/src/index.d.ts",
@@ -13,7 +13,8 @@
13
13
  "out",
14
14
  "scripts",
15
15
  "vendor",
16
- "std"
16
+ "std",
17
+ ".github/skills"
17
18
  ],
18
19
  "repository": "https://github.com/shd101wyy/yo",
19
20
  "author": "Yiyi Wang <shd101wyy@gmail.com>",
@@ -25,25 +25,26 @@ import { execFileSync } from "child_process";
25
25
  const ROOT = path.resolve(import.meta.dir, "..");
26
26
  const GITHUB_REPO = "https://github.com/shd101wyy/Yo";
27
27
 
28
- // Detect the latest release tag for stable links.
29
- // Falls back to "main" if no tags exist or git fails.
30
- export function getLatestTag(rootDir: string = ROOT): string {
28
+ // Detect the exact tag on HEAD for stable GitHub blob links.
29
+ // Falls back to "develop" if HEAD has no exact tag or git fails.
30
+ export function getExactTagOrDevelop(rootDir: string = ROOT): string {
31
31
  try {
32
- const result = execFileSync("git", ["describe", "--tags", "--abbrev=0"], {
33
- cwd: rootDir,
34
- encoding: "utf-8",
35
- stdio: ["ignore", "pipe", "ignore"],
36
- timeout: 5000,
37
- }).trim();
38
- return result || "main";
32
+ const result = execFileSync(
33
+ "git",
34
+ ["describe", "--tags", "--exact-match", "HEAD"],
35
+ {
36
+ cwd: rootDir,
37
+ encoding: "utf-8",
38
+ stdio: ["ignore", "pipe", "ignore"],
39
+ timeout: 5000,
40
+ }
41
+ ).trim();
42
+ return result || "develop";
39
43
  } catch {
40
- return "main";
44
+ return "develop";
41
45
  }
42
46
  }
43
47
 
44
- const GITHUB_REF = getLatestTag();
45
- const GITHUB_BLOB = `${GITHUB_REPO}/blob/${GITHUB_REF}`;
46
-
47
48
  export function getStdDocCommand(rootDir: string = ROOT): {
48
49
  command: string;
49
50
  args: string[];
@@ -57,12 +58,50 @@ export function getStdDocCommand(rootDir: string = ROOT): {
57
58
  // ── Parse args ───────────────────────────────────────────────────────
58
59
 
59
60
  let outputDir = path.join(ROOT, "site");
61
+ let siteVersion: string | undefined;
60
62
  const args = process.argv.slice(2);
61
63
  for (let i = 0; i < args.length; i++) {
62
64
  if (args[i] === "--output" && args[i + 1]) {
63
65
  outputDir = path.resolve(args[i + 1]!);
64
66
  i++;
67
+ } else if (args[i] === "--version" && args[i + 1]) {
68
+ siteVersion = args[i + 1]!;
69
+ i++;
70
+ }
71
+ }
72
+
73
+ // Fallback: auto-detect version from git (tag or commit hash)
74
+ if (!siteVersion) {
75
+ siteVersion = detectGitVersion(ROOT);
76
+ }
77
+
78
+ // Use the explicit version (e.g., "v0.1.17" from --version flag) for blob links
79
+ // when it looks like a tag; otherwise use the exact tag on HEAD; otherwise "develop".
80
+ const GITHUB_REF =
81
+ siteVersion && /^v\d/.test(siteVersion)
82
+ ? siteVersion
83
+ : getExactTagOrDevelop(ROOT);
84
+ const GITHUB_BLOB = `${GITHUB_REPO}/blob/${GITHUB_REF}`;
85
+
86
+ function detectGitVersion(cwd: string): string | undefined {
87
+ function git(...gitArgs: string[]): string | undefined {
88
+ try {
89
+ return (
90
+ execFileSync("git", gitArgs, {
91
+ cwd,
92
+ encoding: "utf-8",
93
+ timeout: 5000,
94
+ }).trim() || undefined
95
+ );
96
+ } catch {
97
+ return undefined;
98
+ }
65
99
  }
100
+ // Show exact tag only if HEAD is exactly at that tag; otherwise show short commit hash
101
+ return (
102
+ git("describe", "--tags", "--exact-match", "HEAD") ??
103
+ git("rev-parse", "--short", "HEAD")
104
+ );
66
105
  }
67
106
 
68
107
  // ── Helpers ──────────────────────────────────────────────────────────
@@ -306,6 +345,17 @@ th {
306
345
  margin-top: 8px;
307
346
  }
308
347
 
348
+ .version-badge {
349
+ font-size: 0.4em;
350
+ font-weight: 500;
351
+ color: var(--accent);
352
+ background: var(--bg-secondary);
353
+ padding: 2px 10px;
354
+ border-radius: 4px;
355
+ vertical-align: middle;
356
+ margin-left: 8px;
357
+ }
358
+
309
359
  .site-nav {
310
360
  margin-top: 16px;
311
361
  display: flex;
@@ -341,7 +391,15 @@ th {
341
391
  `;
342
392
  }
343
393
 
344
- function wrapHomepage(title: string, bodyHtml: string, css: string): string {
394
+ function wrapHomepage(
395
+ title: string,
396
+ bodyHtml: string,
397
+ css: string,
398
+ version?: string
399
+ ): string {
400
+ const versionBadge = version
401
+ ? `<span class="version-badge">${escapeHtml(version)}</span>`
402
+ : "";
345
403
  return `<!DOCTYPE html>
346
404
  <html lang="en">
347
405
  <head>
@@ -354,7 +412,7 @@ function wrapHomepage(title: string, bodyHtml: string, css: string): string {
354
412
  <div class="container">
355
413
  <div class="site-header">
356
414
  <img src="Yo_logo.png" alt="Yo logo" width="80" height="80">
357
- <h1>Yo Programming Language</h1>
415
+ <h1>Yo Programming Language ${versionBadge}</h1>
358
416
  <p class="tagline">A general-purpose, ahead-of-time compiled language with algebraic effects</p>
359
417
  <div class="site-nav">
360
418
  <a href="${GITHUB_REPO}">GitHub</a>
@@ -434,7 +492,12 @@ export async function main(): Promise<void> {
434
492
  readmeHtml = rewriteReadmeLinks(readmeHtml);
435
493
 
436
494
  const css = generateHomepageCSS();
437
- const homepage = wrapHomepage("Yo Programming Language", readmeHtml, css);
495
+ const homepage = wrapHomepage(
496
+ "Yo Programming Language",
497
+ readmeHtml,
498
+ css,
499
+ siteVersion
500
+ );
438
501
  fs.writeFileSync(path.join(outputDir, "index.html"), homepage, "utf-8");
439
502
  console.log(" ✓ index.html");
440
503
 
@@ -461,15 +524,15 @@ export async function main(): Promise<void> {
461
524
 
462
525
  try {
463
526
  const stdDocCommand = getStdDocCommand();
464
- execFileSync(
465
- stdDocCommand.command,
466
- [...stdDocCommand.args, "--output", stdOutputDir],
467
- {
468
- cwd: ROOT,
469
- stdio: ["ignore", "inherit", "inherit"],
470
- timeout: 600_000,
471
- }
472
- );
527
+ const docArgs = [...stdDocCommand.args, "--output", stdOutputDir];
528
+ if (siteVersion) {
529
+ docArgs.push("--version", siteVersion);
530
+ }
531
+ execFileSync(stdDocCommand.command, docArgs, {
532
+ cwd: ROOT,
533
+ stdio: ["ignore", "inherit", "inherit"],
534
+ timeout: 600_000,
535
+ });
473
536
  console.log(" ✓ Standard library docs generated");
474
537
  } catch (err) {
475
538
  console.error(
package/std/build.yo CHANGED
@@ -460,6 +460,9 @@ DocConfig :: struct(
460
460
  (include_deps : bool) ?= false,
461
461
  /// Custom site title (default: project name).
462
462
  (title : comptime_string) ?= "",
463
+ /// Release version to display (e.g., "v1.0.0").
464
+ /// When empty, auto-detects from git tag or commit hash.
465
+ (version : comptime_string) ?= "",
463
466
  /// Path to logo image.
464
467
  (logo : comptime_string) ?= "",
465
468
  /// Path to favicon.
@@ -483,7 +486,8 @@ export DocConfig;
483
486
  /// root: "./src",
484
487
  /// output: "docs/api",
485
488
  /// format: DocFormat.Markdown,
486
- /// title: "My Library API"
489
+ /// title: "My Library API",
490
+ /// version: "v1.0.0"
487
491
  /// });
488
492
  ///
489
493
  /// install :: build.step("install", "Build all artifacts");
@@ -498,7 +502,8 @@ doc :: (fn(comptime(config) : DocConfig) -> comptime(Step)) {
498
502
  __yo_build_doc(
499
503
  config.name, config.root, config.output, fmt_str,
500
504
  config.include_private, config.include_deps,
501
- config.title, config.logo, config.favicon
505
+ config.title, config.logo, config.favicon,
506
+ config.version
502
507
  );
503
508
  Step(name: config.name, kind: StepKind.Documentation)
504
509
  };
@@ -490,7 +490,10 @@ impl(forall(T : Type), ArrayList(T),
490
490
  })
491
491
  );
492
492
  impl(forall(T : Type), ArrayList(T), Index(usize)(
493
+ /// The output type is the element type `T`.
493
494
  Output : T,
495
+
496
+ /// Returns a pointer to the element at the given index. Panics if the index is out of bounds.
494
497
  index : (fn(self: *(Self), idx: usize) -> *(Self.Output))({
495
498
  assert((idx < self.*._length), "ArrayList: index out of bounds");
496
499
  match(self.*._ptr,