This is an automated email from the ASF dual-hosted git repository.

sciabarracom pushed a commit to branch 0.9.1
in repository https://gitbox.apache.org/repos/asf/openserverless-task.git

commit be83eae2d19a4adebc6cb0b59e096d7a69939f36
Author: Trustable User <[email protected]>
AuthorDate: Sun Jul 12 12:01:36 2026 +0200

    Update Bun to 1.3.14
---
 ide/install-dependencies.test.ts |  70 +++++++++++++++++++++
 ide/install-dependencies.ts      | 133 +++++++++++++++++++++++++++++++++++++++
 ide/opsfile.yml                  |  26 +-------
 prereq.yml                       |   6 +-
 tests/opsfile.yml                |   2 +-
 5 files changed, 210 insertions(+), 27 deletions(-)

diff --git a/ide/install-dependencies.test.ts b/ide/install-dependencies.test.ts
new file mode 100644
index 0000000..0e0aa40
--- /dev/null
+++ b/ide/install-dependencies.test.ts
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { expect, test } from "bun:test";
+import {
+  access,
+  mkdtemp,
+  mkdir,
+  readFile,
+  rm,
+  writeFile,
+} from "node:fs/promises";
+import { tmpdir } from "node:os";
+import { join } from "node:path";
+
+import { installDependencies } from "./install-dependencies";
+
+async function exists(path: string): Promise<boolean> {
+  try {
+    await access(path);
+    return true;
+  } catch {
+    return false;
+  }
+}
+
+test("replaces a partial install and skips a verified install", async () => {
+  const projectDir = await mkdtemp(join(tmpdir(), "ops-bun-install-test-"));
+  const nodeModules = join(projectDir, "node_modules");
+
+  try {
+    await writeFile(
+      join(projectDir, "package.json"),
+      JSON.stringify({ name: "dependency-test", private: true }),
+    );
+    await mkdir(nodeModules);
+    await writeFile(join(nodeModules, "partial-download"), "incomplete");
+
+    expect(await installDependencies(projectDir)).toBe(true);
+    expect(await exists(join(nodeModules, "partial-download"))).toBe(false);
+
+    const state = await readFile(
+      join(nodeModules, ".ops-bun-install-state"),
+      "utf8",
+    );
+    expect(state.trim()).toHaveLength(64);
+
+    await writeFile(join(nodeModules, "verified-install"), "keep");
+    expect(await installDependencies(projectDir)).toBe(false);
+    expect(await exists(join(nodeModules, "verified-install"))).toBe(true);
+  } finally {
+    await rm(projectDir, { recursive: true, force: true });
+  }
+});
diff --git a/ide/install-dependencies.ts b/ide/install-dependencies.ts
new file mode 100644
index 0000000..7afd147
--- /dev/null
+++ b/ide/install-dependencies.ts
@@ -0,0 +1,133 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { createHash } from "node:crypto";
+import {
+  access,
+  mkdir,
+  mkdtemp,
+  readFile,
+  rm,
+  writeFile,
+} from "node:fs/promises";
+import { tmpdir } from "node:os";
+import { basename, join, resolve } from "node:path";
+
+const stateFileName = ".ops-bun-install-state";
+const dependencyInputs = [
+  "package.json",
+  "bun.lock",
+  "bun.lockb",
+  "package-lock.json",
+  "pnpm-lock.yaml",
+  "yarn.lock",
+];
+
+async function exists(path: string): Promise<boolean> {
+  try {
+    await access(path);
+    return true;
+  } catch {
+    return false;
+  }
+}
+
+async function dependencyState(projectDir: string): Promise<string> {
+  const hash = createHash("sha256");
+  hash.update(`bun:${Bun.version}\n`);
+
+  for (const name of dependencyInputs) {
+    const path = join(projectDir, name);
+    if (await exists(path)) {
+      hash.update(`${name}\0`);
+      hash.update(await readFile(path));
+    }
+  }
+
+  return hash.digest("hex");
+}
+
+export async function installDependencies(projectPath: string): 
Promise<boolean> {
+  const projectDir = resolve(projectPath);
+  const packageJson = join(projectDir, "package.json");
+  if (!(await exists(packageJson))) {
+    throw new Error(`package.json not found in ${projectDir}`);
+  }
+
+  const nodeModules = join(projectDir, "node_modules");
+  const stateFile = join(nodeModules, stateFileName);
+  const expectedState = await dependencyState(projectDir);
+
+  if (await exists(stateFile)) {
+    const installedState = (await readFile(stateFile, "utf8")).trim();
+    if (installedState === expectedState) {
+      return false;
+    }
+  }
+
+  await rm(nodeModules, { recursive: true, force: true });
+  const cacheDir = await mkdtemp(join(tmpdir(), "openserverless-bun-cache-"));
+
+  try {
+    const install = Bun.spawn(
+      [
+        process.execPath,
+        "install",
+        "--no-save",
+        "--no-cache",
+        "--cache-dir",
+        cacheDir,
+        "--network-concurrency=1",
+      ],
+      {
+        cwd: projectDir,
+        env: process.env,
+        stdout: "inherit",
+        stderr: "inherit",
+      },
+    );
+    const exitCode = await install.exited;
+    if (exitCode !== 0) {
+      throw new Error(
+        `bun install failed with exit code ${exitCode} in ${projectDir}`,
+      );
+    }
+
+    await mkdir(nodeModules, { recursive: true });
+    await writeFile(stateFile, `${expectedState}\n`);
+    return true;
+  } finally {
+    await rm(cacheDir, { recursive: true, force: true });
+  }
+}
+
+if (import.meta.main) {
+  const projectDir = Bun.argv[2];
+  if (!projectDir) {
+    console.error(`Usage: bun ${basename(Bun.argv[1])} <project-directory>`);
+    process.exit(2);
+  }
+
+  try {
+    await installDependencies(projectDir);
+  } catch (error) {
+    console.error(error instanceof Error ? error.message : String(error));
+    process.exit(1);
+  }
+}
diff --git a/ide/opsfile.yml b/ide/opsfile.yml
index 89f83dd..4ca3369 100644
--- a/ide/opsfile.yml
+++ b/ide/opsfile.yml
@@ -23,20 +23,6 @@ vars:
     sh: |
       echo "http://localhost:80";
 
-  DEPLOY_CURRENT_HASH:
-    sh: |
-      if test -e "$OPS_ROOT/ide/deploy/bun.lockb"
-      then cd "$OPS_ROOT/ide/deploy" && bun "$OPS_ROOT/ide/deploy/bun.lockb" 
--hash
-      else echo "0"
-      fi
-
-  DEPLOY_PREVIOUS_HASH:
-    sh: |
-      if test -e "$OPS_ROOT/ide/deploy/hash.lock"
-      then cat "$OPS_ROOT/ide/deploy/hash.lock"
-      else echo "0"
-      fi
-
 tasks:
 
   prereq:
@@ -49,21 +35,15 @@ tasks:
             You can also reopen the project with VSCode and use the command 
'Reopen in Container'.
     cmds:
       - test {{OS}} != "windows" || die '{{.MSG}}'
-      - test "$(printf '%s\n' "$(bun -v)" "1.1.18" | sort -V | head -n 1)" = 
"1.1.18" || die "bun 1.1.18 or greater not available"
+      - test "$(printf '%s\n' "$(bun -v)" "1.3.14" | sort -V | head -n 1)" = 
"1.3.14" || die "bun 1.3.14 or greater not available"
       - test -d "$OPS_PWD/packages" || die "no packages in current directory"
       - test -e ~/.wskprops || die "please run 'ops ide login' first"
       - test -n "$OPSDEV_HOST" || die "please run 'ops ide login' first"
       - test "$(ops -wsk property get --namespace | awk '{ print $3 }')" = 
"$OPSDEV_USERNAME" || die "Repeat the login"
-      - |
-        if ! test -d "$OPS_ROOT/ide/deploy/node_modules" || [ 
"{{.DEPLOY_CURRENT_HASH}}" != "{{.DEPLOY_PREVIOUS_HASH}}" ]
-          then
-            cd $OPS_ROOT/ide/deploy && bun install && rm -f 
$OPS_ROOT/ide/deploy/hash.lock && bun $OPS_ROOT/ide/deploy/bun.lockb --hash > 
$OPS_ROOT/ide/deploy/hash.lock
-        fi
+      - bun "$OPS_ROOT/ide/install-dependencies.ts" "$OPS_ROOT/ide/deploy"
       - |
         if test -e "$OPS_PWD/package.json"
-        then if ! test -d "$OPS_PWD/node_modules"
-             then cd $OPS_PWD ; bun install
-             fi
+        then bun "$OPS_ROOT/ide/install-dependencies.ts" "$OPS_PWD"
         fi
       - task: kill
 
diff --git a/prereq.yml b/prereq.yml
index bd866ca..ce70e3c 100644
--- a/prereq.yml
+++ b/prereq.yml
@@ -102,14 +102,15 @@ tasks:
   bun:
     desc: download bun
     vars:
-      VERSION: "1.2.5"
+      VERSION: "1.3.14"
       ARCH2: '{{if eq .ARCH "amd64"}}x64{{else}}aarch64{{end}}'
       URL: 
'https://github.com/oven-sh/bun/releases/download/bun-v{{.VERSION}}/bun-{{.OS}}-{{.ARCH2}}.zip'
       FILE: '{{base .URL}}'
     cmds:
     - echo "{{.URL}}"
-    - curl -sL "{{.URL}}" -o "{{.FILE}}"
+    - curl -fsSL "{{.URL}}" -o "{{.FILE}}"
     - extract "{{.FILE}}" bun{{.EXE}}
+    - executable bun{{.EXE}}
     - remove "{{.FILE}}"
 
   kubectl:
@@ -385,4 +386,3 @@ tasks:
    - __OS=darwin  __ARCH=amd64 ops -task -t prereq.yml test
    - __OS=darwin  __ARCH=arm64 ops -task -t prereq.yml test
    - __OS=windows __ARCH=amd64 ops -task -t prereq.yml test
-
diff --git a/tests/opsfile.yml b/tests/opsfile.yml
index 8549147..2a8e234 100644
--- a/tests/opsfile.yml
+++ b/tests/opsfile.yml
@@ -46,7 +46,7 @@ tasks:
     silent: true
     desc: Bun test
     cmds:
-    - bun | rg '1.1.27'
+    - bun --version | rg '^1.3.14$'
 
   kubectl:
     silent: true

Reply via email to