mirror of
https://github.com/enso-org/enso.git
synced 2024-09-11 13:15:52 +03:00
Build Script Post-Gui1 Cleanup (#9376)
This PR: * removes much of logic related to building and packaging the gui1; * made `./run gui` and `./run ide` work with the new gui; * rename numerous references to the "gui2" or "new gui" in favor of simply "gui", same for "ide".
This commit is contained in:
parent
a5a729a7d6
commit
d9ca6cf023
126
.github/workflows/gui.yml
vendored
126
.github/workflows/gui.yml
vendored
@ -173,6 +173,55 @@ jobs:
|
||||
access_token: ${{ github.token }}
|
||||
permissions:
|
||||
actions: write
|
||||
enso-build-ci-gen-job-gui-test-linux-x86_64:
|
||||
name: GUI tests (linux, x86_64)
|
||||
runs-on:
|
||||
- self-hosted
|
||||
- Linux
|
||||
steps:
|
||||
- if: startsWith(runner.name, 'GitHub Actions') || startsWith(runner.name, 'Hosted Agent')
|
||||
name: Setup conda (GH runners only)
|
||||
uses: s-weigand/setup-conda@v1.2.1
|
||||
with:
|
||||
update-conda: false
|
||||
conda-channels: anaconda, conda-forge
|
||||
- if: startsWith(runner.name, 'GitHub Actions') || startsWith(runner.name, 'Hosted Agent')
|
||||
name: Installing wasm-pack
|
||||
uses: jetli/wasm-pack-action@v0.4.0
|
||||
with:
|
||||
version: v0.10.2
|
||||
- name: Expose Artifact API and context information.
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: "\n core.exportVariable(\"ACTIONS_RUNTIME_TOKEN\", process.env[\"ACTIONS_RUNTIME_TOKEN\"])\n core.exportVariable(\"ACTIONS_RUNTIME_URL\", process.env[\"ACTIONS_RUNTIME_URL\"])\n core.exportVariable(\"GITHUB_RETENTION_DAYS\", process.env[\"GITHUB_RETENTION_DAYS\"])\n console.log(context)\n "
|
||||
- name: Checking out the repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
clean: false
|
||||
submodules: recursive
|
||||
- name: Build Script Setup
|
||||
run: ./run --help || (git clean -ffdx && ./run --help)
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- if: "(contains(github.event.pull_request.labels.*.name, 'CI: Clean build required') || inputs.clean_build_required)"
|
||||
name: Clean before
|
||||
run: ./run git-clean
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- run: ./run gui test
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- if: failure() && runner.os == 'Windows'
|
||||
name: List files if failed (Windows)
|
||||
run: Get-ChildItem -Force -Recurse
|
||||
- if: failure() && runner.os != 'Windows'
|
||||
name: List files if failed (non-Windows)
|
||||
run: ls -lAR
|
||||
- if: "(always()) && (contains(github.event.pull_request.labels.*.name, 'CI: Clean build required') || inputs.clean_build_required)"
|
||||
name: Clean after
|
||||
run: ./run git-clean
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
enso-build-ci-gen-job-lint-linux-x86_64:
|
||||
name: Lint (linux, x86_64)
|
||||
runs-on:
|
||||
@ -223,7 +272,7 @@ jobs:
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
enso-build-ci-gen-job-native-test-linux-x86_64:
|
||||
name: Native GUI tests (linux, x86_64)
|
||||
name: Native Rust tests (linux, x86_64)
|
||||
runs-on:
|
||||
- self-hosted
|
||||
- Linux
|
||||
@ -272,7 +321,7 @@ jobs:
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
enso-build-ci-gen-job-new-gui-build-linux-x86_64:
|
||||
name: New (Vue) GUI build (linux, x86_64)
|
||||
name: GUI build (linux, x86_64)
|
||||
runs-on:
|
||||
- self-hosted
|
||||
- Linux
|
||||
@ -306,7 +355,7 @@ jobs:
|
||||
run: ./run git-clean
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- run: ./run gui2 build
|
||||
- run: ./run gui build
|
||||
env:
|
||||
ENSO_CLOUD_API_URL: ${{ vars.ENSO_CLOUD_API_URL }}
|
||||
ENSO_CLOUD_CHAT_URL: ${{ vars.ENSO_CLOUD_CHAT_URL }}
|
||||
@ -331,7 +380,7 @@ jobs:
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
enso-build-ci-gen-job-new-gui-build-macos-x86_64:
|
||||
name: New (Vue) GUI build (macos, x86_64)
|
||||
name: GUI build (macos, x86_64)
|
||||
runs-on:
|
||||
- macos-latest
|
||||
steps:
|
||||
@ -364,7 +413,7 @@ jobs:
|
||||
run: ./run git-clean
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- run: ./run gui2 build
|
||||
- run: ./run gui build
|
||||
env:
|
||||
ENSO_CLOUD_API_URL: ${{ vars.ENSO_CLOUD_API_URL }}
|
||||
ENSO_CLOUD_CHAT_URL: ${{ vars.ENSO_CLOUD_CHAT_URL }}
|
||||
@ -389,7 +438,7 @@ jobs:
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
enso-build-ci-gen-job-new-gui-build-windows-x86_64:
|
||||
name: New (Vue) GUI build (windows, x86_64)
|
||||
name: GUI build (windows, x86_64)
|
||||
runs-on:
|
||||
- self-hosted
|
||||
- Windows
|
||||
@ -423,7 +472,7 @@ jobs:
|
||||
run: ./run git-clean
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- run: ./run gui2 build
|
||||
- run: ./run gui build
|
||||
env:
|
||||
ENSO_CLOUD_API_URL: ${{ vars.ENSO_CLOUD_API_URL }}
|
||||
ENSO_CLOUD_CHAT_URL: ${{ vars.ENSO_CLOUD_CHAT_URL }}
|
||||
@ -447,56 +496,7 @@ jobs:
|
||||
run: ./run git-clean
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
enso-build-ci-gen-job-new-gui-test-linux-x86_64:
|
||||
name: New (Vue) GUI tests (linux, x86_64)
|
||||
runs-on:
|
||||
- self-hosted
|
||||
- Linux
|
||||
steps:
|
||||
- if: startsWith(runner.name, 'GitHub Actions') || startsWith(runner.name, 'Hosted Agent')
|
||||
name: Setup conda (GH runners only)
|
||||
uses: s-weigand/setup-conda@v1.2.1
|
||||
with:
|
||||
update-conda: false
|
||||
conda-channels: anaconda, conda-forge
|
||||
- if: startsWith(runner.name, 'GitHub Actions') || startsWith(runner.name, 'Hosted Agent')
|
||||
name: Installing wasm-pack
|
||||
uses: jetli/wasm-pack-action@v0.4.0
|
||||
with:
|
||||
version: v0.10.2
|
||||
- name: Expose Artifact API and context information.
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: "\n core.exportVariable(\"ACTIONS_RUNTIME_TOKEN\", process.env[\"ACTIONS_RUNTIME_TOKEN\"])\n core.exportVariable(\"ACTIONS_RUNTIME_URL\", process.env[\"ACTIONS_RUNTIME_URL\"])\n core.exportVariable(\"GITHUB_RETENTION_DAYS\", process.env[\"GITHUB_RETENTION_DAYS\"])\n console.log(context)\n "
|
||||
- name: Checking out the repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
clean: false
|
||||
submodules: recursive
|
||||
- name: Build Script Setup
|
||||
run: ./run --help || (git clean -ffdx && ./run --help)
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- if: "(contains(github.event.pull_request.labels.*.name, 'CI: Clean build required') || inputs.clean_build_required)"
|
||||
name: Clean before
|
||||
run: ./run git-clean
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- run: ./run gui2 test
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- if: failure() && runner.os == 'Windows'
|
||||
name: List files if failed (Windows)
|
||||
run: Get-ChildItem -Force -Recurse
|
||||
- if: failure() && runner.os != 'Windows'
|
||||
name: List files if failed (non-Windows)
|
||||
run: ls -lAR
|
||||
- if: "(always()) && (contains(github.event.pull_request.labels.*.name, 'CI: Clean build required') || inputs.clean_build_required)"
|
||||
name: Clean after
|
||||
run: ./run git-clean
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
enso-build-ci-gen-job-package-new-ide-linux-x86_64:
|
||||
enso-build-ci-gen-job-package-ide-linux-x86_64:
|
||||
name: Package New IDE (linux, x86_64)
|
||||
needs:
|
||||
- enso-build-ci-gen-job-build-backend-linux-x86_64
|
||||
@ -533,7 +533,7 @@ jobs:
|
||||
run: ./run git-clean
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- run: ./run ide2 build --backend-source current-ci-run --gui2-upload-artifact false
|
||||
- run: ./run ide build --backend-source current-ci-run --gui-upload-artifact false
|
||||
env:
|
||||
ENSO_CLOUD_API_URL: ${{ vars.ENSO_CLOUD_API_URL }}
|
||||
ENSO_CLOUD_CHAT_URL: ${{ vars.ENSO_CLOUD_CHAT_URL }}
|
||||
@ -557,7 +557,7 @@ jobs:
|
||||
run: ./run git-clean
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
enso-build-ci-gen-job-package-new-ide-macos-x86_64:
|
||||
enso-build-ci-gen-job-package-ide-macos-x86_64:
|
||||
name: Package New IDE (macos, x86_64)
|
||||
needs:
|
||||
- enso-build-ci-gen-job-build-backend-macos-x86_64
|
||||
@ -599,7 +599,7 @@ jobs:
|
||||
run: npm uninstall --save --workspace enso electron-builder
|
||||
- name: Install new Electron Builder
|
||||
run: npm install --save-dev --workspace enso electron-builder@24.6.4
|
||||
- run: ./run ide2 build --backend-source current-ci-run --gui2-upload-artifact false
|
||||
- run: ./run ide build --backend-source current-ci-run --gui-upload-artifact false
|
||||
env:
|
||||
APPLEID: ${{ secrets.APPLE_NOTARIZATION_USERNAME }}
|
||||
APPLEIDPASS: ${{ secrets.APPLE_NOTARIZATION_PASSWORD }}
|
||||
@ -630,7 +630,7 @@ jobs:
|
||||
run: ./run git-clean
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
enso-build-ci-gen-job-package-new-ide-windows-x86_64:
|
||||
enso-build-ci-gen-job-package-ide-windows-x86_64:
|
||||
name: Package New IDE (windows, x86_64)
|
||||
needs:
|
||||
- enso-build-ci-gen-job-build-backend-windows-x86_64
|
||||
@ -667,7 +667,7 @@ jobs:
|
||||
run: ./run git-clean
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- run: ./run ide2 build --backend-source current-ci-run --gui2-upload-artifact false
|
||||
- run: ./run ide build --backend-source current-ci-run --gui-upload-artifact false
|
||||
env:
|
||||
ENSO_CLOUD_API_URL: ${{ vars.ENSO_CLOUD_API_URL }}
|
||||
ENSO_CLOUD_CHAT_URL: ${{ vars.ENSO_CLOUD_CHAT_URL }}
|
||||
@ -694,7 +694,7 @@ jobs:
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
enso-build-ci-gen-job-wasm-test-linux-x86_64:
|
||||
name: WASM GUI tests (linux, x86_64)
|
||||
name: WASM tests (linux, x86_64)
|
||||
runs-on:
|
||||
- self-hosted
|
||||
- Linux
|
||||
|
32
.github/workflows/release.yml
vendored
32
.github/workflows/release.yml
vendored
@ -273,10 +273,10 @@ jobs:
|
||||
name: Publish release (linux, x86_64)
|
||||
needs:
|
||||
- enso-build-ci-gen-draft-release-linux-x86_64
|
||||
- enso-build-ci-gen-upload-ide2-linux-x86_64
|
||||
- enso-build-ci-gen-upload-ide2-macos-aarch64
|
||||
- enso-build-ci-gen-upload-ide2-macos-x86_64
|
||||
- enso-build-ci-gen-upload-ide2-windows-x86_64
|
||||
- enso-build-ci-gen-upload-ide-linux-x86_64
|
||||
- enso-build-ci-gen-upload-ide-macos-aarch64
|
||||
- enso-build-ci-gen-upload-ide-macos-x86_64
|
||||
- enso-build-ci-gen-upload-ide-windows-x86_64
|
||||
runs-on:
|
||||
- self-hosted
|
||||
- Linux
|
||||
@ -330,8 +330,8 @@ jobs:
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.ARTEFACT_S3_SECRET_ACCESS_KEY }}
|
||||
ENSO_RELEASE_ID: ${{ needs.enso-build-ci-gen-draft-release-linux-x86_64.outputs.ENSO_RELEASE_ID }}
|
||||
ENSO_VERSION: ${{ needs.enso-build-ci-gen-draft-release-linux-x86_64.outputs.ENSO_VERSION }}
|
||||
enso-build-ci-gen-upload-ide2-linux-x86_64:
|
||||
name: Build New IDE (linux, x86_64)
|
||||
enso-build-ci-gen-upload-ide-linux-x86_64:
|
||||
name: Build IDE (linux, x86_64)
|
||||
needs:
|
||||
- enso-build-ci-gen-draft-release-linux-x86_64
|
||||
- enso-build-ci-gen-job-upload-backend-linux-x86_64
|
||||
@ -368,7 +368,7 @@ jobs:
|
||||
run: ./run git-clean
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- run: ./run ide2 upload --backend-source release --backend-release ${{env.ENSO_RELEASE_ID}}
|
||||
- run: ./run ide upload --backend-source release --backend-release ${{env.ENSO_RELEASE_ID}}
|
||||
env:
|
||||
ENSO_CLOUD_API_URL: ${{ vars.ENSO_CLOUD_API_URL }}
|
||||
ENSO_CLOUD_CHAT_URL: ${{ vars.ENSO_CLOUD_CHAT_URL }}
|
||||
@ -395,8 +395,8 @@ jobs:
|
||||
env:
|
||||
ENSO_RELEASE_ID: ${{ needs.enso-build-ci-gen-draft-release-linux-x86_64.outputs.ENSO_RELEASE_ID }}
|
||||
ENSO_VERSION: ${{ needs.enso-build-ci-gen-draft-release-linux-x86_64.outputs.ENSO_VERSION }}
|
||||
enso-build-ci-gen-upload-ide2-macos-aarch64:
|
||||
name: Build New IDE (macos, aarch64)
|
||||
enso-build-ci-gen-upload-ide-macos-aarch64:
|
||||
name: Build IDE (macos, aarch64)
|
||||
needs:
|
||||
- enso-build-ci-gen-draft-release-linux-x86_64
|
||||
- enso-build-ci-gen-job-upload-backend-macos-aarch64
|
||||
@ -440,7 +440,7 @@ jobs:
|
||||
run: npm uninstall --save --workspace enso electron-builder
|
||||
- name: Install new Electron Builder
|
||||
run: npm install --save-dev --workspace enso electron-builder@24.6.4
|
||||
- run: ./run ide2 upload --backend-source release --backend-release ${{env.ENSO_RELEASE_ID}}
|
||||
- run: ./run ide upload --backend-source release --backend-release ${{env.ENSO_RELEASE_ID}}
|
||||
env:
|
||||
APPLEID: ${{ secrets.APPLE_NOTARIZATION_USERNAME }}
|
||||
APPLEIDPASS: ${{ secrets.APPLE_NOTARIZATION_PASSWORD }}
|
||||
@ -474,8 +474,8 @@ jobs:
|
||||
env:
|
||||
ENSO_RELEASE_ID: ${{ needs.enso-build-ci-gen-draft-release-linux-x86_64.outputs.ENSO_RELEASE_ID }}
|
||||
ENSO_VERSION: ${{ needs.enso-build-ci-gen-draft-release-linux-x86_64.outputs.ENSO_VERSION }}
|
||||
enso-build-ci-gen-upload-ide2-macos-x86_64:
|
||||
name: Build New IDE (macos, x86_64)
|
||||
enso-build-ci-gen-upload-ide-macos-x86_64:
|
||||
name: Build IDE (macos, x86_64)
|
||||
needs:
|
||||
- enso-build-ci-gen-draft-release-linux-x86_64
|
||||
- enso-build-ci-gen-job-upload-backend-macos-x86_64
|
||||
@ -517,7 +517,7 @@ jobs:
|
||||
run: npm uninstall --save --workspace enso electron-builder
|
||||
- name: Install new Electron Builder
|
||||
run: npm install --save-dev --workspace enso electron-builder@24.6.4
|
||||
- run: ./run ide2 upload --backend-source release --backend-release ${{env.ENSO_RELEASE_ID}}
|
||||
- run: ./run ide upload --backend-source release --backend-release ${{env.ENSO_RELEASE_ID}}
|
||||
env:
|
||||
APPLEID: ${{ secrets.APPLE_NOTARIZATION_USERNAME }}
|
||||
APPLEIDPASS: ${{ secrets.APPLE_NOTARIZATION_PASSWORD }}
|
||||
@ -551,8 +551,8 @@ jobs:
|
||||
env:
|
||||
ENSO_RELEASE_ID: ${{ needs.enso-build-ci-gen-draft-release-linux-x86_64.outputs.ENSO_RELEASE_ID }}
|
||||
ENSO_VERSION: ${{ needs.enso-build-ci-gen-draft-release-linux-x86_64.outputs.ENSO_VERSION }}
|
||||
enso-build-ci-gen-upload-ide2-windows-x86_64:
|
||||
name: Build New IDE (windows, x86_64)
|
||||
enso-build-ci-gen-upload-ide-windows-x86_64:
|
||||
name: Build IDE (windows, x86_64)
|
||||
needs:
|
||||
- enso-build-ci-gen-draft-release-linux-x86_64
|
||||
- enso-build-ci-gen-job-upload-backend-windows-x86_64
|
||||
@ -589,7 +589,7 @@ jobs:
|
||||
run: ./run git-clean
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- run: ./run ide2 upload --backend-source release --backend-release ${{env.ENSO_RELEASE_ID}}
|
||||
- run: ./run ide upload --backend-source release --backend-release ${{env.ENSO_RELEASE_ID}}
|
||||
env:
|
||||
ENSO_CLOUD_API_URL: ${{ vars.ENSO_CLOUD_API_URL }}
|
||||
ENSO_CLOUD_CHAT_URL: ${{ vars.ENSO_CLOUD_CHAT_URL }}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/** @file ⚠️⚠️⚠️ THIS SCRIPT IS PROVIDED ONLY FOR CONVENIENCE. ⚠️⚠️⚠️
|
||||
* The sources of truth are at `build/build/src/project/gui2.rs` and
|
||||
* The sources of truth are at `build/build/src/project/gui.rs` and
|
||||
* `build/build/src/ide/web/fonts.rs`. */
|
||||
|
||||
import * as fsSync from 'node:fs'
|
||||
|
@ -68,22 +68,13 @@ Artifacts are platform specific and consist of the single image file.
|
||||
|
||||
### GUI
|
||||
|
||||
GUI is the front-end part of the project. It consists of `WASM` target.
|
||||
|
||||
Sources consist mostly of TS code for the web page that embeds the `WASM`
|
||||
binaries.
|
||||
GUI is the front-end part of the project. It also packages WASM-compiled parser
|
||||
written in rust.
|
||||
|
||||
Artifacts are portable across the platforms and consist of the web page that can
|
||||
be served either using Electron client (as IDE does) or using a web server (like
|
||||
the Cloud version of Enso).
|
||||
|
||||
### WASM
|
||||
|
||||
This is the core of GUI, written in Rust. It has no external dependencies.
|
||||
|
||||
Artifacts are portable across the platforms and consist of the single WASM
|
||||
binary accompanied by the JS snippets and glue.
|
||||
|
||||
### Backend
|
||||
|
||||
Backend is the back-end part of the project, as seen from the IDE perspective.
|
||||
|
@ -63,15 +63,6 @@
|
||||
type: project_manager_bundle
|
||||
var: project_manager_bundle
|
||||
dist/:
|
||||
gui/:
|
||||
assets/:
|
||||
dynamic-assets/: # Assets used by the WASM application.
|
||||
pkg.js: # The `pkg.js` artifact of wasm-pack WITH bundled snippets.
|
||||
pkg.js.map: # The sourcemap mapping to `pkg.js` generated by wasm-pack.
|
||||
pkg-opt.wasm: # The optimized WASM artifact.
|
||||
entrypoint.js:
|
||||
style.css:
|
||||
|
||||
gui2/:
|
||||
assets/:
|
||||
|
||||
|
@ -15,10 +15,10 @@ Enso IDE is the main product of the Enso project. The packages are stand-alone,
|
||||
|
||||
Download links:
|
||||
|
||||
- [Linux]({{download_prefix}}/ide2-enso-linux-x86_64-{{version}}.AppImage) (AppImage);
|
||||
- [macOS (x64)]({{download_prefix}}/ide2-enso-mac-x64-{{version}}.dmg) (DMG);
|
||||
- [macOS (arm64)]({{download_prefix}}/ide2-enso-mac-arm64-{{version}}.dmg) (DMG);
|
||||
- [Windows]({{download_prefix}}/ide2-enso-win-x64-{{version}}.exe) (Installer Executable).
|
||||
- [Linux]({{download_prefix}}/enso-linux-x86_64-{{version}}.AppImage) (AppImage);
|
||||
- [macOS (x64)]({{download_prefix}}/enso-mac-x64-{{version}}.dmg) (DMG);
|
||||
- [macOS (arm64)]({{download_prefix}}/enso-mac-arm64-{{version}}.dmg) (DMG);
|
||||
- [Windows]({{download_prefix}}/enso-win-x64-{{version}}.exe) (Installer Executable).
|
||||
|
||||
This is the recommended download for most users.
|
||||
|
||||
|
@ -402,16 +402,16 @@ impl JobArchetype for PublishRelease {
|
||||
|
||||
/// Build new IDE and upload it as a release asset.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct UploadIde2;
|
||||
pub struct UploadIde;
|
||||
|
||||
impl JobArchetype for UploadIde2 {
|
||||
impl JobArchetype for UploadIde {
|
||||
fn job(&self, target: Target) -> Job {
|
||||
RunStepsBuilder::new(
|
||||
"ide2 upload --backend-source release --backend-release ${{env.ENSO_RELEASE_ID}}",
|
||||
"ide upload --backend-source release --backend-release ${{env.ENSO_RELEASE_ID}}",
|
||||
)
|
||||
.cleaning(RELEASE_CLEANING_POLICY)
|
||||
.customize(with_packaging_steps(target.0))
|
||||
.build_job("Build New IDE", target)
|
||||
.build_job("Build IDE", target)
|
||||
}
|
||||
}
|
||||
|
||||
@ -483,9 +483,9 @@ fn add_release_steps(workflow: &mut Workflow) -> Result {
|
||||
for target in RELEASE_TARGETS {
|
||||
let backend_job_id = workflow.add_dependent(target, job::UploadBackend, [&prepare_job_id]);
|
||||
|
||||
let build_ide2_job_id =
|
||||
workflow.add_dependent(target, UploadIde2, [&prepare_job_id, &backend_job_id]);
|
||||
packaging_job_ids.push(build_ide2_job_id.clone());
|
||||
let build_ide_job_id =
|
||||
workflow.add_dependent(target, UploadIde, [&prepare_job_id, &backend_job_id]);
|
||||
packaging_job_ids.push(build_ide_job_id.clone());
|
||||
}
|
||||
|
||||
let publish_deps = {
|
||||
@ -587,7 +587,7 @@ pub fn gui() -> Result<Workflow> {
|
||||
workflow.add(PRIMARY_TARGET, job::Lint);
|
||||
workflow.add(PRIMARY_TARGET, job::WasmTest);
|
||||
workflow.add(PRIMARY_TARGET, job::NativeTest);
|
||||
workflow.add(PRIMARY_TARGET, job::NewGuiTest);
|
||||
workflow.add(PRIMARY_TARGET, job::GuiTest);
|
||||
|
||||
// FIXME: Integration tests are currently always failing.
|
||||
// The should be reinstated when fixed.
|
||||
@ -597,7 +597,7 @@ pub fn gui() -> Result<Workflow> {
|
||||
|
||||
for target in CHECKED_TARGETS {
|
||||
let project_manager_job = workflow.add(target, job::BuildBackend);
|
||||
workflow.add_customized(target, job::PackageNewIde, |job| {
|
||||
workflow.add_customized(target, job::PackageIde, |job| {
|
||||
job.needs.insert(project_manager_job.clone());
|
||||
});
|
||||
workflow.add(target, job::NewGuiBuild);
|
||||
|
@ -264,16 +264,16 @@ pub struct NativeTest;
|
||||
|
||||
impl JobArchetype for NativeTest {
|
||||
fn job(&self, target: Target) -> Job {
|
||||
plain_job(target, "Native GUI tests", "wasm test --no-wasm")
|
||||
plain_job(target, "Native Rust tests", "wasm test --no-wasm")
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct NewGuiTest;
|
||||
pub struct GuiTest;
|
||||
|
||||
impl JobArchetype for NewGuiTest {
|
||||
impl JobArchetype for GuiTest {
|
||||
fn job(&self, target: Target) -> Job {
|
||||
plain_job(target, "New (Vue) GUI tests", "gui2 test")
|
||||
plain_job(target, "GUI tests", "gui test")
|
||||
}
|
||||
}
|
||||
|
||||
@ -283,10 +283,10 @@ pub struct NewGuiBuild;
|
||||
|
||||
impl JobArchetype for NewGuiBuild {
|
||||
fn job(&self, target: Target) -> Job {
|
||||
let command = "gui2 build";
|
||||
let command = "gui build";
|
||||
RunStepsBuilder::new(command)
|
||||
.customize(|step| vec![expose_cloud_vars(step)])
|
||||
.build_job("New (Vue) GUI build", target)
|
||||
.build_job("GUI build", target)
|
||||
}
|
||||
}
|
||||
|
||||
@ -295,7 +295,7 @@ pub struct WasmTest;
|
||||
|
||||
impl JobArchetype for WasmTest {
|
||||
fn job(&self, target: Target) -> Job {
|
||||
plain_job(target, "WASM GUI tests", "wasm test --no-native")
|
||||
plain_job(target, "WASM tests", "wasm test --no-native")
|
||||
}
|
||||
}
|
||||
|
||||
@ -312,18 +312,6 @@ impl JobArchetype for IntegrationTest {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct BuildWasm;
|
||||
|
||||
impl JobArchetype for BuildWasm {
|
||||
fn job(&self, target: Target) -> Job {
|
||||
let command = "wasm build --wasm-upload-artifact ${{ runner.os == 'Linux' }}";
|
||||
RunStepsBuilder::new(command)
|
||||
.customize(|step| vec![step.with_secret_exposed(crate::env::ENSO_AG_GRID_LICENSE_KEY)])
|
||||
.build_job("Build GUI (WASM)", target)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct BuildBackend;
|
||||
|
||||
@ -447,12 +435,12 @@ pub fn with_packaging_steps(os: OS) -> impl FnOnce(Step) -> Vec<Step> {
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct PackageNewIde;
|
||||
pub struct PackageIde;
|
||||
|
||||
impl JobArchetype for PackageNewIde {
|
||||
impl JobArchetype for PackageIde {
|
||||
fn job(&self, target: Target) -> Job {
|
||||
RunStepsBuilder::new(
|
||||
"ide2 build --backend-source current-ci-run --gui2-upload-artifact false",
|
||||
"ide build --backend-source current-ci-run --gui-upload-artifact false",
|
||||
)
|
||||
.customize(with_packaging_steps(target.0))
|
||||
.build_job("Package New IDE", target)
|
||||
|
@ -1,6 +1,5 @@
|
||||
use crate::prelude::*;
|
||||
|
||||
use byte_unit::Byte;
|
||||
use ide_ci::program;
|
||||
use ide_ci::programs;
|
||||
use semver::VersionReq;
|
||||
@ -49,7 +48,6 @@ impl RecognizedProgram {
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub struct ConfigRaw {
|
||||
pub wasm_size_limit: Option<String>,
|
||||
pub required_versions: HashMap<String, String>,
|
||||
}
|
||||
|
||||
@ -58,7 +56,6 @@ pub struct ConfigRaw {
|
||||
/// In our case, it is usually a configuration file in the main repository.
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
|
||||
pub struct Config {
|
||||
pub wasm_size_limit: Option<Byte>,
|
||||
pub required_versions: HashMap<RecognizedProgram, VersionReq>,
|
||||
}
|
||||
|
||||
@ -90,13 +87,7 @@ impl TryFrom<ConfigRaw> for Config {
|
||||
);
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
wasm_size_limit: value
|
||||
.wasm_size_limit
|
||||
.map(|limit_text| <Byte as FromString>::from_str(&limit_text))
|
||||
.transpose()?,
|
||||
required_versions,
|
||||
})
|
||||
Ok(Self { required_versions })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,22 +3,16 @@ use crate::prelude::*;
|
||||
use crate::ide::web::env::CSC_KEY_PASSWORD;
|
||||
use crate::paths::generated;
|
||||
use crate::project::gui::BuildInfo;
|
||||
use crate::project::wasm;
|
||||
use crate::project::IsArtifact;
|
||||
use crate::project::ProcessWrapper;
|
||||
|
||||
use anyhow::Context;
|
||||
use futures_util::future::try_join;
|
||||
use futures_util::future::try_join3;
|
||||
use ide_ci::io::download_all;
|
||||
use ide_ci::ok_ready_boxed;
|
||||
use ide_ci::program::command::FallibleManipulator;
|
||||
use ide_ci::programs::node::NpmCommand;
|
||||
use ide_ci::programs::Npm;
|
||||
use std::process::Stdio;
|
||||
use tempfile::TempDir;
|
||||
use tokio::process::Child;
|
||||
use tracing::Span;
|
||||
|
||||
|
||||
// ==============
|
||||
@ -199,52 +193,6 @@ pub enum Command {
|
||||
Watch,
|
||||
}
|
||||
|
||||
/// Things that are common to `watch` and `build`.
|
||||
#[derive(Debug)]
|
||||
pub struct ContentEnvironment<Assets, Output> {
|
||||
pub asset_dir: Assets,
|
||||
pub wasm: wasm::Artifact,
|
||||
pub output_path: Output,
|
||||
}
|
||||
|
||||
impl<Output: AsRef<Path>> ContentEnvironment<TempDir, Output> {
|
||||
pub async fn new(
|
||||
ide: &IdeDesktop,
|
||||
wasm: impl Future<Output = Result<wasm::Artifact>>,
|
||||
build_info: &BuildInfo,
|
||||
output_path: Output,
|
||||
) -> Result<Self> {
|
||||
crate::web::install(&ide.repo_root).await?;
|
||||
let asset_dir = TempDir::new()?;
|
||||
let assets_download = download_js_assets(&asset_dir);
|
||||
let fonts_download = fonts::install_html_fonts(&ide.cache, &ide.octocrab, &asset_dir);
|
||||
let (wasm, _, _) = try_join3(wasm, assets_download, fonts_download).await?;
|
||||
ide.write_build_info(build_info)?;
|
||||
Ok(ContentEnvironment { asset_dir, wasm, output_path })
|
||||
}
|
||||
}
|
||||
|
||||
impl<Assets: AsRef<Path>, Output: AsRef<Path>> FallibleManipulator
|
||||
for ContentEnvironment<Assets, Output>
|
||||
{
|
||||
fn try_applying<C: IsCommandWrapper + ?Sized>(&self, command: &mut C) -> Result {
|
||||
let artifacts_for_gui =
|
||||
self.wasm.files_to_ship().into_iter().map(|file| file.to_path_buf()).collect_vec();
|
||||
|
||||
command
|
||||
.set_env(env::ENSO_BUILD_GUI, self.output_path.as_ref())?
|
||||
.set_env(env::ENSO_BUILD_GUI_WASM_ARTIFACTS, &artifacts_for_gui)?
|
||||
.set_env(env::ENSO_BUILD_GUI_ASSETS, self.asset_dir.as_ref())?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<Assets, Output> Drop for ContentEnvironment<Assets, Output> {
|
||||
fn drop(&mut self) {
|
||||
info!("Dropping content environment.")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn target_os_flag(os: OS) -> Result<&'static str> {
|
||||
match os {
|
||||
OS::Windows => Ok("--win"),
|
||||
@ -332,51 +280,6 @@ impl IdeDesktop {
|
||||
Ok(IconsArtifacts(output_path.as_ref().into()))
|
||||
}
|
||||
|
||||
#[tracing::instrument(name="Building IDE Content.", skip_all, fields(
|
||||
dest = %output_path.as_ref().display(),
|
||||
build_info,
|
||||
err))]
|
||||
pub async fn build_content<P: AsRef<Path>>(
|
||||
&self,
|
||||
wasm: impl Future<Output = Result<wasm::Artifact>>,
|
||||
build_info: &BuildInfo,
|
||||
output_path: P,
|
||||
) -> Result<ContentEnvironment<TempDir, P>> {
|
||||
let env = ContentEnvironment::new(self, wasm, build_info, output_path).await?;
|
||||
self.npm()?
|
||||
.try_applying(&env)?
|
||||
.workspace(Workspaces::Content)
|
||||
.run("build")
|
||||
.run_ok()
|
||||
.await?;
|
||||
|
||||
Ok(env)
|
||||
}
|
||||
|
||||
|
||||
#[tracing::instrument(name="Setting up GUI Content watcher.",
|
||||
fields(wasm = tracing::field::Empty),
|
||||
err)]
|
||||
pub async fn watch_content(
|
||||
&self,
|
||||
wasm: impl Future<Output = Result<wasm::Artifact>>,
|
||||
build_info: &BuildInfo,
|
||||
) -> Result<Watcher> {
|
||||
// When watching we expect our artifacts to be served through server, not appear in any
|
||||
// specific location on the disk.
|
||||
let output_path = TempDir::new()?;
|
||||
let watch_environment =
|
||||
ContentEnvironment::new(self, wasm, build_info, output_path).await?;
|
||||
Span::current().record("wasm", watch_environment.wasm.as_ref().as_str());
|
||||
let child_process = self
|
||||
.npm()?
|
||||
.try_applying(&watch_environment)?
|
||||
.workspace(Workspaces::Content)
|
||||
.run("watch")
|
||||
.spawn_intercepting()?;
|
||||
Ok(Watcher { child_process, watch_environment })
|
||||
}
|
||||
|
||||
/// Build the full Electron package, using the electron-builder.
|
||||
#[tracing::instrument(name="Preparing distribution of the IDE.", skip_all, fields(
|
||||
dest = %output_path.as_ref().display(),
|
||||
@ -458,68 +361,6 @@ impl IdeDesktop {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Spawn the watch script for the client.
|
||||
pub async fn watch(
|
||||
&self,
|
||||
wasm_watch_job: BoxFuture<
|
||||
'static,
|
||||
Result<crate::project::PerhapsWatched<crate::project::Wasm>>,
|
||||
>,
|
||||
build_info: BoxFuture<'static, Result<BuildInfo>>,
|
||||
get_project_manager: BoxFuture<'static, Result<crate::project::backend::Artifact>>,
|
||||
ide_options: Vec<String>,
|
||||
) -> Result {
|
||||
let npm_install_job = crate::web::install(&self.repo_root);
|
||||
// TODO: This could be possibly optimized by awaiting WASM a bit later, and passing its
|
||||
// future to the ContentEnvironment. However, the code would get a little tricky.
|
||||
// Should be reconsidered in the future, based on actual timings.
|
||||
let (_npm_installed, watched_wasm, project_manager) =
|
||||
try_join!(npm_install_job, wasm_watch_job, get_project_manager)?;
|
||||
|
||||
let pm_bundle = ProjectManagerInfo::new(&project_manager)?;
|
||||
|
||||
let temp_dir_for_gui = TempDir::new()?;
|
||||
let content_env = ContentEnvironment::new(
|
||||
self,
|
||||
ok_ready_boxed(watched_wasm.as_ref().clone()),
|
||||
&build_info.await?,
|
||||
&temp_dir_for_gui,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let mut script_args = Vec::new();
|
||||
if !ide_options.is_empty() {
|
||||
script_args.push("--");
|
||||
script_args.extend(ide_options.iter().map(String::as_str));
|
||||
}
|
||||
|
||||
|
||||
let temp_dir_for_ide = TempDir::new()?;
|
||||
self.npm()?
|
||||
.try_applying(&content_env)?
|
||||
.set_env(env::ENSO_BUILD_IDE, temp_dir_for_ide.path())?
|
||||
.try_applying(&pm_bundle)?
|
||||
.workspace(Workspaces::Enso)
|
||||
.run("watch")
|
||||
.args(script_args)
|
||||
.run_ok()
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Watcher {
|
||||
pub watch_environment: ContentEnvironment<TempDir, TempDir>,
|
||||
pub child_process: Child,
|
||||
}
|
||||
|
||||
impl ProcessWrapper for Watcher {
|
||||
fn inner(&mut self) -> &mut Child {
|
||||
&mut self.child_process
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -27,18 +27,13 @@ use octocrab::models::repos::Asset;
|
||||
pub mod backend;
|
||||
pub mod engine;
|
||||
pub mod gui;
|
||||
pub mod gui2;
|
||||
pub mod ide;
|
||||
pub mod ide2;
|
||||
pub mod project_manager;
|
||||
pub mod runtime;
|
||||
pub mod wasm;
|
||||
|
||||
pub use backend::Backend;
|
||||
pub use gui::Gui;
|
||||
pub use ide::Ide;
|
||||
pub use runtime::Runtime;
|
||||
pub use wasm::Wasm;
|
||||
|
||||
|
||||
|
||||
|
@ -1,28 +1,132 @@
|
||||
//! Build logic for the GUI project.
|
||||
//!
|
||||
//! The GUI is Vue.js-based and located under `app/gui2`.
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
use crate::ide::web::IdeDesktop;
|
||||
use crate::project::perhaps_watch;
|
||||
use crate::paths::generated::RepoRootAppGui2Dist;
|
||||
use crate::paths::generated::RepoRootDistGui2Assets;
|
||||
use crate::project::Context;
|
||||
use crate::project::IsArtifact;
|
||||
use crate::project::IsTarget;
|
||||
use crate::project::IsWatchable;
|
||||
use crate::project::IsWatcher;
|
||||
use crate::project::PerhapsWatched;
|
||||
use crate::project::Wasm;
|
||||
use crate::source::BuildSource;
|
||||
use crate::source::GetTargetJob;
|
||||
use crate::source::WatchTargetJob;
|
||||
use crate::source::WithDestination;
|
||||
use crate::BoxFuture;
|
||||
|
||||
use derivative::Derivative;
|
||||
use futures_util::future::try_join;
|
||||
use ide_ci::ok_ready_boxed;
|
||||
use ide_ci::programs::node::NpmCommand;
|
||||
use ide_ci::programs::Npm;
|
||||
|
||||
|
||||
|
||||
// ===============
|
||||
// === Scripts ===
|
||||
// ===============
|
||||
|
||||
/// The scripts defined in `package.json`.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, strum::AsRefStr)]
|
||||
#[strum(serialize_all = "kebab-case")]
|
||||
pub enum Scripts {
|
||||
Dev,
|
||||
Build,
|
||||
Preview,
|
||||
Test,
|
||||
#[strum(serialize = "test:unit")]
|
||||
TestUnit,
|
||||
#[strum(serialize = "test:e2e")]
|
||||
TestE2e,
|
||||
BuildOnly,
|
||||
TypeCheck,
|
||||
Lint,
|
||||
Format,
|
||||
BuildRustFfi,
|
||||
}
|
||||
|
||||
pub fn script(repo_root: impl AsRef<Path>, script: Scripts) -> Result<NpmCommand> {
|
||||
let mut ret = Npm.cmd()?;
|
||||
ret.current_dir(repo_root).workspace(crate::web::Workspace::EnsoGui2).run(script.as_ref());
|
||||
Ok(ret)
|
||||
}
|
||||
|
||||
pub fn dashboard_script(repo_root: impl AsRef<Path>, script: Scripts) -> Result<NpmCommand> {
|
||||
let mut ret = Npm.cmd()?;
|
||||
ret.current_dir(repo_root).workspace(crate::web::Workspace::EnsoDashboard).run(script.as_ref());
|
||||
Ok(ret)
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ================
|
||||
// === Commands ===
|
||||
// ================
|
||||
|
||||
/// Run steps that should be done along with the "lint"
|
||||
pub fn lint(repo_root: impl AsRef<Path>) -> BoxFuture<'static, Result> {
|
||||
install_and_run_script(Scripts::Lint, repo_root)
|
||||
}
|
||||
|
||||
pub fn tests(repo_root: impl AsRef<Path>) -> BoxFuture<'static, Result> {
|
||||
install_and_run_script(Scripts::Test, repo_root)
|
||||
}
|
||||
|
||||
pub fn dashboard_tests(repo_root: impl AsRef<Path>) -> BoxFuture<'static, Result> {
|
||||
install_and_run_dashboard_script(Scripts::Test, repo_root)
|
||||
}
|
||||
|
||||
/// Run unit tests.
|
||||
pub fn unit_tests(repo_root: impl AsRef<Path>) -> BoxFuture<'static, Result> {
|
||||
install_and_run_script(Scripts::TestUnit, repo_root)
|
||||
}
|
||||
|
||||
/// Run dashboard unit tests.
|
||||
pub fn dashboard_unit_tests(repo_root: impl AsRef<Path>) -> BoxFuture<'static, Result> {
|
||||
install_and_run_dashboard_script(Scripts::TestUnit, repo_root)
|
||||
}
|
||||
|
||||
/// Run E2E tests.
|
||||
pub fn e2e_tests(repo_root: impl AsRef<Path>) -> BoxFuture<'static, Result> {
|
||||
install_and_run_script(Scripts::TestE2e, repo_root)
|
||||
}
|
||||
|
||||
/// Run dashboard E2E tests.
|
||||
pub fn dashboard_e2e_tests(repo_root: impl AsRef<Path>) -> BoxFuture<'static, Result> {
|
||||
install_and_run_dashboard_script(Scripts::TestE2e, repo_root)
|
||||
}
|
||||
|
||||
pub fn watch(repo_root: impl AsRef<Path>) -> BoxFuture<'static, Result> {
|
||||
install_and_run_script(Scripts::Dev, repo_root)
|
||||
}
|
||||
|
||||
fn install_and_run_script(
|
||||
script: Scripts,
|
||||
repo_root: impl AsRef<Path>,
|
||||
) -> BoxFuture<'static, Result> {
|
||||
let repo_root = repo_root.as_ref().to_owned();
|
||||
async move {
|
||||
crate::web::install(&repo_root).await?;
|
||||
self::script(&repo_root, script)?.run_ok().await
|
||||
}
|
||||
.boxed()
|
||||
}
|
||||
|
||||
fn install_and_run_dashboard_script(
|
||||
script: Scripts,
|
||||
repo_root: impl AsRef<Path>,
|
||||
) -> BoxFuture<'static, Result> {
|
||||
let repo_root = repo_root.as_ref().to_owned();
|
||||
async move {
|
||||
crate::web::install(&repo_root).await?;
|
||||
dashboard_script(&repo_root, script)?.run_ok().await
|
||||
}
|
||||
.boxed()
|
||||
}
|
||||
|
||||
// ================
|
||||
// === Artifact ===
|
||||
// ================
|
||||
|
||||
/// The [artifact](IsArtifact) for the new GUI.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Deref)]
|
||||
pub struct Artifact(crate::paths::generated::RepoRootDistGui);
|
||||
pub struct Artifact(pub RepoRootAppGui2Dist);
|
||||
|
||||
impl AsRef<Path> for Artifact {
|
||||
fn as_ref(&self) -> &Path {
|
||||
@ -33,84 +137,27 @@ impl AsRef<Path> for Artifact {
|
||||
impl IsArtifact for Artifact {}
|
||||
|
||||
impl Artifact {
|
||||
pub fn new(gui_path: impl AsRef<Path>) -> Self {
|
||||
// TODO: sanity check
|
||||
Self(crate::paths::generated::RepoRootDistGui::new_root(gui_path.as_ref()))
|
||||
pub fn new(path: impl AsRef<Path>) -> Self {
|
||||
Artifact(RepoRootAppGui2Dist::new_root(path.as_ref()))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Derivative, derive_more::Deref)]
|
||||
#[derivative(Debug)]
|
||||
pub struct WatchInput {
|
||||
#[deref]
|
||||
pub wasm: <Wasm as IsWatchable>::WatchInput,
|
||||
}
|
||||
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(Debug)]
|
||||
pub struct BuildInput {
|
||||
#[derivative(Debug = "ignore")]
|
||||
pub wasm: GetTargetJob<Wasm>,
|
||||
/// BoxFuture<'static, Result<wasm::Artifact>>,
|
||||
#[derivative(Debug = "ignore")]
|
||||
pub build_info: BoxFuture<'static, Result<BuildInfo>>,
|
||||
}
|
||||
|
||||
/// Watcher of the GUI (including WASM watcher).
|
||||
#[derive(Debug)]
|
||||
pub struct Watcher {
|
||||
/// WASM watcher.
|
||||
pub wasm: PerhapsWatched<Wasm>,
|
||||
/// Watcher of the content project.
|
||||
pub web: crate::project::Watcher<Gui, crate::ide::web::Watcher>,
|
||||
}
|
||||
|
||||
impl AsRef<Artifact> for Watcher {
|
||||
fn as_ref(&self) -> &Artifact {
|
||||
&self.web.artifact
|
||||
}
|
||||
}
|
||||
|
||||
impl IsWatcher<Gui> for Watcher {
|
||||
fn wait_for_finish(&mut self) -> BoxFuture<Result> {
|
||||
let Self { web, wasm } = self;
|
||||
try_join(wasm.wait_ok(), IsWatcher::wait_for_finish(web)).void_ok().boxed()
|
||||
}
|
||||
}
|
||||
|
||||
/// Override the default value of `newDashboard` in `config.json` to `true`.
|
||||
///
|
||||
/// This is a temporary workaround. We want to enable the new dashboard by default in the CI-built
|
||||
/// IDE, but we don't want to enable it by default in the IDE built locally by developers.
|
||||
pub fn override_default_for_authentication(
|
||||
path: &crate::paths::generated::RepoRootAppIdeDesktopLibContentConfigSrcConfigJson,
|
||||
) -> Result {
|
||||
let json_path = ["groups", "featurePreview", "options", "newDashboard", "value"];
|
||||
let mut json = ide_ci::fs::read_json::<serde_json::Value>(path)?;
|
||||
let mut current =
|
||||
json.as_object_mut().ok_or_else(|| anyhow!("Failed to find object in {:?}", path))?;
|
||||
for key in &json_path[..json_path.len() - 1] {
|
||||
current = current
|
||||
.get_mut(*key)
|
||||
.with_context(|| format!("Failed to find {key:?} in {path:?}"))?
|
||||
.as_object_mut()
|
||||
.with_context(|| format!("Failed to find object at {key:?} in {path:?}"))?;
|
||||
}
|
||||
current.insert(json_path.last().unwrap().to_string(), serde_json::Value::Bool(true));
|
||||
ide_ci::fs::write_json(path, &json)?;
|
||||
Ok(())
|
||||
}
|
||||
// ==============
|
||||
// === Target ===
|
||||
// ==============
|
||||
|
||||
/// The [target](IsTarget) for the new GUI.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub struct Gui;
|
||||
|
||||
#[async_trait]
|
||||
impl IsTarget for Gui {
|
||||
type BuildInput = BuildInput;
|
||||
type BuildInput = ();
|
||||
type Artifact = Artifact;
|
||||
|
||||
fn artifact_name(&self) -> String {
|
||||
"gui".into()
|
||||
"gui".to_owned()
|
||||
}
|
||||
|
||||
fn adapt_artifact(self, path: impl AsRef<Path>) -> BoxFuture<'static, Result<Self::Artifact>> {
|
||||
@ -122,107 +169,51 @@ impl IsTarget for Gui {
|
||||
context: Context,
|
||||
job: WithDestination<Self::BuildInput>,
|
||||
) -> BoxFuture<'static, Result<Self::Artifact>> {
|
||||
let WithDestination { inner, destination } = job;
|
||||
let WithDestination { inner: _, destination } = job;
|
||||
async move {
|
||||
// TODO: [mwu]
|
||||
// This is a temporary workaround until https://github.com/enso-org/enso/issues/6662
|
||||
// is resolved.
|
||||
if ide_ci::actions::workflow::is_in_env() {
|
||||
let path = &context.repo_root.app.ide_desktop.lib.content_config.src.config_json;
|
||||
warn!("Overriding default for authentication in {}", path.display());
|
||||
override_default_for_authentication(path)?;
|
||||
}
|
||||
|
||||
let ide = ide_desktop_from_context(&context);
|
||||
crate::web::install(&ide.repo_root).await?;
|
||||
|
||||
let wasm = Wasm.get(context, inner.wasm);
|
||||
ide.build_content(wasm, &inner.build_info.await?, &destination).await?;
|
||||
Ok(Artifact::new(destination.clone()))
|
||||
let repo_root = &context.repo_root;
|
||||
crate::ide::web::google_font::install_with_css(
|
||||
&context.cache,
|
||||
&context.octocrab,
|
||||
"mplus1",
|
||||
"M PLUS 1",
|
||||
"/font-mplus1",
|
||||
&repo_root.app.gui_2.public.font_mplus_1,
|
||||
&repo_root.app.gui_2.src.assets.font_mplus_1_css,
|
||||
)
|
||||
.await?;
|
||||
crate::ide::web::dejavu_font::install_sans_mono_with_css(
|
||||
&context.cache,
|
||||
&context.octocrab,
|
||||
"/font-dejavu",
|
||||
&repo_root.app.gui_2.public.font_dejavu,
|
||||
&repo_root.app.gui_2.src.assets.font_dejavu_css,
|
||||
)
|
||||
.await?;
|
||||
crate::ide::web::enso_font::install_with_css(
|
||||
&context.cache,
|
||||
&context.octocrab,
|
||||
"/font-enso",
|
||||
&repo_root.app.gui_2.public.font_enso,
|
||||
&repo_root.app.gui_2.src.assets.font_enso_css,
|
||||
)
|
||||
.await?;
|
||||
crate::web::install(repo_root).await?;
|
||||
script(repo_root, Scripts::Build)?.run_ok().await?;
|
||||
ide_ci::fs::mirror_directory(
|
||||
&repo_root.app.gui_2.dist,
|
||||
&destination.join(RepoRootDistGui2Assets::segment_name()),
|
||||
)
|
||||
.await?;
|
||||
Ok(Artifact::new(destination))
|
||||
}
|
||||
.boxed()
|
||||
}
|
||||
}
|
||||
|
||||
impl IsWatchable for Gui {
|
||||
type Watcher = Watcher;
|
||||
type WatchInput = WatchInput;
|
||||
|
||||
// fn setup_watcher(
|
||||
// &self,
|
||||
// build_input: Self::BuildInput,
|
||||
// watch_input: Self::WatchInput,
|
||||
// output_path: impl AsRef<Path> + Send + Sync + 'static,
|
||||
// ) -> BoxFuture<'static, Result<Self::Watcher>> {
|
||||
// async move {
|
||||
// let BuildInput { build_info, repo_root, wasm } = build_input;
|
||||
// let ide = IdeDesktop::new(&repo_root.app.ide_desktop);
|
||||
// let watch_process = ide.watch_content(wasm, &build_info.await?).await?;
|
||||
// let artifact = Self::Artifact::from_existing(output_path).await?;
|
||||
// Ok(Self::Watcher { watch_process, artifact })
|
||||
// }
|
||||
// .boxed()
|
||||
// }
|
||||
|
||||
fn watch(
|
||||
&self,
|
||||
context: Context,
|
||||
job: WatchTargetJob<Self>,
|
||||
) -> BoxFuture<'static, Result<Self::Watcher>> {
|
||||
let WatchTargetJob {
|
||||
watch_input,
|
||||
build:
|
||||
WithDestination { inner: BuildSource { input, should_upload_artifact: _ }, destination },
|
||||
} = job;
|
||||
let BuildInput { build_info, wasm } = input;
|
||||
let perhaps_watched_wasm = perhaps_watch(Wasm, context.clone(), wasm, watch_input.wasm);
|
||||
let ide = ide_desktop_from_context(&context);
|
||||
async move {
|
||||
let perhaps_watched_wasm = perhaps_watched_wasm.await?;
|
||||
let wasm_artifacts = ok_ready_boxed(perhaps_watched_wasm.as_ref().clone());
|
||||
let watch_process = ide.watch_content(wasm_artifacts, &build_info.await?).await?;
|
||||
let artifact = Artifact::new(&destination);
|
||||
let web_watcher = crate::project::Watcher { watch_process, artifact };
|
||||
Ok(Self::Watcher { wasm: perhaps_watched_wasm, web: web_watcher })
|
||||
}
|
||||
.boxed()
|
||||
}
|
||||
}
|
||||
|
||||
impl Gui {
|
||||
/// Setup watcher for WASM.
|
||||
///
|
||||
/// If the WASM is static (e.g. comes from a release), it will be just referenced.
|
||||
pub fn perhaps_setup_wasm_watcher(
|
||||
&self,
|
||||
context: Context,
|
||||
job: WatchTargetJob<Self>,
|
||||
) -> GuiBuildWithWatchedWasm {
|
||||
let WatchTargetJob {
|
||||
watch_input,
|
||||
build:
|
||||
WithDestination { inner: BuildSource { input, should_upload_artifact: _ }, destination },
|
||||
} = job;
|
||||
let BuildInput { build_info, wasm } = input;
|
||||
let WatchInput { wasm: wasm_watch_input } = watch_input;
|
||||
let perhaps_watched_wasm = perhaps_watch(Wasm, context, wasm, wasm_watch_input);
|
||||
GuiBuildWithWatchedWasm { perhaps_watched_wasm, build_info, destination }
|
||||
}
|
||||
}
|
||||
|
||||
/// Watch job for the `Gui` target with already created watcher for the `Wasm` target.
|
||||
// Futures cannot be sensibly printed and there is little else of interest here.
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct GuiBuildWithWatchedWasm {
|
||||
/// WASM artifacts provider.
|
||||
pub perhaps_watched_wasm: BoxFuture<'static, Result<PerhapsWatched<Wasm>>>,
|
||||
/// Information for GUI build.
|
||||
pub build_info: BoxFuture<'static, Result<BuildInfo>>,
|
||||
/// Path to the directory where the GUI should be built. Might be ignored in some watching
|
||||
/// scenarios.
|
||||
pub destination: PathBuf,
|
||||
}
|
||||
|
||||
// =================
|
||||
// === BuildInfo ===
|
||||
// =================
|
||||
#[derive(Clone, Derivative, Serialize, Deserialize)]
|
||||
#[derivative(Debug)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
|
@ -1,211 +0,0 @@
|
||||
//! Build logic for the "new GUI" (gui2) project.
|
||||
//!
|
||||
//! The new GUI is Vue.js-based and located under `app/gui2`.
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
use crate::paths::generated::RepoRootAppGui2Dist;
|
||||
use crate::paths::generated::RepoRootDistGui2Assets;
|
||||
use crate::project::Context;
|
||||
use crate::project::IsArtifact;
|
||||
use crate::project::IsTarget;
|
||||
use crate::source::WithDestination;
|
||||
|
||||
use ide_ci::ok_ready_boxed;
|
||||
use ide_ci::programs::node::NpmCommand;
|
||||
use ide_ci::programs::Npm;
|
||||
|
||||
|
||||
|
||||
// ===============
|
||||
// === Scripts ===
|
||||
// ===============
|
||||
|
||||
/// The scripts defined in `package.json`.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, strum::AsRefStr)]
|
||||
#[strum(serialize_all = "kebab-case")]
|
||||
pub enum Scripts {
|
||||
Dev,
|
||||
Build,
|
||||
Preview,
|
||||
Test,
|
||||
#[strum(serialize = "test:unit")]
|
||||
TestUnit,
|
||||
#[strum(serialize = "test:e2e")]
|
||||
TestE2e,
|
||||
BuildOnly,
|
||||
TypeCheck,
|
||||
Lint,
|
||||
Format,
|
||||
BuildRustFfi,
|
||||
}
|
||||
|
||||
pub fn script(repo_root: impl AsRef<Path>, script: Scripts) -> Result<NpmCommand> {
|
||||
let mut ret = Npm.cmd()?;
|
||||
ret.current_dir(repo_root).workspace(crate::web::Workspace::EnsoGui2).run(script.as_ref());
|
||||
Ok(ret)
|
||||
}
|
||||
|
||||
pub fn dashboard_script(repo_root: impl AsRef<Path>, script: Scripts) -> Result<NpmCommand> {
|
||||
let mut ret = Npm.cmd()?;
|
||||
ret.current_dir(repo_root).workspace(crate::web::Workspace::EnsoDashboard).run(script.as_ref());
|
||||
Ok(ret)
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ================
|
||||
// === Commands ===
|
||||
// ================
|
||||
|
||||
/// Run steps that should be done along with the "lint"
|
||||
pub fn lint(repo_root: impl AsRef<Path>) -> BoxFuture<'static, Result> {
|
||||
install_and_run_script(Scripts::Lint, repo_root)
|
||||
}
|
||||
|
||||
pub fn tests(repo_root: impl AsRef<Path>) -> BoxFuture<'static, Result> {
|
||||
install_and_run_script(Scripts::Test, repo_root)
|
||||
}
|
||||
|
||||
pub fn dashboard_tests(repo_root: impl AsRef<Path>) -> BoxFuture<'static, Result> {
|
||||
install_and_run_dashboard_script(Scripts::Test, repo_root)
|
||||
}
|
||||
|
||||
/// Run unit tests.
|
||||
pub fn unit_tests(repo_root: impl AsRef<Path>) -> BoxFuture<'static, Result> {
|
||||
install_and_run_script(Scripts::TestUnit, repo_root)
|
||||
}
|
||||
|
||||
/// Run dashboard unit tests.
|
||||
pub fn dashboard_unit_tests(repo_root: impl AsRef<Path>) -> BoxFuture<'static, Result> {
|
||||
install_and_run_dashboard_script(Scripts::TestUnit, repo_root)
|
||||
}
|
||||
|
||||
/// Run E2E tests.
|
||||
pub fn e2e_tests(repo_root: impl AsRef<Path>) -> BoxFuture<'static, Result> {
|
||||
install_and_run_script(Scripts::TestE2e, repo_root)
|
||||
}
|
||||
|
||||
/// Run dashboard E2E tests.
|
||||
pub fn dashboard_e2e_tests(repo_root: impl AsRef<Path>) -> BoxFuture<'static, Result> {
|
||||
install_and_run_dashboard_script(Scripts::TestE2e, repo_root)
|
||||
}
|
||||
|
||||
pub fn watch(repo_root: impl AsRef<Path>) -> BoxFuture<'static, Result> {
|
||||
install_and_run_script(Scripts::Dev, repo_root)
|
||||
}
|
||||
|
||||
fn install_and_run_script(
|
||||
script: Scripts,
|
||||
repo_root: impl AsRef<Path>,
|
||||
) -> BoxFuture<'static, Result> {
|
||||
let repo_root = repo_root.as_ref().to_owned();
|
||||
async move {
|
||||
crate::web::install(&repo_root).await?;
|
||||
self::script(&repo_root, script)?.run_ok().await
|
||||
}
|
||||
.boxed()
|
||||
}
|
||||
|
||||
fn install_and_run_dashboard_script(
|
||||
script: Scripts,
|
||||
repo_root: impl AsRef<Path>,
|
||||
) -> BoxFuture<'static, Result> {
|
||||
let repo_root = repo_root.as_ref().to_owned();
|
||||
async move {
|
||||
crate::web::install(&repo_root).await?;
|
||||
dashboard_script(&repo_root, script)?.run_ok().await
|
||||
}
|
||||
.boxed()
|
||||
}
|
||||
|
||||
// ================
|
||||
// === Artifact ===
|
||||
// ================
|
||||
|
||||
/// The [artifact](IsArtifact) for the new GUI.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Deref)]
|
||||
pub struct Artifact(pub RepoRootAppGui2Dist);
|
||||
|
||||
impl AsRef<Path> for Artifact {
|
||||
fn as_ref(&self) -> &Path {
|
||||
self.0.as_path()
|
||||
}
|
||||
}
|
||||
|
||||
impl IsArtifact for Artifact {}
|
||||
|
||||
impl Artifact {
|
||||
pub fn new(path: impl AsRef<Path>) -> Self {
|
||||
Artifact(RepoRootAppGui2Dist::new_root(path.as_ref()))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ==============
|
||||
// === Target ===
|
||||
// ==============
|
||||
|
||||
/// The [target](IsTarget) for the new GUI.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub struct Gui2;
|
||||
|
||||
impl IsTarget for Gui2 {
|
||||
type BuildInput = ();
|
||||
type Artifact = Artifact;
|
||||
|
||||
fn artifact_name(&self) -> String {
|
||||
"gui2".to_owned()
|
||||
}
|
||||
|
||||
fn adapt_artifact(self, path: impl AsRef<Path>) -> BoxFuture<'static, Result<Self::Artifact>> {
|
||||
ok_ready_boxed(Artifact::new(path))
|
||||
}
|
||||
|
||||
fn build_internal(
|
||||
&self,
|
||||
context: Context,
|
||||
job: WithDestination<Self::BuildInput>,
|
||||
) -> BoxFuture<'static, Result<Self::Artifact>> {
|
||||
let WithDestination { inner: _, destination } = job;
|
||||
async move {
|
||||
let repo_root = &context.repo_root;
|
||||
crate::ide::web::google_font::install_with_css(
|
||||
&context.cache,
|
||||
&context.octocrab,
|
||||
"mplus1",
|
||||
"M PLUS 1",
|
||||
"/font-mplus1",
|
||||
&repo_root.app.gui_2.public.font_mplus_1,
|
||||
&repo_root.app.gui_2.src.assets.font_mplus_1_css,
|
||||
)
|
||||
.await?;
|
||||
crate::ide::web::dejavu_font::install_sans_mono_with_css(
|
||||
&context.cache,
|
||||
&context.octocrab,
|
||||
"/font-dejavu",
|
||||
&repo_root.app.gui_2.public.font_dejavu,
|
||||
&repo_root.app.gui_2.src.assets.font_dejavu_css,
|
||||
)
|
||||
.await?;
|
||||
crate::ide::web::enso_font::install_with_css(
|
||||
&context.cache,
|
||||
&context.octocrab,
|
||||
"/font-enso",
|
||||
&repo_root.app.gui_2.public.font_enso,
|
||||
&repo_root.app.gui_2.src.assets.font_enso_css,
|
||||
)
|
||||
.await?;
|
||||
crate::web::install(repo_root).await?;
|
||||
script(repo_root, Scripts::Build)?.run_ok().await?;
|
||||
ide_ci::fs::mirror_directory(
|
||||
&repo_root.app.gui_2.dist,
|
||||
&destination.join(RepoRootDistGui2Assets::segment_name()),
|
||||
)
|
||||
.await?;
|
||||
Ok(Artifact::new(destination))
|
||||
}
|
||||
.boxed()
|
||||
}
|
||||
}
|
@ -1,11 +1,8 @@
|
||||
#[allow(unused_imports)]
|
||||
use crate::prelude::*;
|
||||
|
||||
use crate::project::gui::ide_desktop_from_context;
|
||||
use crate::project::gui::GuiBuildWithWatchedWasm;
|
||||
use crate::project::Context;
|
||||
use crate::project::Gui;
|
||||
use crate::project::IsArtifact;
|
||||
use crate::source::WatchTargetJob;
|
||||
|
||||
use ide_ci::actions::artifacts::upload_compressed_directory;
|
||||
use ide_ci::actions::artifacts::upload_single_file;
|
||||
@ -102,13 +99,13 @@ impl Artifact {
|
||||
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(Debug)]
|
||||
pub struct BuildInput<GuiArtifact> {
|
||||
pub struct BuildInput {
|
||||
#[derivative(Debug(format_with = "std::fmt::Display::fmt"))]
|
||||
pub version: Version,
|
||||
#[derivative(Debug = "ignore")]
|
||||
pub project_manager: BoxFuture<'static, Result<crate::project::backend::Artifact>>,
|
||||
#[derivative(Debug = "ignore")]
|
||||
pub gui: BoxFuture<'static, Result<GuiArtifact>>,
|
||||
pub gui: BoxFuture<'static, Result<crate::project::gui::Artifact>>,
|
||||
pub electron_target: Option<String>,
|
||||
/// The name base used to generate CI run artifact names.
|
||||
pub artifact_name: String,
|
||||
@ -130,7 +127,7 @@ impl Ide {
|
||||
pub fn build(
|
||||
&self,
|
||||
context: &Context,
|
||||
input: BuildInput<impl IsArtifact>,
|
||||
input: BuildInput,
|
||||
output_path: impl AsRef<Path> + Send + Sync + 'static,
|
||||
) -> BoxFuture<'static, Result<Artifact>> {
|
||||
let BuildInput { version, project_manager, gui, electron_target, artifact_name: _ } = input;
|
||||
@ -146,25 +143,4 @@ impl Ide {
|
||||
}
|
||||
.boxed()
|
||||
}
|
||||
|
||||
/// Setup watch for IDE.
|
||||
///
|
||||
/// This includes both WASM watcher and watcher for the web parts.
|
||||
pub fn watch(
|
||||
&self,
|
||||
context: &Context,
|
||||
gui_watch_job: WatchTargetJob<Gui>,
|
||||
get_project_manager: BoxFuture<'static, Result<crate::project::backend::Artifact>>,
|
||||
ide_options: Vec<String>,
|
||||
) -> BoxFuture<'static, Result> {
|
||||
let ide_desktop = ide_desktop_from_context(context);
|
||||
let GuiBuildWithWatchedWasm { perhaps_watched_wasm, build_info, destination: _ } =
|
||||
Gui.perhaps_setup_wasm_watcher(context.clone(), gui_watch_job);
|
||||
async move {
|
||||
ide_desktop
|
||||
.watch(perhaps_watched_wasm, build_info, get_project_manager, ide_options)
|
||||
.await
|
||||
}
|
||||
.boxed()
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +0,0 @@
|
||||
#[allow(unused_imports)]
|
||||
use crate::prelude::*;
|
||||
|
||||
|
||||
// ==============
|
||||
// === Export ===
|
||||
// ==============
|
||||
|
||||
pub use crate::project::ide::Artifact;
|
@ -2,30 +2,8 @@
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
use crate::paths::generated::RepoRootDistWasm;
|
||||
use crate::project::Context;
|
||||
use crate::project::IsArtifact;
|
||||
use crate::project::IsTarget;
|
||||
use crate::project::IsWatchable;
|
||||
use crate::source::BuildSource;
|
||||
use crate::source::WatchTargetJob;
|
||||
use crate::source::WithDestination;
|
||||
|
||||
use derivative::Derivative;
|
||||
use ide_ci::cache;
|
||||
use ide_ci::fs::compressed_size;
|
||||
use ide_ci::fs::copy_file_if_different;
|
||||
use ide_ci::goodies::shader_tools::ShaderTools;
|
||||
use ide_ci::programs::cargo;
|
||||
use ide_ci::programs::wasm_opt;
|
||||
use ide_ci::programs::wasm_opt::WasmOpt;
|
||||
use ide_ci::programs::wasm_pack;
|
||||
use ide_ci::programs::Cargo;
|
||||
use ide_ci::programs::WasmPack;
|
||||
use semver::VersionReq;
|
||||
use std::time::Duration;
|
||||
use tempfile::tempdir;
|
||||
use tokio::process::Child;
|
||||
|
||||
|
||||
// ==============
|
||||
@ -37,19 +15,6 @@ pub mod test;
|
||||
|
||||
|
||||
|
||||
pub const BINARYEN_VERSION_TO_INSTALL: u32 = 108;
|
||||
|
||||
pub const DEFAULT_INTEGRATION_TESTS_WASM_TIMEOUT: Duration = Duration::from_secs(300);
|
||||
|
||||
pub const INTEGRATION_TESTS_CRATE_NAME: &str = "enso-integration-test";
|
||||
|
||||
pub const OUTPUT_NAME: &str = "ide";
|
||||
|
||||
/// Name of the artifact that will be uploaded as part of CI run.
|
||||
pub const WASM_ARTIFACT_NAME: &str = "gui_wasm";
|
||||
|
||||
pub const DEFAULT_TARGET_CRATE: &str = "app/gui";
|
||||
|
||||
#[derive(
|
||||
clap::ArgEnum,
|
||||
Clone,
|
||||
@ -91,497 +56,37 @@ pub enum LogLevel {
|
||||
Trace,
|
||||
}
|
||||
|
||||
#[derive(clap::ArgEnum, Clone, Copy, Debug, PartialEq, Eq, strum::Display, strum::AsRefStr)]
|
||||
#[strum(serialize_all = "kebab-case")]
|
||||
pub enum Profile {
|
||||
Dev,
|
||||
Profile,
|
||||
Release,
|
||||
// Production,
|
||||
}
|
||||
|
||||
impl From<Profile> for wasm_pack::Profile {
|
||||
fn from(profile: Profile) -> Self {
|
||||
match profile {
|
||||
Profile::Dev => Self::Dev,
|
||||
Profile::Profile => Self::Profile,
|
||||
Profile::Release => Self::Release,
|
||||
// Profile::Production => Self::Release,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Profile {
|
||||
pub fn should_check_size(self) -> bool {
|
||||
match self {
|
||||
Profile::Dev => false,
|
||||
Profile::Profile => false,
|
||||
Profile::Release => true,
|
||||
// Profile::Production => true,
|
||||
pub async fn test(repo_root: PathBuf, wasm: &[test::Browser], native: bool) -> Result {
|
||||
async fn maybe_run<Fut: Future<Output = Result>>(
|
||||
name: &str,
|
||||
enabled: bool,
|
||||
f: impl (FnOnce() -> Fut),
|
||||
) -> Result {
|
||||
if enabled {
|
||||
info!("Will run {name} tests.");
|
||||
f().await.context(format!("Running {name} tests."))
|
||||
} else {
|
||||
info!("Skipping {name} tests.");
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn extra_rust_options(self) -> Vec<String> {
|
||||
match self {
|
||||
// Profile::Production => ["-Clto=fat", "-Ccodegen-units=1", "-Cincremental=false"]
|
||||
// .into_iter()
|
||||
// .map(ToString::to_string)
|
||||
// .collect(),
|
||||
Profile::Dev | Profile::Profile | Profile::Release => vec![],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn optimization_level(self) -> wasm_opt::OptimizationLevel {
|
||||
match self {
|
||||
Profile::Dev => wasm_opt::OptimizationLevel::O0,
|
||||
Profile::Profile => wasm_opt::OptimizationLevel::O,
|
||||
Profile::Release => wasm_opt::OptimizationLevel::O3,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Derivative)]
|
||||
#[derivative(Debug)]
|
||||
pub struct BuildInput {
|
||||
/// Path to the crate to be compiled to WAM. Relative to the repository root.
|
||||
pub crate_path: PathBuf,
|
||||
pub wasm_opt_options: Vec<String>,
|
||||
pub skip_wasm_opt: bool,
|
||||
pub extra_cargo_options: Vec<String>,
|
||||
pub profile: Profile,
|
||||
pub profiling_level: Option<ProfilingLevel>,
|
||||
pub log_level: LogLevel,
|
||||
pub uncollapsed_log_level: LogLevel,
|
||||
pub wasm_size_limit: Option<byte_unit::Byte>,
|
||||
pub system_shader_tools: bool,
|
||||
}
|
||||
|
||||
impl BuildInput {
|
||||
pub async fn perhaps_check_size(&self, wasm_path: impl AsRef<Path>) -> Result {
|
||||
let compressed_size = compressed_size(&wasm_path).await?.get_appropriate_unit(true);
|
||||
info!("Compressed size of {} is {}.", wasm_path.as_ref().display(), compressed_size);
|
||||
if let Some(wasm_size_limit) = self.wasm_size_limit {
|
||||
let wasm_size_limit = wasm_size_limit.get_appropriate_unit(true);
|
||||
if !self.profile.should_check_size() {
|
||||
warn!("Skipping size check because profile is '{}'.", self.profile,);
|
||||
} else if self.profiling_level.unwrap_or_default() != ProfilingLevel::Objective {
|
||||
// TODO? additional leeway as sanity check
|
||||
warn!(
|
||||
"Skipping size check because profiling level is {:?} rather than {}.",
|
||||
self.profiling_level,
|
||||
ProfilingLevel::Objective
|
||||
);
|
||||
} else {
|
||||
ensure!(
|
||||
compressed_size < wasm_size_limit,
|
||||
"Compressed WASM size ~{} ({} bytes) exceeds the limit of {} ({} bytes).",
|
||||
compressed_size,
|
||||
compressed_size.get_byte(),
|
||||
wasm_size_limit,
|
||||
wasm_size_limit.get_byte(),
|
||||
)
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub struct Wasm;
|
||||
|
||||
#[async_trait]
|
||||
impl IsTarget for Wasm {
|
||||
type BuildInput = BuildInput;
|
||||
type Artifact = Artifact;
|
||||
|
||||
fn artifact_name(&self) -> String {
|
||||
WASM_ARTIFACT_NAME.into()
|
||||
}
|
||||
|
||||
fn adapt_artifact(self, path: impl AsRef<Path>) -> BoxFuture<'static, Result<Self::Artifact>> {
|
||||
ready(Ok(Artifact::new(path.as_ref()))).boxed()
|
||||
}
|
||||
|
||||
fn build_internal(
|
||||
&self,
|
||||
context: Context,
|
||||
job: WithDestination<Self::BuildInput>,
|
||||
) -> BoxFuture<'static, Result<Self::Artifact>> {
|
||||
let Context { octocrab: _, cache, repo_root } = context;
|
||||
let WithDestination { inner, destination } = job;
|
||||
let span = info_span!("Building WASM.",
|
||||
repo = %repo_root.display(),
|
||||
crate = %inner.crate_path.display(),
|
||||
cargo_opts = ?inner.extra_cargo_options
|
||||
);
|
||||
async move {
|
||||
// Old wasm-pack does not pass trailing `build` command arguments to the Cargo.
|
||||
// We want to be able to pass --profile this way.
|
||||
WasmPack.require_present_that(VersionReq::parse(">=0.10.1")?).await?;
|
||||
|
||||
let BuildInput {
|
||||
crate_path,
|
||||
wasm_opt_options,
|
||||
skip_wasm_opt,
|
||||
extra_cargo_options,
|
||||
profile,
|
||||
profiling_level,
|
||||
log_level,
|
||||
uncollapsed_log_level,
|
||||
wasm_size_limit: _wasm_size_limit,
|
||||
system_shader_tools,
|
||||
} = &inner;
|
||||
|
||||
// NOTE: We cannot trust locally installed version of shader tools to be correct.
|
||||
// Those binaries have no reliable versioning, and existing common distributions (e.g.
|
||||
// Vulkan SDK) contain old builds with bugs that impact our shaders. By default, we have
|
||||
// to force usage of our own distribution built on our CI.
|
||||
if *system_shader_tools {
|
||||
ShaderTools.install_if_missing(&cache).await?;
|
||||
} else {
|
||||
ShaderTools.install(&cache).await?;
|
||||
}
|
||||
|
||||
cache::goodie::binaryen::Binaryen { version: BINARYEN_VERSION_TO_INSTALL }
|
||||
.install_if_missing(&cache)
|
||||
.await?;
|
||||
|
||||
info!("Building wasm.");
|
||||
let temp_dir = tempdir()?;
|
||||
let temp_dist = RepoRootDistWasm::new_root(temp_dir.path());
|
||||
crate::web::install(&repo_root).await?;
|
||||
enso_pack::build(
|
||||
enso_pack::WasmPackOutputs {
|
||||
out_dir: temp_dist.path.clone(),
|
||||
out_name: OUTPUT_NAME.into(),
|
||||
},
|
||||
|args| {
|
||||
let mut command = WasmPack.cmd()?;
|
||||
command
|
||||
.current_dir(&repo_root)
|
||||
.kill_on_drop(true)
|
||||
.env_remove(ide_ci::programs::rustup::env::RUSTUP_TOOLCHAIN.name())
|
||||
.build()
|
||||
.arg(wasm_pack::Profile::from(*profile))
|
||||
.target(wasm_pack::Target::Web)
|
||||
.output_directory(args.out_dir)
|
||||
.output_name(args.out_name)
|
||||
.arg(crate_path)
|
||||
.arg("--")
|
||||
.apply(&cargo::Color::Always)
|
||||
.args(extra_cargo_options);
|
||||
|
||||
if let Some(profiling_level) = profiling_level {
|
||||
command.set_env(env::ENSO_MAX_PROFILING_LEVEL, &profiling_level)?;
|
||||
}
|
||||
command.set_env(env::ENSO_MAX_LOG_LEVEL, &log_level)?;
|
||||
command.set_env(env::ENSO_MAX_UNCOLLAPSED_LOG_LEVEL, &uncollapsed_log_level)?;
|
||||
Ok(command)
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
|
||||
Self::finalize_wasm(wasm_opt_options, *skip_wasm_opt, *profile, &temp_dist).await?;
|
||||
|
||||
ide_ci::fs::create_dir_if_missing(&destination)?;
|
||||
let ret = RepoRootDistWasm::new_root(&destination);
|
||||
ide_ci::fs::copy(&temp_dist, &ret)?;
|
||||
inner.perhaps_check_size(&ret.pkg_opt_wasm).await?;
|
||||
Ok(Artifact(ret))
|
||||
}
|
||||
.instrument(span)
|
||||
.boxed()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Clone, Derivative)]
|
||||
#[derivative(Debug)]
|
||||
pub struct WatchInput {
|
||||
pub cargo_watch_options: Vec<String>,
|
||||
}
|
||||
|
||||
impl IsWatchable for Wasm {
|
||||
type Watcher = crate::project::Watcher<Self, Child>;
|
||||
type WatchInput = WatchInput;
|
||||
|
||||
fn watch(
|
||||
&self,
|
||||
context: Context,
|
||||
job: WatchTargetJob<Self>,
|
||||
) -> BoxFuture<'static, Result<Self::Watcher>> {
|
||||
let span = debug_span!("Watching WASM.", ?job).entered();
|
||||
|
||||
// The esbuild watcher must succeed in its first build, or it will prematurely exit.
|
||||
// See the issue: https://github.com/evanw/esbuild/issues/1063
|
||||
//
|
||||
// Because of this, we run first build of wasm manually, rather through cargo-watch.
|
||||
// After it is completed, the cargo-watch gets spawned and this method yields the watcher.
|
||||
// This forces esbuild watcher (whose setup requires the watcher artifacts) to wait until
|
||||
// all wasm build outputs are in place, so the build won't crash.
|
||||
//
|
||||
// In general, much neater workaround should be possible, if we stop relying on cargo-watch
|
||||
// and do the WASM watch directly in the build script.
|
||||
let first_build_job = self
|
||||
.build(context.clone(), job.build.clone())
|
||||
.instrument(debug_span!("Initial single build of WASM before setting up cargo-watch."));
|
||||
|
||||
async move {
|
||||
// Make sure that `npm install` was run, so we can spawned process to skip it.
|
||||
// This prevents issues with multiple `npm install` invocations running in parallel.
|
||||
let npm_install = crate::web::install(&context.repo_root);
|
||||
let (first_build_output, npm_install) =
|
||||
futures::future::join(first_build_job, npm_install).await;
|
||||
npm_install?;
|
||||
let first_build_output = first_build_output?;
|
||||
|
||||
let WatchTargetJob {
|
||||
watch_input: WatchInput { cargo_watch_options: cargo_watch_flags },
|
||||
build:
|
||||
WithDestination {
|
||||
inner: BuildSource { input, should_upload_artifact: _ },
|
||||
destination,
|
||||
},
|
||||
} = job;
|
||||
let BuildInput {
|
||||
crate_path,
|
||||
wasm_opt_options,
|
||||
skip_wasm_opt,
|
||||
extra_cargo_options,
|
||||
profile,
|
||||
profiling_level,
|
||||
log_level,
|
||||
uncollapsed_log_level,
|
||||
wasm_size_limit,
|
||||
system_shader_tools: _,
|
||||
} = input;
|
||||
|
||||
|
||||
let current_exe = std::env::current_exe()?;
|
||||
// cargo-watch apparently cannot handle verbatim path prefix. We remove it and hope for
|
||||
// the best.
|
||||
let current_exe = current_exe.without_verbatim_prefix();
|
||||
|
||||
|
||||
let mut watch_cmd = Cargo.cmd()?;
|
||||
|
||||
let (watch_cmd_name, mut watch_cmd_opts) = match std::env::var("USE_CARGO_WATCH_PLUS") {
|
||||
Ok(_) => ("watch-plus", vec!["--why"]),
|
||||
Err(_) => ("watch", vec![]),
|
||||
};
|
||||
watch_cmd_opts.push("--ignore");
|
||||
watch_cmd_opts.push("README.md");
|
||||
|
||||
watch_cmd
|
||||
.kill_on_drop(true)
|
||||
.current_dir(&context.repo_root)
|
||||
.arg(watch_cmd_name)
|
||||
.args(watch_cmd_opts)
|
||||
.args(cargo_watch_flags)
|
||||
.arg("--");
|
||||
|
||||
// === Build Script top-level options ===
|
||||
watch_cmd
|
||||
// TODO [mwu]
|
||||
// This is not nice, as this module should not be aware of the CLI
|
||||
// parsing/generation. Rather than using `cargo watch` this should
|
||||
// be implemented directly in Rust.
|
||||
.arg(current_exe)
|
||||
.arg("--skip-version-check") // We already checked in the parent process.
|
||||
.args(["--cache-path", context.cache.path().as_str()])
|
||||
.args(["--repo-path", context.repo_root.as_str()])
|
||||
.arg("--skip-npm-install");
|
||||
|
||||
// === Build Script command and its options ===
|
||||
watch_cmd
|
||||
.arg("wasm")
|
||||
.arg("build")
|
||||
.args(["--crate-path", crate_path.as_str()])
|
||||
.args(["--wasm-output-path", destination.as_str()])
|
||||
.args(["--wasm-profile", profile.as_ref()]);
|
||||
if let Some(profiling_level) = profiling_level {
|
||||
watch_cmd.args(["--profiling-level", profiling_level.to_string().as_str()]);
|
||||
}
|
||||
watch_cmd.args(["--wasm-log-level", log_level.to_string().as_str()]);
|
||||
watch_cmd
|
||||
.args(["--wasm-uncollapsed-log-level", uncollapsed_log_level.to_string().as_str()]);
|
||||
for wasm_opt_option in wasm_opt_options {
|
||||
watch_cmd.args(["--wasm-opt-option", &wasm_opt_option]);
|
||||
}
|
||||
if skip_wasm_opt {
|
||||
watch_cmd.args(["--skip-wasm-opt"]);
|
||||
}
|
||||
if let Some(wasm_size_limit) = wasm_size_limit {
|
||||
watch_cmd.args(["--wasm-size-limit", wasm_size_limit.to_string().as_str()]);
|
||||
} else {
|
||||
watch_cmd.args(["--wasm-size-limit", "0"]);
|
||||
}
|
||||
|
||||
// === cargo-watch options ===
|
||||
watch_cmd.arg("--").args(extra_cargo_options);
|
||||
|
||||
let watch_process = watch_cmd.spawn_intercepting()?;
|
||||
let artifact = Artifact(RepoRootDistWasm::new_root(&destination));
|
||||
ensure!(
|
||||
artifact == first_build_output,
|
||||
"First build output does not match general watch build output. First build output: \
|
||||
{first_build_output:?}, general watch build output: {artifact:?}",
|
||||
);
|
||||
Ok(Self::Watcher { artifact, watch_process })
|
||||
}
|
||||
.instrument(span.exit())
|
||||
.boxed()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Clone, Debug, Display, PartialEq, Eq)]
|
||||
pub struct Artifact(pub RepoRootDistWasm);
|
||||
|
||||
impl Artifact {
|
||||
pub fn new(path: impl Into<PathBuf>) -> Self {
|
||||
Self(RepoRootDistWasm::new_root(path))
|
||||
}
|
||||
|
||||
/// Files that should be shipped in the Gui bundle.
|
||||
pub fn files_to_ship(&self) -> Vec<&Path> {
|
||||
// We explicitly deconstruct object, so when new fields are added, we will be forced to
|
||||
// consider whether they should be shipped or not.
|
||||
let RepoRootDistWasm {
|
||||
path: _,
|
||||
dynamic_assets,
|
||||
pkg_js,
|
||||
pkg_js_map,
|
||||
pkg_wasm: _,
|
||||
pkg_opt_wasm,
|
||||
} = &self.0;
|
||||
vec![
|
||||
dynamic_assets.as_path(),
|
||||
pkg_js.as_path(),
|
||||
pkg_js_map.as_path(),
|
||||
pkg_opt_wasm.as_path(),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<Path> for Artifact {
|
||||
fn as_ref(&self) -> &Path {
|
||||
self.0.as_path()
|
||||
}
|
||||
}
|
||||
|
||||
impl IsArtifact for Artifact {}
|
||||
|
||||
impl Wasm {
|
||||
pub async fn check(&self) -> Result {
|
||||
maybe_run("native", native, async || {
|
||||
Cargo
|
||||
.cmd()?
|
||||
.apply(&cargo::Command::Check)
|
||||
.current_dir(repo_root.clone())
|
||||
.apply(&cargo::Command::Test)
|
||||
.apply(&cargo::Options::Workspace)
|
||||
.apply(&cargo::Options::Package(INTEGRATION_TESTS_CRATE_NAME.into()))
|
||||
.apply(&cargo::Options::AllTargets)
|
||||
// Color needs to be passed to tests themselves separately.
|
||||
// See: https://github.com/rust-lang/cargo/issues/1983
|
||||
.arg("--")
|
||||
.apply(&cargo::Color::Always)
|
||||
.run_ok()
|
||||
.await
|
||||
}
|
||||
})
|
||||
.await?;
|
||||
|
||||
pub async fn test(&self, repo_root: PathBuf, wasm: &[test::Browser], native: bool) -> Result {
|
||||
async fn maybe_run<Fut: Future<Output = Result>>(
|
||||
name: &str,
|
||||
enabled: bool,
|
||||
f: impl (FnOnce() -> Fut),
|
||||
) -> Result {
|
||||
if enabled {
|
||||
info!("Will run {name} tests.");
|
||||
f().await.context(format!("Running {name} tests."))
|
||||
} else {
|
||||
info!("Skipping {name} tests.");
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
maybe_run("native", native, async || {
|
||||
Cargo
|
||||
.cmd()?
|
||||
.current_dir(repo_root.clone())
|
||||
.apply(&cargo::Command::Test)
|
||||
.apply(&cargo::Options::Workspace)
|
||||
// Color needs to be passed to tests themselves separately.
|
||||
// See: https://github.com/rust-lang/cargo/issues/1983
|
||||
.arg("--")
|
||||
.apply(&cargo::Color::Always)
|
||||
.run_ok()
|
||||
.await
|
||||
})
|
||||
.await?;
|
||||
|
||||
maybe_run("wasm", !wasm.is_empty(), || test::test_all(repo_root.clone(), wasm)).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn integration_test(
|
||||
&self,
|
||||
source_root: PathBuf,
|
||||
_project_manager: Option<Child>,
|
||||
headless: bool,
|
||||
additional_options: Vec<String>,
|
||||
wasm_timeout: Option<Duration>,
|
||||
) -> Result {
|
||||
info!("Running Rust WASM test suite.");
|
||||
use wasm_pack::TestFlags::*;
|
||||
WasmPack
|
||||
.cmd()?
|
||||
.current_dir(source_root)
|
||||
.set_env_opt(
|
||||
env::WASM_BINDGEN_TEST_TIMEOUT,
|
||||
wasm_timeout.map(|d| d.as_secs()).as_ref(),
|
||||
)?
|
||||
.test()
|
||||
.apply_opt(headless.then_some(&Headless))
|
||||
.apply(&test::BROWSER_FOR_WASM_TESTS)
|
||||
.arg("integration-test")
|
||||
.arg("--profile=integration-test")
|
||||
.args(additional_options)
|
||||
.run_ok()
|
||||
.await
|
||||
// PM will be automatically killed by dropping the handle.
|
||||
}
|
||||
|
||||
/// Process "raw" WASM (as compiled) by optionally invoking wasm-opt.
|
||||
pub async fn finalize_wasm(
|
||||
wasm_opt_options: &[String],
|
||||
skip_wasm_opt: bool,
|
||||
profile: Profile,
|
||||
temp_dist: &RepoRootDistWasm,
|
||||
) -> Result {
|
||||
let should_call_wasm_opt = {
|
||||
if profile == Profile::Dev {
|
||||
debug!("Skipping wasm-opt invocation, as it is not part of profile {profile}.");
|
||||
false
|
||||
} else if skip_wasm_opt {
|
||||
debug!("Skipping wasm-opt invocation, as it was explicitly requested.");
|
||||
false
|
||||
} else {
|
||||
true
|
||||
}
|
||||
};
|
||||
|
||||
if should_call_wasm_opt {
|
||||
let mut wasm_opt_command = WasmOpt.cmd()?;
|
||||
let has_custom_opt_level = wasm_opt_options.iter().any(|opt| {
|
||||
wasm_opt::OptimizationLevel::from_str(opt.trim_start_matches('-')).is_ok()
|
||||
});
|
||||
if !has_custom_opt_level {
|
||||
wasm_opt_command.apply(&profile.optimization_level());
|
||||
}
|
||||
wasm_opt_command
|
||||
.args(wasm_opt_options)
|
||||
.arg(&temp_dist.pkg_wasm)
|
||||
.apply(&wasm_opt::Output(&temp_dist.pkg_opt_wasm))
|
||||
.run_ok()
|
||||
.await?;
|
||||
} else {
|
||||
copy_file_if_different(&temp_dist.pkg_wasm, &temp_dist.pkg_opt_wasm)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
maybe_run("wasm", !wasm.is_empty(), || test::test_all(repo_root.clone(), wasm)).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -145,11 +145,11 @@ pub async fn test_all(repo_root: PathBuf, browsers: &[Browser]) -> Result {
|
||||
for member in all_members {
|
||||
let member_str = member.to_string_lossy();
|
||||
if blacklisted(&member) {
|
||||
info!("Skipping blacklisted crate {member_str}");
|
||||
debug!("Skipping blacklisted crate: {member_str}");
|
||||
} else if is_proc_macro_crate(&member) {
|
||||
info!("Skipping proc-macro crate {member_str}");
|
||||
debug!("Skipping proc-macro crate: {member_str}");
|
||||
} else if has_wasm_tests(&member) {
|
||||
info!("Running tests for {member_str}");
|
||||
info!("Running tests for: {member_str}");
|
||||
WasmPack
|
||||
.cmd()?
|
||||
.current_dir(&repo_root)
|
||||
@ -169,7 +169,7 @@ pub async fn test_all(repo_root: PathBuf, browsers: &[Browser]) -> Result {
|
||||
.run_ok()
|
||||
.await?;
|
||||
} else {
|
||||
println!("No wasm tests in {member_str}");
|
||||
debug!("Skipping crate with no wasm tests: {member_str}");
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
@ -9,11 +9,6 @@ use crate::paths::generated;
|
||||
use crate::paths::TargetTriple;
|
||||
use crate::paths::EDITION_FILE_ARTIFACT_NAME;
|
||||
use crate::project;
|
||||
use crate::project::gui;
|
||||
use crate::project::Gui;
|
||||
use crate::project::IsTarget;
|
||||
use crate::source::ExternalSource;
|
||||
use crate::source::FetchTargetJob;
|
||||
use crate::version;
|
||||
use crate::version::promote::Designation;
|
||||
use crate::version::Versions;
|
||||
@ -242,50 +237,6 @@ pub async fn deploy_to_ecr(context: &BuildContext, repository: String) -> Result
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Download the GUI artifacts from the current CI run artifacts.
|
||||
pub async fn get_gui_from_current_ci_run(
|
||||
context: &BuildContext,
|
||||
out_dir: impl Into<PathBuf>,
|
||||
) -> Result<gui::Artifact> {
|
||||
let target = Gui;
|
||||
let source = ExternalSource::new_ongoing_ci_run(target.artifact_name());
|
||||
let fetch_job = FetchTargetJob { destination: out_dir.into(), inner: source };
|
||||
target.get_external(context.inner.clone(), fetch_job).await
|
||||
}
|
||||
|
||||
/// Upload GUI to the cloud (AWS S3).
|
||||
pub async fn upload_gui_to_cloud_good(context: &BuildContext) -> Result {
|
||||
let temp = tempdir()?;
|
||||
let gui = get_gui_from_current_ci_run(context, temp.path()).await?;
|
||||
upload_gui_to_cloud(&gui.assets, &context.triple.versions.version).await?;
|
||||
notify_cloud_about_gui(&context.triple.versions.version).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Upload GUI to the cloud (AWS S3).
|
||||
pub async fn upload_gui_to_cloud(
|
||||
assets: &crate::paths::generated::RepoRootDistGuiAssets,
|
||||
version: &Version,
|
||||
) -> Result {
|
||||
let bucket = crate::aws::s3::gui::context(version).await?;
|
||||
|
||||
// Some file we upload as-is, some gzipped. This seems somewhat arbitrary now.
|
||||
let files_to_upload = [
|
||||
assets.pkg_opt_wasm.as_path(),
|
||||
assets.style_css.as_path(),
|
||||
assets.dynamic_assets.as_path(),
|
||||
];
|
||||
let files_to_upload_gzipped = [assets.entrypoint_js.as_path(), assets.pkg_js.as_path()];
|
||||
|
||||
for file in files_to_upload.iter() {
|
||||
bucket.put_item(file).await?;
|
||||
}
|
||||
|
||||
put_files_gzipping(&bucket, &files_to_upload_gzipped).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Packs given files with `gzip` and uploads them to the S3 bucket.
|
||||
///
|
||||
/// The files are uploaded with the same name, but with `.gz` extension.
|
||||
@ -347,19 +298,6 @@ pub async fn promote_release(context: &BuildContext, version_designation: Design
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[tokio::test]
|
||||
#[ignore]
|
||||
async fn upload_gui() -> Result {
|
||||
setup_logging()?;
|
||||
let assets = crate::paths::generated::RepoRootDistGuiAssets::new_root(
|
||||
r"H:\NBO\enso4\dist\gui\assets",
|
||||
);
|
||||
let version = "2023.1.1-dev.cloud.test".parse2()?;
|
||||
upload_gui_to_cloud(&assets, &version).await?;
|
||||
notify_cloud_about_gui(&version).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[ignore]
|
||||
async fn notify_cloud() -> Result {
|
||||
|
@ -20,9 +20,7 @@ pub mod backend;
|
||||
pub mod engine;
|
||||
pub mod git_clean;
|
||||
pub mod gui;
|
||||
pub mod gui2;
|
||||
pub mod ide;
|
||||
pub mod ide2;
|
||||
pub mod java_gen;
|
||||
pub mod project_manager;
|
||||
pub mod release;
|
||||
@ -114,22 +112,16 @@ macro_rules! source_args_hlp {
|
||||
pub enum Target {
|
||||
/// Build/Test the Rust part of the GUI.
|
||||
Wasm(wasm::Target),
|
||||
/// Build/Run the legacy Rust-based GUI that consists of WASM and JS parts.
|
||||
/// Build/Run the Vue-based GUI.
|
||||
#[clap(alias = "gui2")]
|
||||
Gui(gui::Target),
|
||||
/// Build/Run the new, Vue-based GUI.
|
||||
Gui2(gui2::Target),
|
||||
/// Enso Engine Runtime.
|
||||
Runtime(runtime::Target),
|
||||
// /// Project Manager package (just the binary, no Engine)
|
||||
// ProjectManager(project_manager::Target),
|
||||
// /// Enso Engine distribution.
|
||||
// Engine(engine::Target),
|
||||
/// Build/Get Project Manager bundle (includes Enso Engine with GraalVM Runtime).
|
||||
Backend(backend::Target),
|
||||
/// Build/Run/Test IDE bundle (includes Rust-based GUI and Project Manager).
|
||||
Ide(ide::Target),
|
||||
/// Build/Run/Test IDE bundle (includes Vue-based GUI and Project Manager).
|
||||
Ide2(ide2::Target),
|
||||
#[clap(alias = "ide2")]
|
||||
Ide(ide::Target),
|
||||
/// Clean the repository. Keeps the IntelliJ's .idea directory intact. WARNING: This removes
|
||||
/// files that are not under version control in the repository subtree.
|
||||
GitClean(git_clean::Options),
|
||||
|
@ -2,34 +2,18 @@ use enso_build::prelude::*;
|
||||
|
||||
use crate::arg::BuildJob;
|
||||
use crate::arg::Source;
|
||||
use crate::arg::WatchJob;
|
||||
use crate::source_args_hlp;
|
||||
use crate::IsWatchableSource;
|
||||
|
||||
use clap::Args;
|
||||
use clap::Subcommand;
|
||||
use enso_build::project::gui::Gui;
|
||||
use enso_build::project::wasm::Wasm;
|
||||
|
||||
|
||||
|
||||
source_args_hlp!(Gui, "gui", BuildInput);
|
||||
|
||||
impl IsWatchableSource for Gui {
|
||||
type WatchInput = WatchInput;
|
||||
}
|
||||
|
||||
#[derive(Args, Clone, Debug, PartialEq)]
|
||||
pub struct BuildInput {
|
||||
#[clap(flatten)]
|
||||
pub wasm: Source<Wasm>,
|
||||
}
|
||||
|
||||
#[derive(Args, Clone, Debug, PartialEq)]
|
||||
pub struct WatchInput {
|
||||
#[clap(flatten)]
|
||||
pub wasm: <Wasm as IsWatchableSource>::WatchInput,
|
||||
}
|
||||
#[derive(Args, Clone, Copy, Debug, PartialEq)]
|
||||
pub struct BuildInput {}
|
||||
|
||||
#[derive(Subcommand, Clone, Debug, PartialEq)]
|
||||
pub enum Command {
|
||||
@ -37,8 +21,12 @@ pub enum Command {
|
||||
Build(BuildJob<Gui>),
|
||||
/// Gets the GUI, either by compiling it from scratch or downloading from an external source.
|
||||
Get(Source<Gui>),
|
||||
/// Runs the GUI's unit tests.
|
||||
Test,
|
||||
/// Run linter on the GUI's sources.
|
||||
Lint,
|
||||
/// Continuously rebuilds GUI when its sources are changed and serves it using dev-server.
|
||||
Watch(WatchJob<Gui>),
|
||||
Watch,
|
||||
}
|
||||
|
||||
#[derive(Args, Clone, Debug)]
|
||||
|
@ -1,37 +0,0 @@
|
||||
use enso_build::prelude::*;
|
||||
|
||||
use crate::arg::BuildJob;
|
||||
use crate::arg::Source;
|
||||
use crate::source_args_hlp;
|
||||
|
||||
use clap::Args;
|
||||
use clap::Subcommand;
|
||||
use enso_build::project::gui2::Gui2;
|
||||
|
||||
|
||||
|
||||
source_args_hlp!(Gui2, "gui2", BuildInput);
|
||||
|
||||
#[derive(Args, Clone, Copy, Debug, PartialEq)]
|
||||
pub struct BuildInput {}
|
||||
|
||||
#[derive(Subcommand, Clone, Debug, PartialEq)]
|
||||
pub enum Command {
|
||||
/// Builds the GUI from the local sources.
|
||||
Build(BuildJob<Gui2>),
|
||||
/// Gets the GUI, either by compiling it from scratch or downloading from an external source.
|
||||
Get(Source<Gui2>),
|
||||
/// Runs the GUI's unit tests.
|
||||
Test,
|
||||
/// Run linter on the GUI's sources.
|
||||
Lint,
|
||||
/// Continuously rebuilds GUI when its sources are changed and serves it using dev-server.
|
||||
Watch,
|
||||
}
|
||||
|
||||
#[derive(Args, Clone, Debug)]
|
||||
pub struct Target {
|
||||
/// Command for GUI package.
|
||||
#[clap(subcommand)]
|
||||
pub command: Command,
|
||||
}
|
@ -1,25 +1,22 @@
|
||||
use crate::prelude::*;
|
||||
|
||||
use crate::arg::IsTargetSource;
|
||||
use crate::arg::OutputPath;
|
||||
use crate::arg::Source;
|
||||
use crate::arg::WatchJob;
|
||||
use crate::source_args_hlp;
|
||||
|
||||
use clap::Args;
|
||||
use clap::Subcommand;
|
||||
use enso_build::project::backend::Backend;
|
||||
use enso_build::project::gui::Gui;
|
||||
use enso_build::project::wasm::DEFAULT_INTEGRATION_TESTS_WASM_TIMEOUT;
|
||||
use octocrab::models::ReleaseId;
|
||||
|
||||
|
||||
|
||||
source_args_hlp!(Target, "ide", BuildInput<Gui, Target>);
|
||||
source_args_hlp!(Target, "ide", BuildInput);
|
||||
|
||||
#[derive(Args, Clone, Debug, Derivative)]
|
||||
#[derivative(PartialEq)]
|
||||
pub struct BuildInput<Gui: IsTargetSource, Ide: IsTargetSource = Target> {
|
||||
pub struct BuildInput {
|
||||
#[derivative(PartialEq(bound = ""))]
|
||||
#[clap(flatten)]
|
||||
pub gui: Source<Gui>,
|
||||
@ -27,7 +24,7 @@ pub struct BuildInput<Gui: IsTargetSource, Ide: IsTargetSource = Target> {
|
||||
pub project_manager: Source<Backend>,
|
||||
#[derivative(PartialEq(bound = ""))]
|
||||
#[clap(flatten)]
|
||||
pub output_path: OutputPath<Ide>,
|
||||
pub output_path: OutputPath<Target>,
|
||||
/// Override the default target for electron-builder. E.g. pass `dir` for unpacked directory
|
||||
/// (fastest). See <https://www.electron.build> for all supported targets.
|
||||
#[clap(long, enso_env())]
|
||||
@ -40,50 +37,16 @@ pub enum Command {
|
||||
/// application.
|
||||
Build {
|
||||
#[clap(flatten)]
|
||||
params: BuildInput<Gui>,
|
||||
params: BuildInput,
|
||||
},
|
||||
/// Build and upload the new IDE as a release asset.
|
||||
/// This command is intended for CI-use only.
|
||||
Upload {
|
||||
#[clap(flatten)]
|
||||
params: BuildInput<Gui>,
|
||||
params: BuildInput,
|
||||
#[clap(long, env = *enso_build::env::ENSO_RELEASE_ID)]
|
||||
release_id: ReleaseId,
|
||||
},
|
||||
/// Like `Build` but automatically starts the IDE.
|
||||
Start {
|
||||
#[clap(flatten)]
|
||||
params: BuildInput<Gui>,
|
||||
/// Additional option to be passed to Enso IDE. Can be used multiple times to pass many
|
||||
/// arguments.
|
||||
#[clap(long, allow_hyphen_values = true, enso_env())]
|
||||
ide_option: Vec<String>,
|
||||
},
|
||||
Watch {
|
||||
#[clap(flatten)]
|
||||
gui: WatchJob<Gui>,
|
||||
#[clap(flatten)]
|
||||
project_manager: Source<Backend>,
|
||||
#[clap(long, allow_hyphen_values = true, enso_env())]
|
||||
ide_option: Vec<String>,
|
||||
},
|
||||
/// Runs integration tests. This involves building and spawning Project Manager, unless
|
||||
/// requested otherwise.
|
||||
IntegrationTest {
|
||||
/// If set, the project manager won't be spawned.
|
||||
#[clap(long)]
|
||||
external_backend: bool,
|
||||
#[clap(flatten)]
|
||||
project_manager: Source<Backend>,
|
||||
/// Run WASM tests in the headless mode
|
||||
#[clap(long, parse(try_from_str), default_value_t = true)]
|
||||
headless: bool,
|
||||
/// Custom timeout for wasm-bindgen test runner. Supports formats like "300secs" or "5min".
|
||||
#[clap(long, default_value_t = DEFAULT_INTEGRATION_TESTS_WASM_TIMEOUT.into())]
|
||||
wasm_timeout: humantime::Duration,
|
||||
/// Additional options to be appended to the wasm-pack invocation. Note that wasm-pack will
|
||||
/// further redirect any unrecognized option to the underlying cargo call.
|
||||
#[clap(last = true)]
|
||||
wasm_pack_options: Vec<String>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Args, Clone, Debug)]
|
||||
|
@ -1,38 +0,0 @@
|
||||
use crate::prelude::*;
|
||||
|
||||
use crate::source_args_hlp;
|
||||
|
||||
use clap::Args;
|
||||
use clap::Subcommand;
|
||||
use enso_build::project::gui2::Gui2;
|
||||
use octocrab::models::ReleaseId;
|
||||
|
||||
|
||||
|
||||
source_args_hlp!(Target, "ide2", BuildInput);
|
||||
|
||||
pub type BuildInput = crate::arg::ide::BuildInput<Gui2, Target>;
|
||||
|
||||
#[derive(Subcommand, Clone, Debug)]
|
||||
pub enum Command {
|
||||
/// Builds both Project Manager and GUI, puts them together into a single, client Electron
|
||||
/// application.
|
||||
Build {
|
||||
#[clap(flatten)]
|
||||
params: BuildInput,
|
||||
},
|
||||
/// Build and upload the new IDE as a release asset.
|
||||
/// This command is intended for CI-use only.
|
||||
Upload {
|
||||
#[clap(flatten)]
|
||||
params: BuildInput,
|
||||
#[clap(long, env = *enso_build::env::ENSO_RELEASE_ID)]
|
||||
release_id: ReleaseId,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Args, Clone, Debug)]
|
||||
pub struct Target {
|
||||
#[clap(subcommand)]
|
||||
pub command: Command,
|
||||
}
|
@ -1,111 +1,15 @@
|
||||
use enso_build::prelude::*;
|
||||
|
||||
use crate::arg::ArgExt;
|
||||
use crate::arg::Source;
|
||||
use crate::arg::WatchJob;
|
||||
use crate::source_args_hlp;
|
||||
use crate::BuildJob;
|
||||
use crate::IsWatchableSource;
|
||||
|
||||
use clap::Args;
|
||||
use clap::Subcommand;
|
||||
use enso_build::project::wasm::test::Browser;
|
||||
use enso_build::project::wasm::Wasm;
|
||||
use std::sync::OnceLock;
|
||||
|
||||
|
||||
// ==============
|
||||
// === Export ===
|
||||
// ==============
|
||||
|
||||
pub use enso_build::project::wasm::LogLevel;
|
||||
pub use enso_build::project::wasm::Profile;
|
||||
pub use enso_build::project::wasm::ProfilingLevel;
|
||||
|
||||
|
||||
|
||||
source_args_hlp!(Wasm, "wasm", BuildInput);
|
||||
|
||||
impl IsWatchableSource for Wasm {
|
||||
type WatchInput = WatchInput;
|
||||
}
|
||||
|
||||
static DEFAULT_WASM_SIZE_LIMIT: OnceLock<String> = OnceLock::new();
|
||||
|
||||
pub fn initialize_default_wasm_size_limit(limit: byte_unit::Byte) -> Result {
|
||||
DEFAULT_WASM_SIZE_LIMIT
|
||||
.set(limit.get_appropriate_unit(true).to_string())
|
||||
.map_err(|e| anyhow!("WASM size limit was already set to {e}."))
|
||||
}
|
||||
|
||||
#[derive(Args, Clone, Debug, PartialEq, Eq)]
|
||||
pub struct BuildInput {
|
||||
/// Which crate should be treated as a WASM entry point. Relative path from source root.
|
||||
#[clap(default_value = enso_build::project::wasm::DEFAULT_TARGET_CRATE, long, enso_env())]
|
||||
pub crate_path: PathBuf,
|
||||
|
||||
/// Profile that is passed to wasm-pack.
|
||||
#[clap(long, arg_enum, default_value_t = Profile::Release, enso_env())]
|
||||
pub wasm_profile: Profile,
|
||||
|
||||
/// Additional options to be passed to wasm-opt. Might overwrite the optimization flag
|
||||
/// resulting from 'wasm_profile' setting.
|
||||
#[clap(long, allow_hyphen_values = true, enso_env())]
|
||||
pub wasm_opt_option: Vec<String>,
|
||||
|
||||
/// Do not invoke wasm-opt, even if it is part of current profile.
|
||||
#[clap(long, conflicts_with = "wasm-opt-option", enso_env())]
|
||||
pub skip_wasm_opt: bool,
|
||||
|
||||
/// Additional options to be passed to Cargo.
|
||||
#[clap(last = true, enso_env())]
|
||||
pub cargo_options: Vec<String>,
|
||||
|
||||
/// Compiles Enso with given profiling level. If not set, defaults to minimum.
|
||||
#[clap(long, arg_enum, enso_env())]
|
||||
pub profiling_level: Option<ProfilingLevel>,
|
||||
|
||||
/// Compiles Enso with given log level.
|
||||
#[clap(long, arg_enum, enso_env(), default_value_t)]
|
||||
pub wasm_log_level: LogLevel,
|
||||
|
||||
/// Compiles Enso with given uncollapsed log level.
|
||||
#[clap(long, arg_enum, enso_env(), default_value_t)]
|
||||
pub wasm_uncollapsed_log_level: LogLevel,
|
||||
|
||||
/// Fail the build if compressed WASM exceeds the specified size. Supports format like
|
||||
/// "4.06MiB". Pass "0" to disable check.
|
||||
#[clap(long, enso_env(),
|
||||
maybe_default = DEFAULT_WASM_SIZE_LIMIT.get(),
|
||||
default_value_if("skip-wasm-opt", Some("true"), Some("0")),
|
||||
default_value_if("skip-wasm-opt", None, Some("0")),
|
||||
)]
|
||||
pub wasm_size_limit: Option<byte_unit::Byte>,
|
||||
|
||||
/// Allow usage of system installation of `shaderc`, `spirv-opt` and `spirv-cross`. When
|
||||
/// present, the binaries from PATH will be preferred over downloading prebuilt distribution.
|
||||
/// Caution: old versions of those tools might introduce subtle bugs in optimized shaders.
|
||||
#[clap(long, enso_env())]
|
||||
pub system_shader_tools: bool,
|
||||
}
|
||||
|
||||
#[derive(Args, Clone, Debug, PartialEq, Eq)]
|
||||
pub struct WatchInput {
|
||||
/// Additional option to be passed to Cargo. Can be used multiple times to pass many arguments.
|
||||
#[clap(long, allow_hyphen_values = true, enso_env())]
|
||||
pub cargo_watch_option: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Subcommand, Clone, Debug, PartialEq)]
|
||||
pub enum Command {
|
||||
/// Build the WASM package.
|
||||
Build(BuildJob<Wasm>),
|
||||
/// Lint the codebase.
|
||||
Check,
|
||||
/// Get the WASM artifacts from arbitrary source (e.g. release).
|
||||
Get(Source<Wasm>),
|
||||
/// Start an ongoing watch process that rebuilds WASM when its sources are touched.
|
||||
Watch(WatchJob<Wasm>),
|
||||
/// Run the unit tests.
|
||||
Test {
|
||||
/// Skip the native (non-WASM) Rust tests.
|
||||
|
@ -38,7 +38,6 @@ use crate::arg::BuildJob;
|
||||
use crate::arg::Cli;
|
||||
use crate::arg::IsTargetSource;
|
||||
use crate::arg::IsWatchableSource;
|
||||
use crate::arg::OutputPath;
|
||||
use crate::arg::Target;
|
||||
use crate::arg::WatchJob;
|
||||
use anyhow::Context;
|
||||
@ -56,16 +55,10 @@ use enso_build::project::backend;
|
||||
use enso_build::project::backend::Backend;
|
||||
use enso_build::project::gui;
|
||||
use enso_build::project::gui::Gui;
|
||||
use enso_build::project::gui2;
|
||||
use enso_build::project::gui2::Gui2;
|
||||
use enso_build::project::ide;
|
||||
use enso_build::project::ide::Ide;
|
||||
use enso_build::project::ide2;
|
||||
use enso_build::project::runtime;
|
||||
use enso_build::project::runtime::Runtime;
|
||||
use enso_build::project::wasm;
|
||||
use enso_build::project::wasm::Wasm;
|
||||
use enso_build::project::IsArtifact;
|
||||
use enso_build::project::IsTarget;
|
||||
use enso_build::project::IsWatchable;
|
||||
use enso_build::project::IsWatcher;
|
||||
@ -96,7 +89,6 @@ use ide_ci::programs::rustc;
|
||||
use ide_ci::programs::Cargo;
|
||||
use octocrab::models::ReleaseId;
|
||||
use std::time::Duration;
|
||||
use tempfile::tempdir;
|
||||
use tokio::process::Child;
|
||||
|
||||
pub fn void<T>(_t: T) {}
|
||||
@ -346,16 +338,12 @@ impl Processor {
|
||||
|
||||
pub fn handle_wasm(&self, wasm: arg::wasm::Target) -> BoxFuture<'static, Result> {
|
||||
match wasm.command {
|
||||
arg::wasm::Command::Watch(job) => self.watch_and_wait(job),
|
||||
arg::wasm::Command::Build(job) => self.build(job).void_ok().boxed(),
|
||||
arg::wasm::Command::Check => Wasm.check().boxed(),
|
||||
arg::wasm::Command::Test { no_wasm, no_native, browser } => {
|
||||
let wasm_browsers =
|
||||
if no_wasm { default() } else { browser.into_iter().map_into().collect_vec() };
|
||||
let root = self.repo_root.to_path_buf();
|
||||
async move { Wasm.test(root, &wasm_browsers, !no_native).await }.boxed()
|
||||
async move { project::wasm::test(root, &wasm_browsers, !no_native).await }.boxed()
|
||||
}
|
||||
arg::wasm::Command::Get(source) => self.get(source).void_ok().boxed(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -363,30 +351,22 @@ impl Processor {
|
||||
match gui.command {
|
||||
arg::gui::Command::Build(job) => self.build(job),
|
||||
arg::gui::Command::Get(source) => self.get(source).void_ok().boxed(),
|
||||
arg::gui::Command::Watch(job) => self.watch_and_wait(job),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_gui2(&self, gui: arg::gui2::Target) -> BoxFuture<'static, Result> {
|
||||
match gui.command {
|
||||
arg::gui2::Command::Build(job) => self.build(job),
|
||||
arg::gui2::Command::Get(source) => self.get(source).void_ok().boxed(),
|
||||
arg::gui2::Command::Test => {
|
||||
arg::gui::Command::Test => {
|
||||
let repo_root = self.repo_root.clone();
|
||||
let gui_tests = run_and_upload_dir(
|
||||
gui2::tests(&repo_root),
|
||||
gui::tests(&repo_root),
|
||||
&repo_root.app.gui_2.playwright_report,
|
||||
"gui2-playwright-report",
|
||||
"gui-playwright-report",
|
||||
);
|
||||
let dashboard_tests = run_and_upload_dir(
|
||||
gui2::dashboard_tests(&repo_root),
|
||||
gui::dashboard_tests(&repo_root),
|
||||
&repo_root.app.ide_desktop.lib.dashboard.playwright_report,
|
||||
"dashboard-playwright-report",
|
||||
);
|
||||
try_join(gui_tests, dashboard_tests).void_ok().boxed()
|
||||
}
|
||||
arg::gui2::Command::Watch => gui2::watch(&self.repo_root),
|
||||
arg::gui2::Command::Lint => gui2::lint(&self.repo_root),
|
||||
arg::gui::Command::Watch => gui::watch(&self.repo_root),
|
||||
arg::gui::Command::Lint => gui::lint(&self.repo_root),
|
||||
}
|
||||
}
|
||||
|
||||
@ -556,77 +536,11 @@ impl Processor {
|
||||
|
||||
pub fn handle_ide(&self, ide: arg::ide::Target) -> BoxFuture<'static, Result> {
|
||||
match ide.command {
|
||||
arg::ide::Command::Build { params } => self.build_old_ide(params).void_ok().boxed(),
|
||||
arg::ide::Command::Build { params } => self.build_ide(params).void_ok().boxed(),
|
||||
arg::ide::Command::Upload { params, release_id } => {
|
||||
let build_job = self.build_old_ide(params);
|
||||
let build_job = self.build_ide(params);
|
||||
self.upload_ide_assets(build_job, release_id, None)
|
||||
}
|
||||
arg::ide::Command::Start { params, ide_option } => {
|
||||
let build_job = self.build_old_ide(params);
|
||||
async move {
|
||||
let ide = build_job.await?;
|
||||
ide.start_unpacked(ide_option).run_ok().await?;
|
||||
Ok(())
|
||||
}
|
||||
.boxed()
|
||||
}
|
||||
arg::ide::Command::Watch { gui, project_manager, ide_option: ide_watch } => {
|
||||
let context = self.context();
|
||||
let watch_gui_job = self.resolve_watch_job(gui);
|
||||
let project_manager = self.get(project_manager);
|
||||
async move {
|
||||
crate::project::Ide::default()
|
||||
.watch(&context, watch_gui_job.await?, project_manager, ide_watch)
|
||||
.await
|
||||
}
|
||||
.boxed()
|
||||
}
|
||||
arg::ide::Command::IntegrationTest {
|
||||
external_backend,
|
||||
project_manager,
|
||||
wasm_pack_options,
|
||||
headless,
|
||||
wasm_timeout,
|
||||
} => {
|
||||
let custom_root = tempdir();
|
||||
let (custom_root, project_manager) = match custom_root {
|
||||
Ok(tempdir) => {
|
||||
let custom_root = Some(tempdir.path().into());
|
||||
(
|
||||
Some(tempdir),
|
||||
Ok(self.spawn_project_manager(project_manager, custom_root)),
|
||||
)
|
||||
}
|
||||
Err(e) => (None, Err(e)),
|
||||
};
|
||||
let source_root = self.repo_root.to_path_buf();
|
||||
async move {
|
||||
let project_manager =
|
||||
if !external_backend { Some(project_manager?.await?) } else { None };
|
||||
Wasm.integration_test(
|
||||
source_root,
|
||||
project_manager,
|
||||
headless,
|
||||
wasm_pack_options,
|
||||
Some(wasm_timeout.into()),
|
||||
)
|
||||
.await?;
|
||||
// Custom root must live while the tests are being run.
|
||||
drop(custom_root);
|
||||
Ok(())
|
||||
}
|
||||
.boxed()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_ide2(&self, ide: arg::ide2::Target) -> BoxFuture<'static, Result> {
|
||||
match ide.command {
|
||||
arg::ide2::Command::Build { params } => self.build_new_ide(params).void_ok().boxed(),
|
||||
arg::ide2::Command::Upload { params, release_id } => {
|
||||
let build_job = self.build_new_ide(params);
|
||||
self.upload_ide_assets(build_job, release_id, Some("ide2".into()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -649,43 +563,11 @@ impl Processor {
|
||||
}
|
||||
.boxed()
|
||||
}
|
||||
|
||||
pub fn build_ide(
|
||||
&self,
|
||||
input: ide::BuildInput<impl IsArtifact>,
|
||||
output_path: OutputPath<impl IsTargetSource + Send + Sync + 'static>,
|
||||
params: arg::ide::BuildInput,
|
||||
) -> BoxFuture<'static, Result<ide::Artifact>> {
|
||||
let target = Ide { target_os: self.triple.os, target_arch: self.triple.arch };
|
||||
let artifact_name_prefix = input.artifact_name.clone();
|
||||
let build_job = target.build(&self.context, input, output_path);
|
||||
async move {
|
||||
let artifacts = build_job.await?;
|
||||
if is_in_env() {
|
||||
artifacts.upload_as_ci_artifact(artifact_name_prefix).await?;
|
||||
}
|
||||
Ok(artifacts)
|
||||
}
|
||||
.boxed()
|
||||
}
|
||||
|
||||
pub fn build_old_ide(
|
||||
&self,
|
||||
params: arg::ide::BuildInput<Gui>,
|
||||
) -> BoxFuture<'static, Result<ide::Artifact>> {
|
||||
let arg::ide::BuildInput { gui, project_manager, output_path, electron_target } = params;
|
||||
let input = ide::BuildInput {
|
||||
gui: self.get(gui),
|
||||
project_manager: self.get(project_manager),
|
||||
version: self.triple.versions.version.clone(),
|
||||
electron_target,
|
||||
artifact_name: "ide".into(),
|
||||
};
|
||||
self.build_ide(input, output_path)
|
||||
}
|
||||
|
||||
pub fn build_new_ide(
|
||||
&self,
|
||||
params: arg::ide2::BuildInput,
|
||||
) -> BoxFuture<'static, Result<ide2::Artifact>> {
|
||||
let arg::ide::BuildInput { gui, project_manager, output_path, electron_target } = params;
|
||||
|
||||
let build_info_get = self.js_build_info();
|
||||
@ -707,9 +589,20 @@ impl Processor {
|
||||
project_manager: self.get(project_manager),
|
||||
version: self.triple.versions.version.clone(),
|
||||
electron_target,
|
||||
artifact_name: "ide2".into(),
|
||||
artifact_name: "ide".into(),
|
||||
};
|
||||
self.build_ide(input, output_path)
|
||||
|
||||
let target = Ide { target_os: self.triple.os, target_arch: self.triple.arch };
|
||||
let artifact_name_prefix = input.artifact_name.clone();
|
||||
let build_job = target.build(&self.context, input, output_path);
|
||||
async move {
|
||||
let artifacts = build_job.await?;
|
||||
if is_in_env() {
|
||||
artifacts.upload_as_ci_artifact(artifact_name_prefix).await?;
|
||||
}
|
||||
Ok(artifacts)
|
||||
}
|
||||
.boxed()
|
||||
}
|
||||
|
||||
pub fn target<Target: Resolvable>(&self) -> Result<Target> {
|
||||
@ -726,60 +619,9 @@ pub trait Resolvable: IsTarget + IsTargetSource + Clone {
|
||||
) -> BoxFuture<'static, Result<<Self as IsTarget>::BuildInput>>;
|
||||
}
|
||||
|
||||
impl Resolvable for Wasm {
|
||||
fn prepare_target(_context: &Processor) -> Result<Self> {
|
||||
Ok(Wasm {})
|
||||
}
|
||||
|
||||
fn resolve(
|
||||
_ctx: &Processor,
|
||||
from: <Self as IsTargetSource>::BuildInput,
|
||||
) -> BoxFuture<'static, Result<<Self as IsTarget>::BuildInput>> {
|
||||
let arg::wasm::BuildInput {
|
||||
crate_path,
|
||||
wasm_profile,
|
||||
wasm_opt_option: wasm_opt_options,
|
||||
cargo_options,
|
||||
profiling_level,
|
||||
wasm_log_level,
|
||||
wasm_uncollapsed_log_level,
|
||||
wasm_size_limit,
|
||||
skip_wasm_opt,
|
||||
system_shader_tools,
|
||||
} = from;
|
||||
ok_ready_boxed(wasm::BuildInput {
|
||||
crate_path,
|
||||
wasm_opt_options,
|
||||
skip_wasm_opt,
|
||||
extra_cargo_options: cargo_options,
|
||||
profile: wasm_profile,
|
||||
profiling_level,
|
||||
log_level: wasm_log_level,
|
||||
uncollapsed_log_level: wasm_uncollapsed_log_level,
|
||||
wasm_size_limit: wasm_size_limit.filter(|size_limit| size_limit.get_bytes() > 0),
|
||||
system_shader_tools,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Resolvable for Gui {
|
||||
fn prepare_target(_context: &Processor) -> Result<Self> {
|
||||
Ok(Gui {})
|
||||
}
|
||||
|
||||
fn resolve(
|
||||
ctx: &Processor,
|
||||
from: <Self as IsTargetSource>::BuildInput,
|
||||
) -> BoxFuture<'static, Result<<Self as IsTarget>::BuildInput>> {
|
||||
let wasm_source = ctx.resolve(Wasm, from.wasm);
|
||||
let build_info = ctx.js_build_info();
|
||||
async move { Ok(gui::BuildInput { wasm: wasm_source.await?, build_info }) }.boxed()
|
||||
}
|
||||
}
|
||||
|
||||
impl Resolvable for Gui2 {
|
||||
fn prepare_target(_context: &Processor) -> Result<Self> {
|
||||
Ok(Gui2)
|
||||
Ok(Gui)
|
||||
}
|
||||
|
||||
fn resolve(
|
||||
@ -841,24 +683,6 @@ pub trait WatchResolvable: Resolvable + IsWatchableSource + IsWatchable {
|
||||
) -> Result<<Self as IsWatchable>::WatchInput>;
|
||||
}
|
||||
|
||||
impl WatchResolvable for Wasm {
|
||||
fn resolve_watch(
|
||||
_ctx: &Processor,
|
||||
from: <Self as IsWatchableSource>::WatchInput,
|
||||
) -> Result<<Self as IsWatchable>::WatchInput> {
|
||||
Ok(wasm::WatchInput { cargo_watch_options: from.cargo_watch_option })
|
||||
}
|
||||
}
|
||||
|
||||
impl WatchResolvable for Gui {
|
||||
fn resolve_watch(
|
||||
ctx: &Processor,
|
||||
from: <Self as IsWatchableSource>::WatchInput,
|
||||
) -> Result<<Self as IsWatchable>::WatchInput> {
|
||||
Ok(gui::WatchInput { wasm: Wasm::resolve_watch(ctx, from.wasm)? })
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(err, skip(config))]
|
||||
pub async fn main_internal(config: Option<Config>) -> Result {
|
||||
trace!("Starting the build process.");
|
||||
@ -868,11 +692,6 @@ pub async fn main_internal(config: Option<Config>) -> Result {
|
||||
});
|
||||
|
||||
trace!("Creating the build context.");
|
||||
// Setup that affects Cli parser construction.
|
||||
if let Some(wasm_size_limit) = config.wasm_size_limit {
|
||||
crate::arg::wasm::initialize_default_wasm_size_limit(wasm_size_limit)?;
|
||||
}
|
||||
|
||||
debug!("Initial configuration for the CLI driver: {config:#?}");
|
||||
|
||||
let cli = Cli::parse();
|
||||
@ -902,14 +721,9 @@ pub async fn main_internal(config: Option<Config>) -> Result {
|
||||
match cli.target {
|
||||
Target::Wasm(wasm) => ctx.handle_wasm(wasm).await?,
|
||||
Target::Gui(gui) => ctx.handle_gui(gui).await?,
|
||||
Target::Gui2(gui2) => ctx.handle_gui2(gui2).await?,
|
||||
Target::Runtime(runtime) => ctx.handle_runtime(runtime).await?,
|
||||
// Target::ProjectManager(project_manager) =>
|
||||
// ctx.handle_project_manager(project_manager).await?,
|
||||
// Target::Engine(engine) => ctx.handle_engine(engine).await?,
|
||||
Target::Backend(backend) => ctx.handle_backend(backend).await?,
|
||||
Target::Ide(ide) => ctx.handle_ide(ide).await?,
|
||||
Target::Ide2(ide2) => ctx.handle_ide2(ide2).await?,
|
||||
Target::GitClean(options) => {
|
||||
let crate::arg::git_clean::Options { dry_run, cache, build_script } = options;
|
||||
let mut exclusions = vec![".idea"];
|
||||
|
Loading…
Reference in New Issue
Block a user