diff --git a/pkgs/development/tools/devpod/add-tauri-updater-feature.patch b/pkgs/development/tools/devpod/add-tauri-updater-feature.patch deleted file mode 100644 index 166948c78a03..000000000000 --- a/pkgs/development/tools/devpod/add-tauri-updater-feature.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff --git a/Cargo.toml b/Cargo.toml -index 03f64e53..9e2ddcb6 100644 ---- a/Cargo.toml -+++ b/Cargo.toml -@@ -15,6 +15,7 @@ serde_json = "1.0" - serde = { version = "1.0", features = ["derive"] } - # Tauri - tauri = { version = "1.2.4", features = [ -+ "updater", - "dialog-save", - "process-relaunch", - "window-close", diff --git a/pkgs/development/tools/devpod/default.nix b/pkgs/development/tools/devpod/default.nix index e7851d7d1e29..0f31faf8427b 100644 --- a/pkgs/development/tools/devpod/default.nix +++ b/pkgs/development/tools/devpod/default.nix @@ -1,54 +1,53 @@ { lib, + stdenv, buildGoModule, - copyDesktopItems, - darwin, - desktopToDarwinBundle, + rustPlatform, fetchFromGitHub, fetchYarnDeps, - gtk3, + + cargo-tauri_1, + desktop-file-utils, installShellFiles, - jq, + makeBinaryWrapper, + nodejs, + pkg-config, + yarnConfigHook, + wrapGAppsHook3, + + glib-networking, libayatana-appindicator, libsoup_2_4, - makeDesktopItem, - mkYarnPackage, openssl, - pkg-config, - rust, - rustPlatform, - stdenv, - testers, webkitgtk_4_0, + + testers, }: let - pname = "devpod"; version = "0.5.20"; src = fetchFromGitHub { owner = "loft-sh"; - repo = pname; - rev = "v${version}"; - sha256 = "sha256-8LbqrOKC1als3Xm6ZuU2AySwT0UWjLN2xh+/CvioYew="; + repo = "devpod"; + tag = "v${version}"; + hash = "sha256-8LbqrOKC1als3Xm6ZuU2AySwT0UWjLN2xh+/CvioYew="; }; - meta = with lib; { + meta = { description = "Codespaces but open-source, client-only and unopinionated: Works with any IDE and lets you use any cloud, kubernetes or just localhost docker"; mainProgram = "devpod"; homepage = "https://devpod.sh"; - license = licenses.mpl20; - maintainers = with maintainers; [ maxbrunet ]; + license = lib.licenses.mpl20; + maintainers = with lib.maintainers; [ + maxbrunet + tomasajt + ]; }; -in -rec { - devpod = buildGoModule { - inherit - version - src - pname - meta - ; + + devpod = buildGoModule (finalAttrs: { + pname = "devpod"; + inherit version src meta; vendorHash = null; @@ -70,128 +69,107 @@ rec { ''; passthru.tests.version = testers.testVersion { - package = devpod; + package = finalAttrs.finalPackage; command = "devpod version"; version = "v${version}"; }; - }; + }); - devpod-desktop = - let - frontend-build = mkYarnPackage { - inherit version; - pname = "devpod-frontend"; + devpod-desktop = rustPlatform.buildRustPackage { + pname = "devpod-desktop"; + inherit version src; - src = "${src}/desktop"; + sourceRoot = "${src.name}/desktop"; - offlineCache = fetchYarnDeps { - yarnLock = "${src}/desktop/yarn.lock"; - hash = "sha256-vUV4yX+UvEKrP0vHxjGwtW2WyONGqHVmFor+WqWbkCc="; - }; + offlineCache = fetchYarnDeps { + yarnLock = "${src}/desktop/yarn.lock"; + hash = "sha256-vUV4yX+UvEKrP0vHxjGwtW2WyONGqHVmFor+WqWbkCc="; + }; - packageJSON = ./package.json; + cargoRoot = "src-tauri"; + buildAndTestSubdir = "src-tauri"; - buildPhase = '' - export HOME=$(mktemp -d) - yarn --offline run build + useFetchCargoVendor = true; + cargoHash = "sha256-HD9b7OWilltL5Ymj28zoZwv5TJV3HT3LyCdagMqLH6E="; - cp -r deps/devpod/dist $out - ''; + patches = [ + # don't create a .desktop file automatically registered to open the devpod:// URI scheme + # we edit the in-store .desktop file in postInstall to support opening the scheme, + # but users will have to configure the default handler manually + ./dont-auto-register-scheme.patch - doDist = false; - dontInstall = true; - }; + # disable the button that symlinks the `devpod-cli` binary to ~/.local/bin/devpod + # and don't show popup where it prompts you to press the above mentioned button + # we'll symlink it manually to $out/bin/devpod in postInstall + ./dont-copy-sidecar-out-of-store.patch + ]; - rustTargetPlatformSpec = stdenv.hostPlatform.rust.rustcTarget; - in - rustPlatform.buildRustPackage { - inherit version src; - pname = "devpod-desktop"; - - sourceRoot = "${src.name}/desktop/src-tauri"; - - useFetchCargoVendor = true; - cargoHash = "sha256-HD9b7OWilltL5Ymj28zoZwv5TJV3HT3LyCdagMqLH6E="; - - # Workaround: - # The `tauri` dependency features on the `Cargo.toml` file does not match the allowlist defined under `tauri.conf.json`. - # Please run `tauri dev` or `tauri build` or add the `updater` feature. - # Upstream is not interested in fixing that: https://github.com/loft-sh/devpod/pull/648 - patches = [ ./add-tauri-updater-feature.patch ]; - - postPatch = - '' - ln -s ${devpod}/bin/devpod bin/devpod-cli-${rustTargetPlatformSpec} - cp -r ${frontend-build} frontend-build - - substituteInPlace tauri.conf.json --replace '"distDir": "../dist",' '"distDir": "frontend-build",' - '' - + lib.optionalString stdenv.hostPlatform.isLinux '' - substituteInPlace $cargoDepsCopy/libappindicator-sys-*/src/lib.rs \ - --replace "libayatana-appindicator3.so.1" "${libayatana-appindicator}/lib/libayatana-appindicator3.so.1" - - # Since `cargo build` is used instead of `tauri build`, configs are merged manually. - jq --slurp '.[0] * .[1]' tauri.conf.json tauri-linux.conf.json >tauri.conf.json.merged - mv tauri.conf.json.merged tauri.conf.json - ''; - - nativeBuildInputs = - [ - copyDesktopItems - pkg-config - ] - ++ lib.optionals stdenv.hostPlatform.isLinux [ - jq - ] - ++ lib.optionals stdenv.hostPlatform.isDarwin [ - desktopToDarwinBundle - ]; - - buildInputs = - [ - libsoup_2_4 - openssl - ] - ++ lib.optionals stdenv.hostPlatform.isLinux [ - gtk3 - libayatana-appindicator - webkitgtk_4_0 - ] - ++ lib.optionals stdenv.hostPlatform.isDarwin [ - darwin.apple_sdk.frameworks.Carbon - darwin.apple_sdk.frameworks.Cocoa - darwin.apple_sdk.frameworks.WebKit - ]; - - desktopItems = [ - (makeDesktopItem { - name = "DevPod"; - categories = [ "Development" ]; - comment = "Spin up dev environments in any infra"; - desktopName = "DevPod"; - exec = "DevPod %U"; - icon = "DevPod"; - terminal = false; - type = "Application"; - mimeTypes = [ "x-scheme-handler/devpod" ]; - }) - ]; - - postInstall = '' - ln -sf ${devpod}/bin/devpod $out/bin/devpod-cli - mv $out/bin/devpod-desktop $out/bin/DevPod - - mkdir -p $out/share/icons/hicolor/{256x256@2,128x128,32x32}/apps - cp icons/128x128@2x.png $out/share/icons/hicolor/256x256@2/apps/DevPod.png - cp icons/128x128.png $out/share/icons/hicolor/128x128/apps/DevPod.png - cp icons/32x32.png $out/share/icons/hicolor/32x32/apps/DevPod.png + postPatch = + '' + ln -s ${lib.getExe devpod} src-tauri/bin/devpod-cli-${stdenv.hostPlatform.rust.rustcTarget} + '' + + lib.optionalString stdenv.hostPlatform.isLinux '' + substituteInPlace $cargoDepsCopy/libappindicator-sys-*/src/lib.rs \ + --replace-fail "libayatana-appindicator3.so.1" "${libayatana-appindicator}/lib/libayatana-appindicator3.so.1" ''; - meta = meta // { - mainProgram = "DevPod"; - # darwin does not build - # https://github.com/h4llow3En/mac-notification-sys/issues/28 - platforms = lib.platforms.linux; - }; + nativeBuildInputs = + [ + cargo-tauri_1.hook + nodejs + yarnConfigHook + ] + ++ lib.optionals stdenv.hostPlatform.isLinux [ + desktop-file-utils + pkg-config + wrapGAppsHook3 + ] + ++ lib.optionals stdenv.hostPlatform.isDarwin [ + makeBinaryWrapper + ]; + + buildInputs = lib.optionals stdenv.hostPlatform.isLinux [ + glib-networking + libayatana-appindicator + libsoup_2_4 + openssl + webkitgtk_4_0 + ]; + + postInstall = + lib.optionalString stdenv.hostPlatform.isDarwin '' + # replace sidecar binary with symlink + ln -sf ${lib.getExe devpod} "$out/Applications/DevPod.app/Contents/MacOS/devpod-cli" + + makeWrapper "$out/Applications/DevPod.app/Contents/MacOS/DevPod" "$out/bin/dev-pod" + '' + + lib.optionalString stdenv.hostPlatform.isLinux '' + # replace sidecar binary with symlink + ln -sf ${lib.getExe devpod} "$out/bin/devpod-cli" + + # set up scheme handling + desktop-file-edit "$out/share/applications/dev-pod.desktop" \ + --set-key="Exec" --set-value="dev-pod %u" \ + --set-key="MimeType" --set-value="x-scheme-handler/devpod" + '' + + '' + # propagate the `devpod` command + ln -s ${lib.getExe devpod} "$out/bin/devpod" + ''; + + # we only want to wrap the main binary + dontWrapGApps = true; + + postFixup = lib.optionalString stdenv.hostPlatform.isLinux '' + wrapGApp "$out/bin/dev-pod" + ''; + + meta = meta // { + mainProgram = "dev-pod"; + platforms = lib.platforms.linux ++ lib.platforms.darwin; }; + }; +in +{ + inherit devpod devpod-desktop; } diff --git a/pkgs/development/tools/devpod/dont-auto-register-scheme.patch b/pkgs/development/tools/devpod/dont-auto-register-scheme.patch new file mode 100644 index 000000000000..1d05ada1ce6e --- /dev/null +++ b/pkgs/development/tools/devpod/dont-auto-register-scheme.patch @@ -0,0 +1,13 @@ +diff --git a/src-tauri/src/custom_protocol.rs b/src-tauri/src/custom_protocol.rs +index b6ed6e7..5434337 100644 +--- a/src-tauri/src/custom_protocol.rs ++++ b/src-tauri/src/custom_protocol.rs +@@ -162,7 +162,7 @@ impl CustomProtocol { + pub fn setup(&self, app: AppHandle) { + let app_handle = app.clone(); + +- let result = tauri_plugin_deep_link::register(APP_URL_SCHEME, move |url_scheme| { ++ let result = tauri_plugin_deep_link::listen(move |url_scheme| { + tauri::async_runtime::block_on(async { + info!("App opened with URL: {:?}", url_scheme.to_string()); + diff --git a/pkgs/development/tools/devpod/dont-copy-sidecar-out-of-store.patch b/pkgs/development/tools/devpod/dont-copy-sidecar-out-of-store.patch new file mode 100644 index 000000000000..6aab73b0c795 --- /dev/null +++ b/pkgs/development/tools/devpod/dont-copy-sidecar-out-of-store.patch @@ -0,0 +1,25 @@ +diff --git a/src/client/client.ts b/src/client/client.ts +index 3e1747e..a842534 100644 +--- a/src/client/client.ts ++++ b/src/client/client.ts +@@ -250,6 +250,7 @@ class Client { + } + + public async isCLIInstalled(): Promise> { ++ return Return.Value(true); + try { + // we're in a flatpak, we need to check in other paths. + if (import.meta.env.TAURI_IS_FLATPAK === "true") { +diff --git a/src/components/useInstallCLI.tsx b/src/components/useInstallCLI.tsx +index ba3be79..ad25f3f 100644 +--- a/src/components/useInstallCLI.tsx ++++ b/src/components/useInstallCLI.tsx +@@ -77,7 +77,7 @@ export function useInstallCLI() { + variant="outline" + isLoading={isLoading} + onClick={() => addBinaryToPath({})} +- isDisabled={status === "success"}> ++ isDisabled={true}> + Add CLI to Path + + diff --git a/pkgs/development/tools/devpod/package.json b/pkgs/development/tools/devpod/package.json deleted file mode 100644 index 1efadc72ce6f..000000000000 --- a/pkgs/development/tools/devpod/package.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "name": "devpod", - "private": true, - "version": "0.0.0", - "type": "module", - "scripts": { - "dev": "vite", - "build": "tsc && vite build", - "preview": "vite preview", - "tauri": "tauri", - "desktop:dev": "tauri dev --config src-tauri/tauri-dev.conf.json", - "desktop:dev:debug": "export DEBUG=true; yarn desktop:dev", - "desktop:build:dev": "DEBUG=true tauri build --config src-tauri/tauri-dev.conf.json", - "desktop:build:debug": "tauri build --debug", - "desktop:build": "tauri build --features enable-updater", - "format:check": "prettier --check .", - "format:fix": "prettier --write .", - "types:check": "tsc -p ./tsconfig.json --noEmit" - }, - "dependencies": { - "@chakra-ui/icons": "2.1.1", - "@chakra-ui/react": "2.8.1", - "@emotion/react": "11.11.1", - "@emotion/styled": "11.11.0", - "@headlessui/react": "1.7.17", - "@tanstack/react-query": "4.36.1", - "@tanstack/react-query-devtools": "4.36.1", - "@tanstack/react-table": "8.10.7", - "@tauri-apps/api": "1.5.3", - "dayjs": "1.11.10", - "framer-motion": "10.16.9", - "markdown-to-jsx": "7.3.2", - "react": "18.2.0", - "react-dom": "18.2.0", - "react-hook-form": "7.48.2", - "react-icons": "4.12.0", - "react-router": "6.20.0", - "react-router-dom": "6.20.0", - "tauri-plugin-store-api": "https://github.com/tauri-apps/tauri-plugin-store#v1", - "uuid": "9.0.1", - "xterm": "5.3.0", - "xterm-addon-fit": "0.7.0" - }, - "devDependencies": { - "@tanstack/eslint-plugin-query": "4.36.1", - "@tauri-apps/cli": "1.5.11", - "@types/node": "18.15.3", - "@types/react": "18.2.28", - "@types/react-dom": "18.2.13", - "@types/uuid": "9.0.5", - "@typescript-eslint/eslint-plugin": "5.59.11", - "@typescript-eslint/parser": "5.59.11", - "@vitejs/plugin-react": "4.1.0", - "eslint": "8.44.0", - "eslint-config-prettier": "8.8.0", - "eslint-config-react-app": "7.0.1", - "eslint-plugin-react": "7.34.1", - "eslint-plugin-react-hooks": "4.6.0", - "prettier": "3.0.3", - "typescript": "5.0.4", - "vite": "4.4.9" - }, - "resolutions": { - "lodash": "4.17.21" - } -}