diff options
author | 2021-10-28 05:34:38 -0700 | |
---|---|---|
committer | 2021-10-28 05:34:38 -0700 | |
commit | a44cb9708f8a1460a2851bc3357d2cec655f7ee2 (patch) | |
tree | 3e1e31d0cd13f86228d493635e41dfe66e1c84e6 | |
parent | c7fc08056ac2588c2305017e1c6d0677bdb69448 (diff) | |
download | bun-a44cb9708f8a1460a2851bc3357d2cec655f7ee2.tar.gz bun-a44cb9708f8a1460a2851bc3357d2cec655f7ee2.tar.zst bun-a44cb9708f8a1460a2851bc3357d2cec655f7ee2.zip |
New subcommand: `bun upgrade`. It upgrades bun to the latest version.
25 files changed, 769 insertions, 362 deletions
diff --git a/.gitignore b/.gitignore index 5e2b4efcb..b9a559203 100644 --- a/.gitignore +++ b/.gitignore @@ -64,7 +64,11 @@ release/ sign.*.json packages/debug-* packages/bun-cli/postinstall.js -packages/bun-*/bin/* +packages/bun-*/bun +packages/bun-*/bun-profile +packages/bun-*/debug-bun +packages/bun-*/*.o +packages/bun-cli/postinstall.js packages/bun-cli/bin/* bun-test-scratch diff --git a/.gitmodules b/.gitmodules index 935351eb2..e843246d2 100644 --- a/.gitmodules +++ b/.gitmodules @@ -24,4 +24,4 @@ [submodule "src/deps/s2n-tls"] path = src/deps/s2n-tls url = https://github.com/Jarred-Sumner/s2n-tls - ignore = dirty
\ No newline at end of file + ignore = dirty @@ -2,6 +2,7 @@ SHELL := /bin/bash # Use bash syntax to be consistent OS_NAME := $(shell uname -s | tr '[:upper:]' '[:lower:]') ARCH_NAME_RAW := $(shell uname -m) +BUN_AUTO_UPDATER_REPO = Jarred-Sumner/bun-releases-for-updater make-lazy = $(eval $1 = $$(eval $1 := $(value $(1)))$$($1)) @@ -15,20 +16,17 @@ else endif TRIPLET = $(OS_NAME)-$(ARCH_NAME) -PACKAGE_NAME = bun-cli-$(TRIPLET) +PACKAGE_NAME = bun-$(TRIPLET) PACKAGES_REALPATH = $(realpath packages) PACKAGE_DIR = $(PACKAGES_REALPATH)/$(PACKAGE_NAME) DEBUG_PACKAGE_DIR = $(PACKAGES_REALPATH)/debug-$(PACKAGE_NAME) -BIN_DIR = $(PACKAGE_DIR)/bin RELEASE_BUN = $(PACKAGE_DIR)/bin/bun -DEBUG_BIN = $(DEBUG_PACKAGE_DIR)/bin +DEBUG_BIN = $(DEBUG_PACKAGE_DIR)/ DEBUG_BUN = $(DEBUG_BIN)/bun-debug BUILD_ID = $(shell cat ./build-id) PACKAGE_JSON_VERSION = 0.0.$(BUILD_ID) BUN_BUILD_TAG = bun-v$(PACKAGE_JSON_VERSION) -PACKAGE_MAC = $(PACKAGES_REALPATH)/bun-cli-mac -MAC_BIN = $(PACKAGE_MAC)/bin -MAC_BUN = $(MAC_BIN)/bun +BUN_RELEASE_BIN = $(PACKAGE_DIR)/bun # We must use the same compiler version for the JavaScriptCore bindings and JavaScriptCore # If we don't do this, strange memory allocation failures occur. @@ -78,6 +76,7 @@ build-iconv-linux: cd src/deps/libiconv/libiconv-1.16; ./configure --enable-static; make -j 12; cp ./lib/.libs/libiconv.a $(DEPS_DIR)/libiconv.a BUN_TMP_DIR := /tmp/make-bun +BUN_DEPLOY_DIR = /tmp/bun-v$(PACKAGE_JSON_VERSION)/$(PACKAGE_NAME) DEFAULT_USE_BMALLOC := 1 # ifeq ($(OS_NAME),linux) @@ -309,7 +308,8 @@ BUN_LLD_FLAGS = $(OBJ_FILES) \ bun: vendor build-obj bun-link-lld-release -vendor-without-check: api analytics node-fallbacks runtime_js fallback_decoder bun_error mimalloc picohttp zlib openssl s2n libarchive +vendor-without-check: api analytics node-fallbacks runtime_js fallback_decoder bun_error mimalloc picohttp zlib openssl s2n bzip2 libarchive + libarchive: cd src/deps/libarchive; \ @@ -321,10 +321,10 @@ libarchive: cp ./.libs/libarchive.a $(DEPS_DIR)/libarchive.a; tgz: - zig build-exe -Drelease-fast --main-pkg-path $(shell pwd) ./misctools/tgz.zig $(DEPS_DIR)/zlib/libz.a $(DEPS_DIR)/libarchive.a $(LIBICONV_PATH) -lc + zig build-exe -Drelease-fast --main-pkg-path $(shell pwd) ./misctools/tgz.zig $(DEPS_DIR)/zlib/libz.a $(DEPS_DIR)/libarchive.a $(LIBICONV_PATH) -lc tgz-debug: - zig build-exe --main-pkg-path $(shell pwd) ./misctools/tgz.zig $(DEPS_DIR)/zlib/libz.a $(DEPS_DIR)/libarchive.a $(LIBICONV_PATH) -lc + zig build-exe --main-pkg-path $(shell pwd) ./misctools/tgz.zig $(DEPS_DIR)/zlib/libz.a $(DEPS_DIR)/libarchive.a $(LIBICONV_PATH) -lc vendor: require init-submodules vendor-without-check @@ -365,8 +365,6 @@ jsc-check: all-js: runtime_js fallback_decoder bun_error node-fallbacks -bin-dir: - @echo $(BIN_DIR) api: pnpm install; ./node_modules/.bin/peechy --schema src/api/schema.peechy --esm src/api/schema.js --ts src/api/schema.d.ts --zig src/api/schema.zig @@ -387,8 +385,8 @@ bun_error: @cd packages/bun-error; pnpm install; npm run --silent build generate-install-script: - @rm -f $(PACKAGES_REALPATH)/bun-cli/install.js - # NODE_ENV=production esbuild --log-level=error --define:BUN_VERSION="\"$(PACKAGE_JSON_VERSION)\"" --define:process.env.NODE_ENV="\"production\"" --platform=node --target=node14 --bundle --format=cjs $(PACKAGES_REALPATH)/bun-cli/node-install.ts > $(PACKAGES_REALPATH)/bun-cli/install.js + @rm -f $(PACKAGES_REALPATH)/bun/install.js + @esbuild --log-level=error --define:BUN_VERSION="\"$(PACKAGE_JSON_VERSION)\"" --define:process.env.NODE_ENV="\"production\"" --platform=node --format=cjs $(PACKAGES_REALPATH)/bun/install.ts > $(PACKAGES_REALPATH)/bun/install.js fetch: cd misctools; zig build-obj -Drelease-fast ./fetch.zig -fcompiler-rt -lc --main-pkg-path ../ @@ -476,197 +474,65 @@ bump: expr $(BUILD_ID) + 1 > build-id -# When adding a new architecture, don't forget to update this! -write-package-json-version-cli-json: - jq -S --raw-output '.version = "${PACKAGE_JSON_VERSION}"' packages/bun-cli/package.json > packages/bun-cli/package.json.new - mv packages/bun-cli/package.json.new packages/bun-cli/package.json - jq -S --raw-output '.optionalDependencies."bun-cli-linux-x64" = "${PACKAGE_JSON_VERSION}"' packages/bun-cli/package.json > packages/bun-cli/package.json.new - mv packages/bun-cli/package.json.new packages/bun-cli/package.json - jq -S --raw-output '.optionalDependencies."bun-cli-mac" = "${PACKAGE_JSON_VERSION}"' packages/bun-cli/package.json > packages/bun-cli/package.json.new - mv packages/bun-cli/package.json.new packages/bun-cli/package.json - -write-package-json-version: - jq -S --raw-output '.version = "${PACKAGE_JSON_VERSION}"' $(PACKAGE_DIR)/package.json > $(PACKAGE_DIR)/package.json.new - mv $(PACKAGE_DIR)/package.json.new $(PACKAGE_DIR)/package.json - -write-package-json-version-cli: write-package-json-version-cli-json generate-install-script - -write-package-json-version-mac: - jq -S --raw-output '.version = "${PACKAGE_JSON_VERSION}"' $(PACKAGE_MAC)/package.json > $(PACKAGE_MAC)/package.json.new - mv $(PACKAGE_MAC)/package.json.new $(PACKAGE_MAC)/package.json - tag: git tag $(BUN_BUILD_TAG) git push --tags -prepare-release: tag release-create write-package-json-version-cli write-package-json-version write-package-json-version-mac +prepare-release: tag release-create + +release-create-auto-updater: release-create: gh release create --title "Bun v$(PACKAGE_JSON_VERSION)" "$(BUN_BUILD_TAG)" - -BUN_DEPLOY_DIR = $(BUN_TMP_DIR)/bun-deploy -BUN_DEPLOY_CLI = $(BUN_TMP_DIR)/bun-cli -BUN_DEPLOY_PKG = $(BUN_DEPLOY_DIR)/$(PACKAGE_NAME) -BUN_DEPLOY_TGZ = $(BUN_DEPLOY_PKG)/$(PACKAGE_NAME)-$(PACKAGE_JSON_VERSION).tgz - -BUN_DEPLOY_PKG_MAC = $(BUN_DEPLOY_DIR)/bun-cli-mac -BUN_DEPLOY_TGZ_MAC = $(BUN_DEPLOY_PKG_MAC)/bun-cli-mac-$(PACKAGE_JSON_VERSION).tgz - -RELEASE_CLI_CHECK_DIR = /tmp/bun-$(PACKAGE_JSON_VERSION)-cli-check -RELEASE_BIN_CHECK_DIR = /tmp/bun-$(PACKAGE_JSON_VERSION)-bin-check - -release-cli-generate: write-package-json-version-cli release-cli-generate-build - -release-cli-generate-build: - rm -rf $(BUN_DEPLOY_CLI) - mkdir -p $(BUN_DEPLOY_CLI) - chmod +x packages/bun-cli/bin/bun - cp -r packages/bun-cli $(BUN_DEPLOY_CLI) - cd $(BUN_DEPLOY_CLI)/bun-cli; npm pack; - -release-cli-check-npm: - rm -rf $(RELEASE_CLI_CHECK_DIR); - mkdir -p $(RELEASE_CLI_CHECK_DIR); - echo "{\"name\": \"bun-test-$(PACKAGE_JSON_VERSION)\"}" > $(RELEASE_CLI_CHECK_DIR)/package.json - cd $(RELEASE_CLI_CHECK_DIR) && npm install --save $(BUN_DEPLOY_CLI)/bun-cli/bun-cli-$(PACKAGE_JSON_VERSION).tgz - test "$(PACKAGE_JSON_VERSION)" == "$(shell eval $(RELEASE_CLI_CHECK_DIR)/node_modules/.bin/bun --version || echo "FAIL" )" - -release-cli-check-yarn: - rm -rf $(RELEASE_CLI_CHECK_DIR); - mkdir -p $(RELEASE_CLI_CHECK_DIR); - echo "{\"name\": \"bun-test-$(PACKAGE_JSON_VERSION)\"}" > $(RELEASE_CLI_CHECK_DIR)/package.json - cd $(RELEASE_CLI_CHECK_DIR) && yarn add $(BUN_DEPLOY_CLI)/bun-cli/bun-cli-$(PACKAGE_JSON_VERSION).tgz - test "$(PACKAGE_JSON_VERSION)" == "$(shell eval $(RELEASE_CLI_CHECK_DIR)/node_modules/.bin/bun --version || echo "FAIL" )" - -release-cli-check-pnpm: - rm -rf $(RELEASE_CLI_CHECK_DIR); - mkdir -p $(RELEASE_CLI_CHECK_DIR); - echo "{\"name\": \"bun-test-$(PACKAGE_JSON_VERSION)\"}" > $(RELEASE_CLI_CHECK_DIR)/package.json - cd $(RELEASE_CLI_CHECK_DIR) && pnpm add $(BUN_DEPLOY_CLI)/bun-cli/bun-cli-$(PACKAGE_JSON_VERSION).tgz - test "$(PACKAGE_JSON_VERSION)" == "$(shell eval $(RELEASE_CLI_CHECK_DIR)/node_modules/.bin/bun --version || echo "FAIL" )" - -release-cli-check: release-cli-check-npm release-cli-check-yarn release-cli-check-pnpm - -release-bin-check-npm: - rm -rf $(RELEASE_BIN_CHECK_DIR); - mkdir -p $(RELEASE_BIN_CHECK_DIR); - echo "{\"name\": \"bun-test-$(PACKAGE_JSON_VERSION)\"}" > $(RELEASE_BIN_CHECK_DIR)/package.json - cd $(RELEASE_BIN_CHECK_DIR) && npm install --save $(BUN_DEPLOY_TGZ) - test "$(PACKAGE_JSON_VERSION)" == "$(shell eval $(RELEASE_BIN_CHECK_DIR)/node_modules/$(PACKAGE_NAME)/bin/bun --version || echo "FAIL" )" - -release-bin-check-yarn: - rm -rf $(RELEASE_BIN_CHECK_DIR); - mkdir -p $(RELEASE_BIN_CHECK_DIR); - echo "{\"name\": \"bun-test-$(PACKAGE_JSON_VERSION)\"}" > $(RELEASE_BIN_CHECK_DIR)/package.json - cd $(RELEASE_BIN_CHECK_DIR) && yarn add $(BUN_DEPLOY_TGZ) - test "$(PACKAGE_JSON_VERSION)" == "$(shell eval $(RELEASE_BIN_CHECK_DIR)/node_modules/$(PACKAGE_NAME)/bin/bun --version || echo "FAIL" )" - -release-bin-check-pnpm: - rm -rf $(RELEASE_BIN_CHECK_DIR); - mkdir -p $(RELEASE_BIN_CHECK_DIR); - echo "{\"name\": \"bun-test-$(PACKAGE_JSON_VERSION)\"}" > $(RELEASE_BIN_CHECK_DIR)/package.json - cd $(RELEASE_BIN_CHECK_DIR) && pnpm add $(BUN_DEPLOY_TGZ) - test "$(PACKAGE_JSON_VERSION)" == "$(shell eval $(RELEASE_BIN_CHECK_DIR)/node_modules/$(PACKAGE_NAME)/bin/bun --version || echo "FAIL" )" - -release-bin-check: release-bin-check-npm release-bin-check-yarn release-bin-check-pnpm - -release-mac-check-npm: - rm -rf $(RELEASE_BIN_CHECK_DIR); - mkdir -p $(RELEASE_BIN_CHECK_DIR); - echo "{\"name\": \"bun-test-$(PACKAGE_JSON_VERSION)\"}" > $(RELEASE_BIN_CHECK_DIR)/package.json - cd $(RELEASE_BIN_CHECK_DIR) && npm install --save $(BUN_DEPLOY_TGZ_MAC) - test "$(PACKAGE_JSON_VERSION)" == "$(shell eval $(RELEASE_BIN_CHECK_DIR)/node_modules/.bin/bun --version || echo "FAIL" )" - -release-mac-check-yarn: - rm -rf $(RELEASE_BIN_CHECK_DIR); - mkdir -p $(RELEASE_BIN_CHECK_DIR); - echo "{\"name\": \"bun-test-$(PACKAGE_JSON_VERSION)\"}" > $(RELEASE_BIN_CHECK_DIR)/package.json - cd $(RELEASE_BIN_CHECK_DIR) && yarn add $(BUN_DEPLOY_TGZ_MAC) - test "$(PACKAGE_JSON_VERSION)" == "$(shell eval $(RELEASE_BIN_CHECK_DIR)/node_modules/.bin/bun --version || echo "FAIL" )" - -release-mac-check-pnpm: - rm -rf $(RELEASE_BIN_CHECK_DIR); - mkdir -p $(RELEASE_BIN_CHECK_DIR); - echo "{\"name\": \"bun-test-$(PACKAGE_JSON_VERSION)\"}" > $(RELEASE_BIN_CHECK_DIR)/package.json - cd $(RELEASE_BIN_CHECK_DIR) && pnpm add $(BUN_DEPLOY_TGZ_MAC) - test "$(PACKAGE_JSON_VERSION)" == "$(shell eval $(RELEASE_BIN_CHECK_DIR)/node_modules/.bin/bun --version || echo "FAIL" )" - -release-mac-check: release-mac-check-npm release-mac-check-yarn release-mac-check-pnpm - -release-cli-push: - gh release upload $(BUN_BUILD_TAG) --clobber $(BUN_DEPLOY_CLI)/bun-cli/bun-cli-$(PACKAGE_JSON_VERSION).tgz - npm publish $(BUN_DEPLOY_CLI)/bun-cli/bun-cli-$(PACKAGE_JSON_VERSION).tgz --access=public - -release-bin-generate: write-package-json-version - rm -rf $(BUN_DEPLOY_DIR) - mkdir -p $(BUN_DEPLOY_DIR) - cp -r $(PACKAGE_DIR) $(BUN_DEPLOY_DIR) - cd $(BUN_DEPLOY_PKG); npm pack; - -release-mac-generate: write-package-json-version-mac - rm -rf $(BUN_DEPLOY_DIR) - mkdir -p $(BUN_DEPLOY_DIR) - cp -r $(PACKAGE_MAC) $(BUN_DEPLOY_DIR) - cd $(BUN_DEPLOY_PKG_MAC); npm pack; + gh release create --repo=$(BUN_AUTO_UPDATER_REPO) --title "Bun v$(PACKAGE_JSON_VERSION)" "$(BUN_BUILD_TAG)" -n "See https://github.com/Jarred-Sumner/bun/releases/tag/$(BUN_BUILD_TAG) for release notes. Using the install script or `bun upgrade` is the recommended way to install Bun. Join Bun's Discord to get access https://bun.sh/discord" release-bin-entitlements: -release-bin-entitlements-mac: + +release-bin-generate-zip: ifeq ($(OS_NAME),darwin) # Without this, JIT will fail on aarch64 # strip will remove the entitlements.plist # which, in turn, will break JIT release-bin-entitlements: - codesign --entitlements $(realpath entitlements.plist) --options runtime --force --timestamp --sign "$(CODESIGN_IDENTITY)" -vvv --deep --strict $(BIN_DIR)/bun + codesign --entitlements $(realpath entitlements.plist) --options runtime --force --timestamp --sign "$(CODESIGN_IDENTITY)" -vvvv --deep --strict $(BUN_RELEASE_BIN) -release-bin-entitlements-mac: - codesign --entitlements $(realpath entitlements.plist) --options runtime --force --timestamp --sign "$(CODESIGN_IDENTITY)" -vvv --deep --strict $(MAC_BUN) + +# macOS expects a specific directory structure for the zip file +# ditto lets us generate it similarly to right clicking "Compress" in Finder +release-bin-generate-zip: + dot_clean -vnm /tmp/bun-$(PACKAGE_JSON_VERSION)/bun-$(TRIPLET) + cd /tmp/bun-$(PACKAGE_JSON_VERSION)/bun-$(TRIPLET) && \ + codesign --entitlements $(realpath entitlements.plist) --options runtime --force --timestamp --sign "$(CODESIGN_IDENTITY)" -vvvv --deep --strict bun + ditto -ck --rsrc --sequesterRsrc --keepParent /tmp/bun-$(PACKAGE_JSON_VERSION)/bun-$(TRIPLET) $(BUN_DEPLOY_ZIP) + +else + +release-bin-generate-zip: + cd /tmp/bun-$(PACKAGE_JSON_VERSION)/ && zip -r bun-$(TRIPLET) endif -release-bin-codesign: - mkdir -p $(BUN_DEPLOY_ZIP)-input/package - tar -xzvf $(BUN_DEPLOY_TGZ) package - zip -r $(BUN_DEPLOY_ZIP) package - xcrun notarytool submit --wait $(BUN_DEPLOY_ZIP) +BUN_DEPLOY_ZIP = /tmp/bun-$(PACKAGE_JSON_VERSION)/bun-$(TRIPLET).zip -release-bin-notarize: - xcrun notarytool submit $(BIN_DIR)/bun -release-bin-without-push: test-all release-bin-check -release-bin: release-bin-without-push release-bin-push -release-mac-without-push: release-mac-generate-bin release-bin-entitlements-mac test-all-mac release-mac-generate release-mac-check -release-mac: release-mac-without-push release-mac-push +release-bin-generate-copy: + rm -rf /tmp/bun-$(PACKAGE_JSON_VERSION)/bun-$(TRIPLET) $(BUN_DEPLOY_ZIP) + mkdir -p /tmp/bun-$(PACKAGE_JSON_VERSION)/bun-$(TRIPLET) + cp $(BUN_RELEASE_BIN) /tmp/bun-$(PACKAGE_JSON_VERSION)/bun-$(TRIPLET)/bun +release-bin-generate: release-bin-generate-copy release-bin-generate-zip +release-bin-codesign: + xcrun notarytool submit --wait $(BUN_DEPLOY_ZIP) --keychain-profile "bun" -release-mac-check: - rm -rf /tmp/bun-$(PACKAGE_JSON_VERSION)-check; - mkdir -p /tmp/bun-$(PACKAGE_JSON_VERSION)-check; - echo "{\"name\": \"bun-test-$(PACKAGE_JSON_VERSION)\"}" > /tmp/bun-$(PACKAGE_JSON_VERSION)-check/package.json - cd /tmp/bun-$(PACKAGE_JSON_VERSION)-check && npm install $(BUN_DEPLOY_TGZ_MAC) - test "$(PACKAGE_JSON_VERSION)" == "$(shell eval /tmp/bun-$(PACKAGE_JSON_VERSION)-check/node_modules/.bin/bun --version)" +release-bin-without-push: test-all release-bin-generate release-bin-codesign +release-bin: release-bin-without-push release-bin-push release-bin-push: - gh release upload $(BUN_BUILD_TAG) --clobber $(BUN_DEPLOY_TGZ) - npm publish $(BUN_DEPLOY_TGZ) --access=public - -release-mac-push: - gh release upload $(BUN_BUILD_TAG) --clobber $(BUN_DEPLOY_TGZ_MAC) - npm publish $(BUN_DEPLOY_TGZ_MAC) --access=public - -release-mac-generate-bin: - rm -rf /tmp/bun-fat-$(PACKAGE_JSON_VERSION) - mkdir -p /tmp/bun-fat-$(PACKAGE_JSON_VERSION) - curl "https://registry.npmjs.org/bun-cli-darwin-aarch64/-/bun-cli-darwin-aarch64-0.0.37.tgz" > /tmp/bun-fat-$(PACKAGE_JSON_VERSION)/aarch64.tgz - curl "https://registry.npmjs.org/bun-cli-darwin-x64/-/bun-cli-darwin-x64-0.0.37.tgz" > /tmp/bun-fat-$(PACKAGE_JSON_VERSION)/x64.tgz - mkdir /tmp/bun-fat-$(PACKAGE_JSON_VERSION)/x64 - mkdir /tmp/bun-fat-$(PACKAGE_JSON_VERSION)/aarch64 - cd /tmp/bun-fat-$(PACKAGE_JSON_VERSION) && tar -xvf x64.tgz -C x64 - cd /tmp/bun-fat-$(PACKAGE_JSON_VERSION) && tar -xvf aarch64.tgz -C aarch64 - rm -f $(MAC_BUN) - lipo -create -output $(MAC_BUN) /tmp/bun-fat-$(PACKAGE_JSON_VERSION)/x64/package/bin/bun /tmp/bun-fat-$(PACKAGE_JSON_VERSION)/aarch64/package/bin/bun + gh release upload $(BUN_BUILD_TAG) --clobber $(BUN_DEPLOY_ZIP) + gh release upload $(BUN_BUILD_TAG) --clobber $(BUN_DEPLOY_ZIP) --repo $(BUN_AUTO_UPDATER_REPO) dev-obj: zig build obj @@ -788,21 +654,21 @@ bun-link-lld-debug: bun-relink-copy: - cp /tmp/bun-$(PACKAGE_JSON_VERSION).o $(BIN_DIR)/bun.o + cp /tmp/bun-$(PACKAGE_JSON_VERSION).o $(BUN_RELEASE_BIN).o bun-relink: bun-relink-copy bun-link-lld-release bun-link-lld-release: $(CXX) $(BUN_LLD_FLAGS) \ - $(BIN_DIR)/bun.o \ - -o $(BIN_DIR)/bun \ + $(BUN_RELEASE_BIN).o \ + -o $(BUN_RELEASE_BIN) \ -W \ -flto \ -ftls-model=initial-exec \ -O3 - cp $(BIN_DIR)/bun $(BIN_DIR)/bun-profile - $(STRIP) $(BIN_DIR)/bun - mv $(BIN_DIR)/bun.o /tmp/bun-$(PACKAGE_JSON_VERSION).o + cp $(BUN_RELEASE_BIN) $(BUN_RELEASE_BIN)-profile + $(STRIP) $(BUN_RELEASE_BIN) + mv $(BUN_RELEASE_BIN).o /tmp/bun-$(PACKAGE_JSON_VERSION).o # We do this outside of build.zig for performance reasons # The C compilation stuff with build.zig is really slow and we don't need to run this as often as the rest @@ -15,8 +15,7 @@ All in one fast & easy-to-use tool. Instead of 1,000 node_modules for develo ## Install: ``` -# Global install is recommended so bun appears in your $PATH -npm install -g bun-cli +curl -fsSL bun.sh/install | bash ``` ## Benchmarks @@ -458,9 +457,9 @@ When running bun on an M1 (or Apple Silicon), if you see a message like this: > [1] 28447 killed bun create next ./test -It most likely means you're running bun's x64 version on Apple Silicon. This happens if `node` (or, rather, `npm`) is running via Rosetta. Rosetta is unable to emulate AVX2 instructions, which Bun indirectly uses. +It most likely means you're running bun's x64 version on Apple Silicon. This happens if bun is running via Rosetta. Rosetta is unable to emulate AVX2 instructions, which Bun indirectly uses. -The fix is to ensure you installed a version of Node built for Apple Silicon and then reinstall `bun-cli`. You can also try to directly install `npm install -g bun-cli-darwin-aarch64`. +The fix is to ensure you installed a version of Bun built for Apple Silicon. # Reference @@ -1 +1 @@ -38 +39 @@ -34,7 +34,7 @@ pub fn build(b: *std.build.Builder) !void { const cwd: []const u8 = b.pathFromRoot("."); var exe: *std.build.LibExeObjStep = undefined; var output_dir_buf = std.mem.zeroes([4096]u8); - var bin_label = if (mode == std.builtin.Mode.Debug) "packages/debug-bun-cli-" else "packages/bun-cli-"; + var bin_label = if (mode == std.builtin.Mode.Debug) "packages/debug-bun-" else "packages/bun-"; var triplet_buf: [64]u8 = undefined; var os_tagname = @tagName(target.getOs().tag); @@ -60,7 +60,7 @@ pub fn build(b: *std.build.Builder) !void { var triplet = triplet_buf[0 .. osname.len + cpuArchName.len + 1]; - const output_dir_base = try std.fmt.bufPrint(&output_dir_buf, "{s}{s}/bin", .{ bin_label, triplet }); + const output_dir_base = try std.fmt.bufPrint(&output_dir_buf, "{s}{s}", .{ bin_label, triplet }); const output_dir = b.pathFromRoot(output_dir_base); const bun_executable_name = if (mode == std.builtin.Mode.Debug) "bun-debug" else "bun"; @@ -207,67 +207,64 @@ pub fn build(b: *std.build.Builder) !void { headers_obj.setMainPkgPath(javascript.main_pkg_path.?); headers_step.dependOn(&headers_obj.step); - b.default_step.dependOn(&exe.step); { + var steps = [_]*std.build.LibExeObjStep{ exe, javascript, typings_exe }; - - var steps = [_]*std.build.LibExeObjStep{ exe, javascript, typings_exe }; - - // const single_threaded = b.option(bool, "single-threaded", "Build single-threaded") orelse false; - - for (steps) |step, i| { - step.linkLibC(); - step.linkLibCpp(); - addPicoHTTP( - step, - true, - ); - - step.addObjectFile("src/deps/libJavaScriptCore.a"); - step.addObjectFile("src/deps/libWTF.a"); - step.addObjectFile("src/deps/libcrypto.a"); - step.addObjectFile("src/deps/libbmalloc.a"); - step.addObjectFile("src/deps/libarchive.a"); - step.addObjectFile("src/deps/libs2n.a"); - - step.addObjectFile("src/deps/zlib/libz.a"); - - step.addObjectFile("src/deps/mimalloc/libmimalloc.a"); - step.addLibPath("src/deps/mimalloc"); - step.addIncludeDir("src/deps/mimalloc"); - - // step.single_threaded = single_threaded; - - if (target.getOsTag() == .macos) { - const homebrew_prefix = comptime if (std.Target.current.cpu.arch == .aarch64) - "/opt/homebrew/" - else - "/usr/local/"; - - // We must link ICU statically - step.addObjectFile(homebrew_prefix ++ "opt/icu4c/lib/libicudata.a"); - step.addObjectFile(homebrew_prefix ++ "opt/icu4c/lib/libicui18n.a"); - step.addObjectFile(homebrew_prefix ++ "opt/icu4c/lib/libicuuc.a"); - step.addObjectFile(homebrew_prefix ++ "opt/libiconv/lib/libiconv.a"); - // icucore is a weird macOS only library - step.linkSystemLibrary("icucore"); - step.addLibPath(homebrew_prefix ++ "opt/icu4c/lib"); - step.addIncludeDir(homebrew_prefix ++ "opt/icu4c/include"); - } else { - step.linkSystemLibrary("icuuc"); - step.linkSystemLibrary("icudata"); - step.linkSystemLibrary("icui18n"); - step.addObjectFile("src/deps/libiconv.a"); - } + // const single_threaded = b.option(bool, "single-threaded", "Build single-threaded") orelse false; - for (bindings_files.items) |binding| { - step.addObjectFile( - binding, + for (steps) |step, i| { + step.linkLibC(); + step.linkLibCpp(); + addPicoHTTP( + step, + true, ); + + step.addObjectFile("src/deps/libJavaScriptCore.a"); + step.addObjectFile("src/deps/libWTF.a"); + step.addObjectFile("src/deps/libcrypto.a"); + step.addObjectFile("src/deps/libbmalloc.a"); + step.addObjectFile("src/deps/libarchive.a"); + step.addObjectFile("src/deps/libs2n.a"); + + step.addObjectFile("src/deps/zlib/libz.a"); + + step.addObjectFile("src/deps/mimalloc/libmimalloc.a"); + step.addLibPath("src/deps/mimalloc"); + step.addIncludeDir("src/deps/mimalloc"); + + // step.single_threaded = single_threaded; + + if (target.getOsTag() == .macos) { + const homebrew_prefix = comptime if (std.Target.current.cpu.arch == .aarch64) + "/opt/homebrew/" + else + "/usr/local/"; + + // We must link ICU statically + step.addObjectFile(homebrew_prefix ++ "opt/icu4c/lib/libicudata.a"); + step.addObjectFile(homebrew_prefix ++ "opt/icu4c/lib/libicui18n.a"); + step.addObjectFile(homebrew_prefix ++ "opt/icu4c/lib/libicuuc.a"); + step.addObjectFile(homebrew_prefix ++ "opt/libiconv/lib/libiconv.a"); + // icucore is a weird macOS only library + step.linkSystemLibrary("icucore"); + step.addLibPath(homebrew_prefix ++ "opt/icu4c/lib"); + step.addIncludeDir(homebrew_prefix ++ "opt/icu4c/include"); + } else { + step.linkSystemLibrary("icuuc"); + step.linkSystemLibrary("icudata"); + step.linkSystemLibrary("icui18n"); + step.addObjectFile("src/deps/libiconv.a"); + } + + for (bindings_files.items) |binding| { + step.addObjectFile( + binding, + ); + } } } - } { var obj_step = b.step("obj", "Build Bun as a .o file"); diff --git a/entitlements.plist b/entitlements.plist index 29677e891..d34af29fe 100644 --- a/entitlements.plist +++ b/entitlements.plist @@ -2,13 +2,15 @@ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> - <key>com.apple.application-identifier</key> - <string>com.codeblogcorp.bun</string> - <key>com.apple.security.cs.allow-unsigned-executable-memory</key> - <true/> - <key>com.apple.security.cs.single-jit</key> - <true/> - <key>com.apple.security.network.client</key> + <key>com.apple.security.cs.allow-jit</key> + <true/> + <key>com.apple.security.cs.allow-unsigned-executable-memory</key> + <true/> + <key>com.apple.security.cs.disable-executable-page-protection</key> + <true/> + <key>com.apple.security.cs.allow-dyld-environment-variables</key> + <true/> + <key>com.apple.security.cs.disable-library-validation</key> <true/> </dict> </plist>
\ No newline at end of file diff --git a/misctools/tgz.zig b/misctools/tgz.zig index 4a986c4ee..64b966554 100644 --- a/misctools/tgz.zig +++ b/misctools/tgz.zig @@ -74,7 +74,7 @@ pub fn main() anyerror!void { tarball_buf_list = std.ArrayListUnmanaged(u8){ .capacity = file_buf.len, .items = file_buf }; } - _ = try Archive.extractToDisk( + _ = try Archive.extractToDisk( file_buf, folder, null, diff --git a/packages/bun-cli-darwin-aarch64/package.json b/packages/bun-cli-darwin-aarch64/package.json deleted file mode 100644 index e0ccedad3..000000000 --- a/packages/bun-cli-darwin-aarch64/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "cpu": [ - "arm64" - ], - "bugs": { - "url": "https://github.com/jarred-sumner/bun/issues" - }, - "homepage": "https://bun.sh", - "name": "bun-cli-darwin-aarch64", - "private": false, - "os": [ - "darwin" - ], - "repository": "https://github.com/jarred-sumner/bun", - "version": "0.0.37" -} diff --git a/packages/bun-cli-darwin-x64/package.json b/packages/bun-cli-darwin-x64/package.json deleted file mode 100644 index 225b9f058..000000000 --- a/packages/bun-cli-darwin-x64/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "bugs": { - "url": "https://github.com/jarred-sumner/bun/issues" - }, - "cpu": [ - "x64" - ], - "homepage": "https://bun.sh", - "name": "bun-cli-darwin-x64", - "os": [ - "darwin" - ], - "private": false, - "repository": "https://github.com/jarred-sumner/bun", - "version": "0.0.38" -} diff --git a/packages/bun-cli-linux-x64/package.json b/packages/bun-cli-linux-x64/package.json deleted file mode 100644 index e2f2928af..000000000 --- a/packages/bun-cli-linux-x64/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "cpu": [ - "x64" - ], - "bugs": { - "url": "https://github.com/jarred-sumner/bun/issues" - }, - "homepage": "https://bun.sh", - "description": "Linux build of Bun", - "name": "bun-cli-linux-x64", - "private": false, - "os": [ - "linux" - ], - "repository": "https://github.com/jarred-sumner/bun", - "version": "0.0.37" -} diff --git a/packages/bun-cli-mac/.npmignore b/packages/bun-cli-mac/.npmignore deleted file mode 100644 index 08d23cb2a..000000000 --- a/packages/bun-cli-mac/.npmignore +++ /dev/null @@ -1,4 +0,0 @@ -bin/bun-profile -bin/*.o -*.o -*.a
\ No newline at end of file diff --git a/packages/bun-cli-mac/package.json b/packages/bun-cli-mac/package.json deleted file mode 100644 index 0c5b6e894..000000000 --- a/packages/bun-cli-mac/package.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "cpu": [ - "x64", - "arm64" - ], - "description": "macOS build of Bun", - "bugs": { - "url": "https://github.com/jarred-sumner/bun/issues" - }, - "homepage": "https://bun.sh", - "name": "bun-cli-mac", - "os": [ - "darwin" - ], - "private": false, - "repository": "https://github.com/jarred-sumner/bun", - "version": "0.0.37" -} diff --git a/packages/bun-cli/.npmignore b/packages/bun-cli/.npmignore deleted file mode 100644 index a5722fb02..000000000 --- a/packages/bun-cli/.npmignore +++ /dev/null @@ -1,3 +0,0 @@ -scripts -pnpm-lock.yaml -*.ts diff --git a/packages/bun-cli/package.json b/packages/bun-cli/package.json deleted file mode 100644 index a66453170..000000000 --- a/packages/bun-cli/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "bugs": { - "url": "https://github.com/jarred-sumner/bun/issues" - }, - "description": "Bun: a fast bundler, transpiler and task runner for web software. To get early access, join the Discord https://bun.sh/discord", - "homepage": "https://bun.sh", - "license": "MIT", - "main": "package.json", - "name": "bun-cli", - "optionalDependencies": { - "bun-cli-linux-x64": "0.0.37", - "bun-cli-mac": "0.0.37" - }, - "repository": "https://github.com/jarred-sumner/bun", - "scripts": {}, - "version": "0.0.37" -} diff --git a/packages/bun-cli/reset-bin.js b/packages/bun-cli/reset-bin.js deleted file mode 100755 index 233061ef2..000000000 --- a/packages/bun-cli/reset-bin.js +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env node -throw new Error(`bun-cli: Failed to install correctly - -Make sure you don't have "ignore-scripts" set to true. You can check this with -"npm config get ignore-scripts". If that returns true you can reset it back to -false using "npm config set ignore-scripts false" and then reinstall bun. - -If you're using npm v7, make sure your package-lock.json file contains either -"lockfileVersion": 1 or the code "hasInstallScript": true. If it doesn't have -either of those, then it is likely the case that a known bug in npm v7 has -corrupted your package-lock.json file. Regenerating your package-lock.json file -should fix this issue. -`); diff --git a/packages/bun-cli-darwin-aarch64/.npmignore b/packages/bun-darwin-aarch64/.npmignore index 08d23cb2a..08d23cb2a 100644 --- a/packages/bun-cli-darwin-aarch64/.npmignore +++ b/packages/bun-darwin-aarch64/.npmignore diff --git a/packages/bun-cli-darwin-x64/.npmignore b/packages/bun-darwin-x64/.npmignore index 08d23cb2a..08d23cb2a 100644 --- a/packages/bun-cli-darwin-x64/.npmignore +++ b/packages/bun-darwin-x64/.npmignore diff --git a/packages/bun-cli-linux-x64/.npmignore b/packages/bun-linux-x64/.npmignore index 08d23cb2a..08d23cb2a 100644 --- a/packages/bun-cli-linux-x64/.npmignore +++ b/packages/bun-linux-x64/.npmignore diff --git a/src/cli.zig b/src/cli.zig index e0ffc1235..9748945e8 100644 --- a/src/cli.zig +++ b/src/cli.zig @@ -35,7 +35,7 @@ const BuildCommand = @import("./cli/build_command.zig").BuildCommand; const CreateCommand = @import("./cli/create_command.zig").CreateCommand; const CreateListExamplesCommand = @import("./cli/create_command.zig").CreateListExamplesCommand; const RunCommand = @import("./cli/run_command.zig").RunCommand; - +const UpgradeCommand = @import("./cli/upgrade_command.zig").UpgradeCommand; var start_time: i128 = undefined; pub const Cli = struct { @@ -459,7 +459,8 @@ const HelpCommand = struct { \\> <r> <b><magenta>bun <r><d> ./a.ts ./b.jsx<r> Bundle dependencies of input files into a <r><magenta>.bun<r> \\> <r> <b><green>run <r><d> test <r> Run a package.json script or executable<r> \\> <r> <b><cyan>create <r><d>next ./app<r> Start a new project from a template <d>(shorthand: c)<r> - \\> <r> <b><blue>discord <r> Open Bun's Discord server + \\> <r> <b><blue>upgrade <r> Get the latest version of Bun + \\> <r> <b><d>discord <r> Open Bun's Discord server \\> <r> <b><d>help <r> Print this help menu \\ ; @@ -477,6 +478,7 @@ const HelpCommand = struct { \\> <r> <b><magenta>bun <r><d> ./a.ts ./b.jsx<r> Bundle dependencies of input files into a <r><magenta>.bun<r> \\> <r> <green>run <r><d> ./a.ts <r> Run a JavaScript-like file with Bun.js \\> <r> <b><blue>discord<r> Open Bun's Discord server + \\> <r> <b><blue>upgrade <r> Get the latest version of Bun \\> <r> <b><d>help <r> Print this help menu \\ ; @@ -578,6 +580,7 @@ pub const Command = struct { RootCommandMatcher.case("init") => .InitCommand, RootCommandMatcher.case("bun") => .BunCommand, RootCommandMatcher.case("discord") => .DiscordCommand, + RootCommandMatcher.case("upgrade") => .UpgradeCommand, RootCommandMatcher.case("c"), RootCommandMatcher.case("create") => .CreateCommand, RootCommandMatcher.case("b"), RootCommandMatcher.case("build") => .BuildCommand, @@ -594,6 +597,7 @@ pub const Command = struct { RootCommandMatcher.case("discord") => .DiscordCommand, RootCommandMatcher.case("d"), RootCommandMatcher.case("dev") => .DevCommand, RootCommandMatcher.case("c"), RootCommandMatcher.case("create") => .CreateCommand, + RootCommandMatcher.case("upgrade") => .UpgradeCommand, RootCommandMatcher.case("help") => .HelpCommand, else => .AutoCommand, @@ -656,6 +660,11 @@ pub const Command = struct { _ = try RunCommand.exec(ctx, false, true); } }, + .UpgradeCommand => { + const ctx = try Command.Context.create(allocator, log, .UpgradeCommand); + try UpgradeCommand.exec(ctx); + return; + }, .AutoCommand => { var ctx = Command.Context.create(allocator, log, .AutoCommand) catch |e| { switch (e) { @@ -702,5 +711,6 @@ pub const Command = struct { AutoCommand, HelpCommand, CreateCommand, + UpgradeCommand, }; }; diff --git a/src/cli/install.sh b/src/cli/install.sh new file mode 100644 index 000000000..e771ba28d --- /dev/null +++ b/src/cli/install.sh @@ -0,0 +1,138 @@ +#!/bin/bash + + +# Reset +Color_Off='' # Text Reset + +# Regular Colors +Black='' # Black +Red='' # Red +Green='' # Green +Yellow='' # Yellow +Blue='' # Blue +Purple='' # Purple +Cyan='' # Cyan +White='' # White + +# Bold +BBlack='' # Black +BRed='' # Red +BGreen='' # Green +BYellow='' # Yellow +BBlue='' # Blue +BPurple='' # Purple +BCyan='' # Cyan +BWhite='' # White + +if test -t 1; then +# Reset +Color_Off='\033[0m' # Text Reset + +# Regular Colors +Black='\033[0;30m' # Black +Red='\033[0;31m' # Red +Green='\033[0;32m' # Green +Yellow='\033[0;33m' # Yellow +Blue='\033[0;34m' # Blue +Purple='\033[0;35m' # Purple +Cyan='\033[0;36m' # Cyan +White='\033[0;37m' # White + +# Bold +BBlack='\033[1;30m' # Black +BRed='\033[1;31m' # Red +BGreen='\033[1;32m' # Green +BYellow='\033[1;33m' # Yellow +BBlue='\033[1;34m' # Blue +BPurple='\033[1;35m' # Purple +BCyan='\033[1;36m' # Cyan +BWhite='\033[1;37m' # White +fi + + +if ! command -v unzip >/dev/null; then + echo -e "${Red}error${Color_Off}: unzip is required to install Bun (see: https://github.com/Jarred-Sumner/bun#unzip-is-required)." 1>&2 + exit 1 +fi + +if [ "$OS" = "Windows_NT" ]; then + echo "error: Please install Bun using Windows Subsystem for Linux." + exit 1 +else + case $(uname -sm) in + "Darwin x86_64") target="darwin-x64" ;; + "Darwin arm64") target="darwin-aarch64" ;; + *) target="linux-x64" ;; + esac +fi + +github_repo="https://github.com/Jarred-Sumner/bun-releases-for-updater" + +if [ $# -eq 0 ]; then + bun_uri="$github_repo/releases/latest/download/bun-${target}.zip" +else + bun_uri="$github_repo/releases/download/${1}/bun-${target}.zip" +fi + +bun_install="${BUN_INSTALL:-$HOME/.bun}" +bin_dir="$bun_install/bin" +exe="$bin_dir/bun" + +if [ ! -d "$bin_dir" ]; then + mkdir -p "$bin_dir" +fi + +curl --fail --location --progress-bar --output "$exe.zip" "$bun_uri" + +if (( $? )); then + echo -e "${Red}error${Color_Off}: Failed to download Bun from $bun_uri" 1>&2 + exit 1 +fi +unzip -d "$bin_dir" -q -o "$exe.zip" +if (( $? )); then + echo -e "${Red}error${Color_Off}: Failed to extract Bun" 1>&2 + exit 1 +fi +mv "$bin_dir/bun-${target}/bun" "$exe" +if (( $? )); then + echo -e "${Red}error${Color_Off}: Failed to extract Bun" 1>&2 + exit 1 +fi +chmod +x "$exe" +if (( $? )); then + echo -e "${Red}error${Color_Off}: Failed to set permissions on bun executable." 1>&2 + exit 1 +fi +rmdir $bin_dir/bun-${target} +rm "$exe.zip" + +echo -e "${Green}Bun was installed successfully to ${BGreen}$exe$Color_Off" + +if command -v bun --version >/dev/null; then + echo "Run 'bun --help' to get started" + exit 0 +fi + +if test $(basename $SHELL) == "fish"; then + echo "" + echo "Manually add the directory to your \$HOME/.config/fish" + echo "" + echo -e " $BWhite set -Ux BUN_INSTALL \"$bun_install\"$Color_Off" + echo -e " $BWhite set -px --path PATH \"$bin_dir\"$Color_Off" +elif test $(basename $SHELL) == "zsh"; then + echo "" + echo "Manually add the directory to your \$HOME/.zshrc (or similar)" + echo "" + echo -e " $BWhite export BUN_INSTALL=\"$bun_install$Color_Off" + echo -e " $BWhite export PATH=\"\$BUN_INSTALL/bin:\$PATH\"$Color_Off" +else + echo "" + echo "Manually add the directory to your \$HOME/.bashrc (or similar)" + echo "" + echo -e " $BWhiteexport BUN_INSTALL=\"$bun_install\"$Color_Off" + echo -e " $BWhiteexport PATH=\"\$BUN_INSTALL/bin:\$PATH\"$Color_Off" +fi +echo "" +echo -e "To get started, run" +echo -e "$BWhite" +echo -e " bun --help$Color_Off"
\ No newline at end of file diff --git a/src/cli/run_command.zig b/src/cli/run_command.zig index 3a8039978..b2dc426ef 100644 --- a/src/cli/run_command.zig +++ b/src/cli/run_command.zig @@ -464,7 +464,7 @@ pub const RunCommand = struct { var display_name = package_json.name; if (display_name.len == 0) { - display_name = std.fs.path.basename(root_dir_info.getEntries().?.dir); + display_name = std.fs.path.basename(package_json.source.path.name.dir); } var iterator = scripts.iterator(); diff --git a/src/cli/upgrade_command.zig b/src/cli/upgrade_command.zig new file mode 100644 index 000000000..8dc83a037 --- /dev/null +++ b/src/cli/upgrade_command.zig @@ -0,0 +1,495 @@ +usingnamespace @import("../global.zig"); +const std = @import("std"); + +const lex = @import("../js_lexer.zig"); +const logger = @import("../logger.zig"); +const alloc = @import("../alloc.zig"); +const options = @import("../options.zig"); +const js_parser = @import("../js_parser.zig"); +const js_ast = @import("../js_ast.zig"); +const linker = @import("../linker.zig"); +usingnamespace @import("../ast/base.zig"); +usingnamespace @import("../defines.zig"); +const panicky = @import("../panic_handler.zig"); +const allocators = @import("../allocators.zig"); +const sync = @import(".././sync.zig"); +const Api = @import("../api/schema.zig").Api; +const resolve_path = @import("../resolver/resolve_path.zig"); +const configureTransformOptionsForBun = @import("../javascript/jsc/config.zig").configureTransformOptionsForBun; +const Command = @import("../cli.zig").Command; +const bundler = @import("../bundler.zig"); +const NodeModuleBundle = @import("../node_module_bundle.zig").NodeModuleBundle; +const fs = @import("../fs.zig"); +const URL = @import("../query_string_map.zig").URL; +const HTTPClient = @import("../http_client.zig"); +const ParseJSON = @import("../json_parser.zig").ParseJSON; +const Archive = @import("../libarchive/libarchive.zig").Archive; +const Zlib = @import("../zlib.zig"); +const JSPrinter = @import("../js_printer.zig"); +const DotEnv = @import("../env_loader.zig"); +const NPMClient = @import("../which_npm_client.zig").NPMClient; +const which = @import("../which.zig").which; +const clap = @import("clap"); +const Lock = @import("../lock.zig").Lock; +const Headers = @import("../javascript/jsc/webcore/response.zig").Headers; +const CopyFile = @import("../copy_file.zig"); + +pub var initialized_store = false; +pub fn initializeStore() void { + if (initialized_store) return; + initialized_store = true; + js_ast.Expr.Data.Store.create(default_allocator); + js_ast.Stmt.Data.Store.create(default_allocator); +} + +pub const Version = struct { + zip_url: string, + tag: string, + buf: MutableString, + size: u32 = 0, + + pub fn name(this: Version) ?string { + if (this.tag.len > "bun-v".len and strings.eqlComptime(this.tag[0.."bun-v".len], "bun-v")) { + return this.tag[("bun-v".len)..]; + } else { + return null; + } + } + + pub const platform_label = if (Environment.isMac) "darwin" else "linux"; + pub const arch_label = if (Environment.isAarch64) "aarch64" else "x64"; + pub const triplet = platform_label ++ "-" ++ arch_label; + pub const folder_name = "bun-" ++ triplet; + pub const zip_filename = folder_name ++ ".zip"; + + const current_version: string = "bun-v" ++ Global.package_json_version; + + pub fn isCurrent(this: Version) bool { + return strings.eqlComptime(this.tag, current_version); + } +}; + +pub const UpgradeCommand = struct { + pub const timeout: u32 = 30000; + const default_github_headers = "Acceptapplication/vnd.github.v3+json"; + var github_repository_url_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined; + + var current_executable_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined; + var unzip_path_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined; + + pub fn getLatestVersion( + allocator: *std.mem.Allocator, + env_loader: *DotEnv.Loader, + refresher: *std.Progress, + progress: *std.Progress.Node, + comptime silent: bool, + ) !?Version { + var headers_buf: string = default_github_headers; + + var header_entries: Headers.Entries = .{}; + const accept = Headers.Kv{ + .name = Api.StringPointer{ .offset = 0, .length = @intCast(u32, "Accept".len) }, + .value = Api.StringPointer{ .offset = @intCast(u32, "Accept".len), .length = @intCast(u32, "application/vnd.github.v3+json".len) }, + }; + try header_entries.append(allocator, accept); + + // Incase they're using a GitHub proxy in e.g. China + var github_api_domain: string = "api.github.com"; + if (env_loader.map.get("GITHUB_API_DOMAIN")) |api_domain| { + if (api_domain.len > 0) { + github_api_domain = api_domain; + } + } + + var api_url = URL.parse( + try std.fmt.bufPrint( + &github_repository_url_buf, + "https://{s}/repos/Jarred-Sumner/bun-releases-for-updater/releases/latest", + .{ + github_api_domain, + }, + ), + ); + + var client = HTTPClient.init( + allocator, + .GET, + api_url, + header_entries, + headers_buf, + ); + client.timeout = timeout; + if (!silent) { + client.progress_node = progress; + } + + if (env_loader.map.get("GITHUB_ACCESS_TOKEN")) |access_token| { + if (access_token.len > 0) { + headers_buf = try std.fmt.allocPrint(allocator, default_github_headers ++ "Access-TokenBearer {s}", .{access_token}); + try header_entries.append( + allocator, + Headers.Kv{ + .name = Api.StringPointer{ + .offset = accept.value.length + accept.value.offset, + .length = @intCast(u32, "Access-Token".len), + }, + .value = Api.StringPointer{ + .offset = @intCast(u32, accept.value.length + accept.value.offset + "Access-Token".len), + .length = @intCast(u32, access_token.len), + }, + }, + ); + } + } + + var metadata_body = try MutableString.init(allocator, 2048); + var response = try client.send("", &metadata_body); + + switch (response.status_code) { + 404 => return error.HTTP404, + 403 => return error.HTTPForbidden, + 429 => return error.HTTPTooManyRequests, + 499...599 => return error.GitHubIsDown, + 200 => {}, + else => return error.HTTPError, + } + + var log = logger.Log.init(allocator); + var source = logger.Source.initPathString("releases.json", metadata_body.list.items); + initializeStore(); + var expr = ParseJSON(&source, &log, allocator) catch |err| { + if (!silent) { + progress.end(); + refresher.refresh(); + + if (log.errors > 0) { + if (Output.enable_ansi_colors) { + try log.printForLogLevelWithEnableAnsiColors(Output.errorWriter(), true); + } else { + try log.printForLogLevelWithEnableAnsiColors(Output.errorWriter(), false); + } + Output.flush(); + std.os.exit(1); + } else { + Output.prettyErrorln("Error parsing releases from GitHub: <r><red>{s}<r>", .{@errorName(err)}); + Output.flush(); + std.os.exit(1); + } + } + + return null; + }; + + if (log.errors > 0) { + if (comptime !silent) { + progress.end(); + refresher.refresh(); + + if (Output.enable_ansi_colors) { + try log.printForLogLevelWithEnableAnsiColors(Output.errorWriter(), true); + } else { + try log.printForLogLevelWithEnableAnsiColors(Output.errorWriter(), false); + } + Output.flush(); + std.os.exit(1); + } + + return null; + } + + var version = Version{ .zip_url = "", .tag = "", .buf = metadata_body, .size = 0 }; + + if (expr.data != .e_object) { + if (comptime !silent) { + progress.end(); + refresher.refresh(); + + const json_type: js_ast.Expr.Tag = @as(js_ast.Expr.Tag, expr.data); + Output.prettyErrorln("JSON error - expected an object but received {s}", .{@tagName(json_type)}); + Output.flush(); + std.os.exit(1); + } + + return null; + } + + if (expr.asProperty("tag_name")) |tag_name_| { + if (tag_name_.expr.asString(allocator)) |tag_name| { + version.tag = tag_name; + } + } + + if (version.tag.len == 0) { + if (comptime !silent) { + progress.end(); + refresher.refresh(); + + Output.prettyErrorln("JSON Error parsing releases from GitHub: <r><red>tag_name<r> is missing?\n{s}", .{metadata_body.list.items}); + Output.flush(); + std.os.exit(1); + } + + return null; + } + + get_asset: { + const assets_ = expr.asProperty("assets") orelse break :get_asset; + var assets = assets_.expr.asArray() orelse break :get_asset; + + while (assets.next()) |asset| { + if (asset.asProperty("name")) |name_| { + if (name_.expr.asString(allocator)) |name| { + if (strings.eqlComptime(name, Version.zip_filename)) { + version.zip_url = (asset.asProperty("browser_download_url") orelse break :get_asset).expr.asString(allocator) orelse break :get_asset; + + if (asset.asProperty("size")) |size_| { + if (size_.expr.data == .e_number) { + version.size = @intCast(u32, @maximum(@floatToInt(i32, std.math.ceil(size_.expr.data.e_number.value)), 0)); + } + } + return version; + } + } + } + } + } + + if (comptime !silent) { + progress.end(); + refresher.refresh(); + if (version.name()) |name| { + Output.prettyErrorln("Bun v{s} is out, but not for this platform ({s}) yet.", .{ + name, Version.triplet, + }); + } + + Output.flush(); + std.os.exit(0); + } + + version.buf.deinit(); + + return null; + } + const exe_subpath = Version.folder_name; + + pub fn exec(ctx: Command.Context) !void { + var filesystem = try fs.FileSystem.init1(ctx.allocator, null); + var env_loader: DotEnv.Loader = brk: { + var map = try ctx.allocator.create(DotEnv.Map); + map.* = DotEnv.Map.init(ctx.allocator); + + break :brk DotEnv.Loader.init(map, ctx.allocator); + }; + + env_loader.loadProcess(); + + var version: Version = undefined; + + { + var refresher = std.Progress{}; + var progress = try refresher.start("Fetching version tags", 0); + + version = (try getLatestVersion(ctx.allocator, &env_loader, &refresher, progress, false)) orelse return; + + progress.end(); + refresher.refresh(); + + if (version.name() != null and version.isCurrent()) { + Output.prettyErrorln( + "<r><green>Congrats!<r> You're already on the latest version of Bun <d>(which is v {s})<r>", + .{ + version.name().?, + }, + ); + Output.flush(); + std.os.exit(0); + } + + if (version.name() == null) { + Output.prettyErrorln( + "<r><red>error:<r> Bun versions are currently unavailable (the latest version name didn't match the expeccted format)", + .{}, + ); + Output.flush(); + std.os.exit(1); + } + } + + { + Output.prettyErrorln("<r><b>Bun <cyan>v{s}<r> is out<r>! You're on <blue>{s}<r>\n", .{ version.name().?, Global.package_json_version }); + Output.flush(); + + var refresher = std.Progress{}; + var progress = try refresher.start("Downloading", version.size); + + var client = HTTPClient.init( + ctx.allocator, + .GET, + URL.parse(version.zip_url), + .{}, + "", + ); + client.timeout = timeout; + client.progress_node = progress; + var zip_file_buffer = try MutableString.init(ctx.allocator, @maximum(version.size, 1024)); + var response = try client.send( + "", + &zip_file_buffer, + ); + + progress.end(); + refresher.refresh(); + + switch (response.status_code) { + 404 => return error.HTTP404, + 403 => return error.HTTPForbidden, + 429 => return error.HTTPTooManyRequests, + 499...599 => return error.GitHubIsDown, + 200 => {}, + else => return error.HTTPError, + } + + var bytes = zip_file_buffer.toOwnedSliceLeaky(); + if (bytes.len == 0) { + Output.prettyErrorln("<r><red>error:<r> Failed to download the latest version of Bun. Received empty content", .{}); + Output.flush(); + std.os.exit(1); + } + + const version_name = version.name().?; + + var save_dir_ = filesystem.tmpdir(); + var save_dir = save_dir_.makeOpenPath(version_name, .{ .iterate = true }) catch |err| { + Output.prettyErrorln("<r><red>error:<r> Failed to open temporary directory", .{}); + Output.flush(); + std.os.exit(1); + }; + + const tmpname = "bun.zip"; + + var zip_file = save_dir.createFileZ(tmpname, .{ .truncate = true }) catch |err| { + Output.prettyErrorln("<r><red>error:<r> Failed to open temp file {s}", .{@errorName(err)}); + Output.flush(); + std.os.exit(1); + }; + + { + _ = zip_file.writeAll(bytes) catch |err| { + save_dir.deleteFileZ(tmpname) catch {}; + Output.prettyErrorln("<r><red>error:<r> Failed to write to temp file {s}", .{@errorName(err)}); + Output.flush(); + std.os.exit(1); + }; + zip_file.close(); + } + + { + defer { + save_dir.deleteFileZ(tmpname) catch {}; + } + + const unzip_exe = which(&unzip_path_buf, env_loader.map.get("PATH") orelse "", filesystem.top_level_dir, "unzip") orelse { + save_dir.deleteFileZ(tmpname) catch {}; + Output.prettyErrorln("<r><red>error:<r> Failed to locate \"unzip\" in PATH. bun upgrade needs \"unzip\" to work.", .{}); + Output.flush(); + std.os.exit(1); + }; + Output.prettyErrorln("<r><b>Unzipping...<r>", .{}); + Output.flush(); + + var unzip_argv = [_]string{ + std.mem.span(unzip_exe), + std.mem.span(tmpname), + }; + + var unzip_process = try std.ChildProcess.init(&unzip_argv, ctx.allocator); + defer unzip_process.deinit(); + unzip_process.cwd_dir = save_dir; + unzip_process.stdin_behavior = .Inherit; + unzip_process.stdout_behavior = .Inherit; + unzip_process.stderr_behavior = .Inherit; + + const unzip_result = unzip_process.spawnAndWait() catch |err| { + save_dir.deleteFileZ(tmpname) catch {}; + Output.prettyErrorln("<r><red>error:<r> Failed to spawn unzip due to {s}.", .{@errorName(err)}); + Output.flush(); + std.os.exit(1); + }; + + if (unzip_result.Exited != 0) { + Output.prettyErrorln("<r><red>Unzip failed<r> (exit code: {d})", .{unzip_result.Exited}); + Output.flush(); + save_dir.deleteFileZ(tmpname) catch {}; + std.os.exit(1); + } + } + + { + var verify_argv = [_]string{ + exe_subpath, + "--version", + }; + + const result = std.ChildProcess.exec(.{ + .allocator = ctx.allocator, + .argv = &verify_argv, + .cwd_dir = save_dir, + .max_output_bytes = 128, + }) catch |err| { + save_dir_.deleteTree(version_name) catch {}; + Output.prettyErrorln("<r><red>error<r> Failed to verify Bun {s}<r>)", .{@errorName(err)}); + Output.flush(); + std.os.exit(1); + }; + + if (result.term.Exited != 0) { + Output.prettyErrorln("<r><red>error<r> failed to verify Bun<r> (exit code: {d})", .{result.term.Exited}); + Output.flush(); + std.os.exit(1); + } + + if (!strings.eql(std.mem.trim(u8, result.stdout, " \n\r\t"), version_name)) { + Output.prettyErrorln( + "<r><red>error<r>: The downloaded version of Bun (<red>{s}<r>) doesn't match the expected version (<b>{s}<r>)<r>. Cancelled upgrade", + .{ + result.stdout[0..@minimum(result.stdout.len, 128)], + version_name, + }, + ); + Output.flush(); + std.os.exit(1); + } + } + + var destination_executable_ = std.fs.selfExePath(¤t_executable_buf) catch return error.UpgradeFailedMissingExecutable; + current_executable_buf[destination_executable_.len] = 0; + + var target_filename_ = std.fs.path.basename(destination_executable_); + var target_filename = current_executable_buf[destination_executable_.len - target_filename_.len ..][0..target_filename_.len :0]; + var target_dir_ = std.fs.path.dirname(destination_executable_) orelse return error.UpgradeFailedBecauseOfMissingExecutableDir; + // safe because the slash will no longer be in use + current_executable_buf[target_dir_.len] = 0; + var target_dirname = current_executable_buf[0..target_dir_.len :0]; + var target_dir = std.fs.openDirAbsoluteZ(target_dirname, .{ .iterate = true }) catch |err| { + Output.prettyErrorln("<r><red>error:<r> Failed to open Bun's install directory {s}", .{@errorName(err)}); + Output.flush(); + std.os.exit(1); + }; + + if (env_loader.map.get("BUN_DRY_RUN") == null) { + C.moveFileZ(save_dir.fd, exe_subpath, target_dir.fd, target_filename) catch |err| { + Output.prettyErrorln("<r><red>error:<r> Failed to move new version of Bun due to {s}. You could try the install script instead:\n curl https://bun.sh/install | bash", .{@errorName(err)}); + Output.flush(); + std.os.exit(1); + }; + } + + Output.prettyErrorln("\n", .{}); + Output.flush(); + Output.prettyln("<r><b><green>Upgraded successfully<r>. Welcome to Bun v{s}!\nFind out what's new: https://github.com/Jarred-Sumner/bun/releases<r>", .{version_name}); + Output.flush(); + return; + } + } +}; diff --git a/src/fs.zig b/src/fs.zig index 0b28fa9b7..9c8a0b6d3 100644 --- a/src/fs.zig +++ b/src/fs.zig @@ -493,7 +493,7 @@ pub const FileSystem = struct { pub var tmpdir_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined; const PLATFORM_TMP_DIR: string = switch (std.Target.current.os.tag) { - .windows => "%TMPDIR%", + .windows => "TMPDIR", .macos => "/private/tmp", else => "/tmp", }; diff --git a/src/javascript/jsc/WebKit b/src/javascript/jsc/WebKit -Subproject 58007798f366ae8bb7487ca5256a6db860c6da4 +Subproject 2c7c359ff9e6d1cff8528354ef19881d4d0e6c7 |