├── .editorconfig ├── .github ├── changelog-configuration.json └── workflows │ ├── deploy.yml │ ├── docs.yml │ ├── release.yml │ └── virtualos.yml ├── .gitignore ├── .mise.toml ├── .mise └── tasks │ ├── build │ ├── bundle │ ├── cache │ ├── docs │ ├── build │ ├── deploy │ └── dev │ ├── encrypt-certificate │ ├── install │ ├── lint │ ├── lint-fix │ └── test ├── .swiftformat ├── .swiftlint.yml ├── CHANGELOG.md ├── LICENSE ├── Package.resolved ├── Package.swift ├── Project.swift ├── README.md ├── Sources ├── VirtualOSEnvironment │ └── Environment.swift ├── VirtualOSEnvironmentInterface │ ├── Environmenting.swift │ └── ServiceContext+Environment.swift ├── VirtualOSLogging │ └── Logger.swift ├── VirtualOSNetwork │ └── VirtualOSNetwork.swift ├── VirtualOSNetworkInterface │ └── NetworkInterface.swift ├── VirtualOSOCI │ └── VirtualOSOCI.swift ├── VirtualOSOCIInterface │ ├── OCIContentDescriptor.swift │ └── OCIImage.swift ├── VirtualOSPull │ ├── PullCommand.swift │ └── PullService.swift ├── VirtualOSPullInterface │ └── VirtualOSPullInterface.swift ├── VirtualOSPushInterface │ └── VirtualOSPushInterface.swift ├── VirtualOSRun │ └── RunCommand.swift ├── VirtualOSRunInterface │ └── VirtualOSRunInterface.swift ├── VirtualOSStorage │ └── Storage.swift ├── VirtualOSStorageInterface │ ├── Image.swift │ └── Storaging.swift └── virtualos │ ├── VirtualOS.swift │ └── VirtualOSCommand.swift ├── Tests ├── VirtualOSEnvironmentTests │ └── VirtualOSEnvironmentTests.swift ├── VirtualOSLoggingTests │ └── LoggerTests.swift ├── VirtualOSNetworkTests │ └── VirtualOSNetworkTests.swift ├── VirtualOSOCITests │ └── VirtualOSOCITests.swift ├── VirtualOSPullTests │ └── VirtualOSPullTests.swift ├── VirtualOSRunTests │ └── VirtualOSRunTests.swift └── VirtualOSStorageTests │ └── VirtualOSStorageTests.swift ├── Tuist.swift ├── Tuist └── ProjectDescriptionHelpers │ └── Module.swift ├── assets └── logo.svg ├── certificates └── certificate.p12.enc ├── cliff.toml ├── docs ├── .vitepress │ ├── config.mjs │ └── icons.mjs ├── content │ ├── index.md │ └── public │ │ ├── favicon.ico │ │ ├── logo.png │ │ └── og.jpeg ├── package.json └── pnpm-lock.yaml └── renovate.json /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: https://EditorConfig.org 2 | 3 | # Top-most EditorConfig file 4 | root = true 5 | 6 | # Unix-style newlines with a newline ending every file 7 | [*] 8 | end_of_line = lf 9 | insert_final_newline = true 10 | indent_style = space 11 | indent_size = 2 12 | trim_trailing_whitespace = true 13 | 14 | [*.rb] 15 | charset = utf-8 16 | 17 | [*.md] 18 | trim_trailing_whitespace = false -------------------------------------------------------------------------------- /.github/changelog-configuration.json: -------------------------------------------------------------------------------- 1 | { 2 | "categories": [ 3 | { 4 | "title": "#### Changed", 5 | "labels": ["changelog:changed"] 6 | }, 7 | { 8 | "title": "#### Added", 9 | "labels": ["changelog:added"] 10 | }, 11 | { 12 | "title": "#### Fixed", 13 | "labels": ["changelog:fixed"] 14 | }, 15 | { 16 | "title": "#### Dependency updates", 17 | "labels": ["changelog:updated-dependencies"] 18 | } 19 | ], 20 | "pr_template": "- ${{TITLE}} by [@${{AUTHOR}}](https://github.com/${{AUTHOR}})" 21 | } -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: Deploy 2 | on: 3 | push: 4 | branches: 5 | - "main" 6 | 7 | concurrency: 8 | group: deploy-${{ github.head_ref }} 9 | cancel-in-progress: true 10 | 11 | env: 12 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 13 | 14 | jobs: 15 | docs: 16 | name: Docs 17 | runs-on: ubuntu-latest 18 | env: 19 | CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} 20 | CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} 21 | steps: 22 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 23 | - uses: jdx/mise-action@v2 24 | with: 25 | experimental: true 26 | - run: mise run install 27 | - run: mise run docs:deploy 28 | -------------------------------------------------------------------------------- /.github/workflows/docs.yml: -------------------------------------------------------------------------------- 1 | name: Docs 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: {} 8 | 9 | concurrency: 10 | group: docs-${{ github.head_ref }} 11 | cancel-in-progress: true 12 | 13 | env: 14 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 15 | 16 | jobs: 17 | build: 18 | name: "Build" 19 | runs-on: "ubuntu-latest" 20 | steps: 21 | - uses: actions/checkout@v4 22 | - uses: jdx/mise-action@v2 23 | with: 24 | experimental: true 25 | - name: Install 26 | run: | 27 | mise run install 28 | - name: Build 29 | run: | 30 | mise run docs:build 31 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | concurrency: 9 | group: release-${{ github.head_ref }} 10 | cancel-in-progress: true 11 | 12 | env: 13 | MISE_EXPERIMENTAL: "1" 14 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 15 | 16 | jobs: 17 | build: 18 | name: Continuous 19 | runs-on: "macos-14" 20 | steps: 21 | - uses: actions/checkout@v4 22 | with: 23 | fetch-depth: "0" 24 | fetch-tags: true 25 | - uses: jdx/mise-action@v2 26 | if: "!startsWith(github.event.head_commit.message, 'release')" 27 | - run: mise run install 28 | if: "!startsWith(github.event.head_commit.message, 'release')" 29 | - name: bundle 30 | if: "!startsWith(github.event.head_commit.message, 'release')" 31 | env: 32 | CERTIFICATE_PASSWORD: ${{ secrets.CERTIFICATE_PASSWORD }} 33 | APPLE_ID: ${{ secrets.APPLE_ID }} 34 | APP_SPECIFIC_PASSWORD: ${{ secrets.APP_SPECIFIC_PASSWORD }} 35 | CERTIFICATE_ENCRYPTION_PASSWORD: ${{ secrets.CERTIFICATE_ENCRYPTION_PASSWORD }} 36 | TUIST_CONFIG_TOKEN: ${{ secrets.TUIST_CONFIG_TOKEN }} 37 | run: mise run bundle 38 | - name: Get next version 39 | if: "!startsWith(github.event.head_commit.message, 'release')" 40 | id: version 41 | env: 42 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 43 | run: | 44 | echo "VERSION=$(git-cliff --bumped-version)" >> $GITHUB_ENV 45 | - name: Generate changelog 46 | if: "!startsWith(github.event.head_commit.message, 'release')" 47 | id: changelog 48 | env: 49 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 50 | run: | 51 | git-cliff --bump -o CHANGELOG.md 52 | # - name: Generate release notes 53 | # if: "!startsWith(github.event.head_commit.message, 'release')" 54 | # id: release-notes 55 | # env: 56 | # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 57 | # run: | 58 | # echo "RELEASE_NOTES=$(git-cliff --unreleased)" >> $GITHUB_ENV 59 | - uses: stefanzweifel/git-auto-commit-action@v5 60 | if: "!startsWith(github.event.head_commit.message, 'release')" 61 | with: 62 | commit_message: release ${{ env.VERSION }} 63 | - name: Release 64 | uses: softprops/action-gh-release@v2 65 | if: "!startsWith(github.event.head_commit.message, 'release')" 66 | with: 67 | draft: false 68 | name: ${{ env.VERSION }} 69 | tag_name: ${{ env.VERSION }} 70 | make_latest: true 71 | generate_release_notes: true 72 | files: | 73 | build/artifacts/virtualos.zip 74 | build/artifacts/SHASUMS256.txt 75 | build/artifacts/SHASUMS512.txt 76 | -------------------------------------------------------------------------------- /.github/workflows/virtualos.yml: -------------------------------------------------------------------------------- 1 | name: VirtualOS 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: {} 8 | 9 | concurrency: 10 | group: virtualos-${{ github.head_ref }} 11 | cancel-in-progress: true 12 | 13 | env: 14 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 15 | 16 | jobs: 17 | build: 18 | name: "Build" 19 | runs-on: "macos-13" 20 | steps: 21 | - uses: actions/checkout@v4 22 | - uses: jdx/mise-action@v2 23 | with: 24 | experimental: true 25 | - name: Run 26 | env: 27 | TUIST_CONFIG_TOKEN: ${{ secrets.TUIST_CONFIG_TOKEN }} 28 | run: | 29 | mise run install 30 | mise run build 31 | 32 | bundle: 33 | name: "Bundle" 34 | runs-on: "macos-13" 35 | steps: 36 | - uses: actions/checkout@v4 37 | - uses: jdx/mise-action@v2 38 | with: 39 | experimental: true 40 | - run: mise run install 41 | - name: bundle 42 | env: 43 | CERTIFICATE_PASSWORD: ${{ secrets.CERTIFICATE_PASSWORD }} 44 | APPLE_ID: ${{ secrets.APPLE_ID }} 45 | APP_SPECIFIC_PASSWORD: ${{ secrets.APP_SPECIFIC_PASSWORD }} 46 | CERTIFICATE_ENCRYPTION_PASSWORD: ${{ secrets.CERTIFICATE_ENCRYPTION_PASSWORD }} 47 | TUIST_CONFIG_TOKEN: ${{ secrets.TUIST_CONFIG_TOKEN }} 48 | run: mise run bundle 49 | 50 | test: 51 | name: "Test" 52 | runs-on: "macos-13" 53 | steps: 54 | - uses: actions/checkout@v4 55 | - uses: jdx/mise-action@v2 56 | with: 57 | experimental: true 58 | - name: Run 59 | env: 60 | TUIST_CONFIG_TOKEN: ${{ secrets.TUIST_CONFIG_TOKEN }} 61 | run: | 62 | mise run install 63 | mise run test 64 | 65 | lint: 66 | name: Lint 67 | runs-on: macos-15 68 | steps: 69 | - uses: actions/checkout@v4 70 | - uses: jdx/mise-action@v2 71 | with: 72 | experimental: true 73 | - name: Run 74 | run: mise run lint 75 | 76 | implicit-imports: 77 | name: Implicit imports 78 | runs-on: macos-15 79 | steps: 80 | - uses: actions/checkout@v4 81 | - uses: jdx/mise-action@v2 82 | with: 83 | experimental: true 84 | - run: tuist inspect implicit-imports 85 | 86 | cache: 87 | name: Cache 88 | runs-on: macos-15 89 | steps: 90 | - uses: actions/checkout@v4 91 | - uses: jdx/mise-action@v2 92 | with: 93 | experimental: true 94 | - name: Run 95 | env: 96 | TUIST_CONFIG_TOKEN: ${{ secrets.TUIST_CONFIG_TOKEN }} 97 | run: | 98 | mise run install 99 | mise run cache 100 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /.build 3 | /Packages 4 | xcuserdata/ 5 | DerivedData/ 6 | .swiftpm/configuration/registries.json 7 | .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata 8 | .netrc 9 | 10 | *.xcodeproj/ 11 | *.xcworkspace 12 | Tuist/Dependencies/SwiftPackageManager 13 | 14 | Derived/ 15 | .swiftpm/ 16 | build/ 17 | 18 | node_modules/ 19 | docs/.vitepress/cache/ 20 | docs/.vitepress/dist/ 21 | 22 | certificates/certificate.p12 23 | -------------------------------------------------------------------------------- /.mise.toml: -------------------------------------------------------------------------------- 1 | [tools] 2 | "tuist" = "4.40.0" 3 | "swiftlint" = "0.54.0" 4 | "swiftformat" = "0.52.10" 5 | "swift" = "5.9.2" 6 | "node" = "22.13.1" 7 | "pnpm" = "9.15.4" 8 | "git-cliff" = "2.4.0" 9 | 10 | [alias] 11 | tuist = "asdf:asdf-community/asdf-tuist" 12 | swift = "asdf:fcrespo82/asdf-swift" 13 | virtualos = "asdf:tuist/asdf-virtualos" 14 | -------------------------------------------------------------------------------- /.mise/tasks/build: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # mise description="Builds the package using Tuist" 3 | 4 | set -euo pipefail 5 | 6 | tuist build --path $MISE_PROJECT_ROOT -------------------------------------------------------------------------------- /.mise/tasks/bundle: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # mise description="Bundles the CLI for distribution" 3 | 4 | set -euo pipefail 5 | 6 | # Usage 7 | # CERTIFICATE_PASSWORD=xxxxx APPLE_ID=email APP_SPECIFIC_PASSWORD=xxx mise run bundle 8 | 9 | TMP_DIRECTORY=$(mktemp -d) 10 | TMP_KEYCHAIN_PATH=$TMP_DIRECTORY/keychain.keychain 11 | KEYCHAIN_PASSWORD=$(uuidgen) 12 | ENCRYPTED_CERTIFICATE_PATH=$MISE_PROJECT_ROOT/certificates/certificate.p12.enc 13 | CERTIFICATE_PATH=$TMP_DIRECTORY/certificate.p12 14 | BUILD_DIRECTORY=$MISE_PROJECT_ROOT/build 15 | DERIVED_DATA_PATH=$BUILD_DIRECTORY/derived 16 | BUILD_DIRECTORY_BINARY=$DERIVED_DATA_PATH/Build/Products/Release/virtualos 17 | BUILD_ARTIFACTS_DIRECTORY=$BUILD_DIRECTORY/artifacts 18 | BUILD_ZIP_PATH=$BUILD_ARTIFACTS_DIRECTORY/virtualos.zip 19 | SHASUMS256_FILE=$BUILD_ARTIFACTS_DIRECTORY/SHASUMS256.txt 20 | SHASUMS512_FILE=$BUILD_ARTIFACTS_DIRECTORY/SHASUMS512.txt 21 | TEAM_ID='U6LC622NKF' 22 | GREEN='\033[0;32m' 23 | YELLOW='\033[1;33m' 24 | NC='\033[0m' 25 | 26 | print_status() { 27 | echo -e "${YELLOW}$1${NC}" 28 | } 29 | 30 | # Remove temporary directory on exit 31 | trap "rm -rf $TMP_DIRECTORY" EXIT 32 | 33 | # Decrypt the certificate 34 | print_status "Decrypting the certificate..." 35 | openssl enc -aes-256-cbc -d -pbkdf2 -in $ENCRYPTED_CERTIFICATE_PATH -out $CERTIFICATE_PATH -pass pass:"$CERTIFICATE_ENCRYPTION_PASSWORD" 36 | 37 | # Build 38 | print_status "Building the virtualos..." 39 | tuist generate --path $MISE_PROJECT_ROOT --no-open 40 | tuist build --clean --path $MISE_PROJECT_ROOT virtualos -- -configuration Release -destination generic/platform=macOS -derivedDataPath $DERIVED_DATA_PATH 41 | 42 | # Codesign 43 | print_status "Code signing virtualos..." 44 | security create-keychain -p $KEYCHAIN_PASSWORD $TMP_KEYCHAIN_PATH 45 | security default-keychain -s $TMP_KEYCHAIN_PATH 46 | security import $CERTIFICATE_PATH -P $CERTIFICATE_PASSWORD -A 47 | codesign --force --options runtime --sign "Developer ID Application: Tuist GmbH (U6LC622NKF)" $BUILD_DIRECTORY_BINARY 48 | 49 | # Notarize 50 | print_status "Submitting virtualos for notarization..." 51 | mkdir -p $BUILD_ARTIFACTS_DIRECTORY 52 | ditto -c -k --keepParent $BUILD_DIRECTORY_BINARY $BUILD_ZIP_PATH 53 | SUBMISSION_ID=$(xcrun notarytool submit "${BUILD_ZIP_PATH}" \ 54 | --apple-id "$APPLE_ID" \ 55 | --team-id "$TEAM_ID" \ 56 | --password "$APP_SPECIFIC_PASSWORD" \ 57 | --output-format json | jq -r '.id') 58 | 59 | while true; do 60 | STATUS=$(xcrun notarytool info "$SUBMISSION_ID" \ 61 | --apple-id "$APPLE_ID" \ 62 | --team-id "$TEAM_ID" \ 63 | --password "$APP_SPECIFIC_PASSWORD" \ 64 | --output-format json | jq -r '.status') 65 | 66 | case $STATUS in 67 | "Accepted") 68 | echo -e "${GREEN}Notarization succeeded!${NC}" 69 | break 70 | ;; 71 | "In Progress") 72 | print_status "Notarization in progress... waiting 30 seconds" 73 | sleep 30 74 | ;; 75 | "Invalid"|"Rejected") 76 | echo "Notarization failed with status: $STATUS" 77 | xcrun notarytool log "$SUBMISSION_ID" \ 78 | --apple-id "$APPLE_ID" \ 79 | --team-id "$TEAM_ID" \ 80 | --password "$APP_SPECIFIC_PASSWORD" 81 | exit 1 82 | ;; 83 | *) 84 | echo "Unknown status: $STATUS" 85 | exit 1 86 | ;; 87 | esac 88 | done 89 | 90 | # Generathing shasums 91 | print_status "Generating shasums..." 92 | for file in "$BUILD_ARTIFACTS_DIRECTORY"/*; do 93 | if [ -f "$file" ] && [[ $(basename "$file") != SHASUMS* ]]; then 94 | shasum -a 256 "$file" | awk '{print $1 " " FILENAME}' FILENAME=$(basename "$file") >> $SHASUMS256_FILE 95 | shasum -a 512 "$file" | awk '{print $1 " " FILENAME}' FILENAME=$(basename "$file") >> $SHASUMS512_FILE 96 | fi 97 | done 98 | -------------------------------------------------------------------------------- /.mise/tasks/cache: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # mise description="Warms the Tuist cache" 3 | 4 | set -euo pipefail 5 | 6 | tuist cache --path $MISE_PROJECT_ROOT -------------------------------------------------------------------------------- /.mise/tasks/docs/build: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # mise description="Dev the documentation" 3 | 4 | set -euo pipefail 5 | 6 | pnpm run -C $MISE_PROJECT_ROOT/docs build 7 | -------------------------------------------------------------------------------- /.mise/tasks/docs/deploy: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # mise description="Deploy the website" 3 | 4 | pnpm run -C $MISE_PROJECT_ROOT/docs deploy 5 | -------------------------------------------------------------------------------- /.mise/tasks/docs/dev: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # mise description="Dev the documentation" 3 | 4 | set -euo pipefail 5 | 6 | pnpm run -C $MISE_PROJECT_ROOT/docs dev -------------------------------------------------------------------------------- /.mise/tasks/encrypt-certificate: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # mise description="Encrypts the certificate" 3 | 4 | set -euo pipefail 5 | 6 | openssl enc -aes-256-cbc -salt -pbkdf2 -in $MISE_PROJECT_ROOT/certificates/certificate.p12 -out $MISE_PROJECT_ROOT/certificates/certificate.p12.enc -pass pass:"$CERTIFICATE_ENCRYPTION_PASSWORD" 7 | -------------------------------------------------------------------------------- /.mise/tasks/install: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # mise description="Installs the project dependencies" 3 | 4 | set -euo pipefail 5 | 6 | if [[ "$(uname)" == "Darwin" ]]; then 7 | tuist install --path $MISE_PROJECT_ROOT 8 | fi 9 | pnpm install -C $MISE_PROJECT_ROOT/docs 10 | -------------------------------------------------------------------------------- /.mise/tasks/lint: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # mise description="Lints the project" 3 | 4 | set -euo pipefail 5 | 6 | swiftformat $MISE_PROJECT_ROOT --lint 7 | swiftlint lint --quiet --config $MISE_PROJECT_ROOT/.swiftlint.yml $MISE_PROJECT_ROOT/Sources 8 | -------------------------------------------------------------------------------- /.mise/tasks/lint-fix: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # mise description = "Lints the project fixing the fixable issues" 3 | set -euo pipefail 4 | 5 | swiftformat $MISE_PROJECT_ROOT 6 | swiftlint lint --fix --quiet --config $MISE_PROJECT_ROOT/.swiftlint.yml $MISE_PROJECT_ROOT/Sources 7 | -------------------------------------------------------------------------------- /.mise/tasks/test: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # mise description="Tests the package using the Tuist" 3 | set -euo pipefail 4 | 5 | tuist test --path $MISE_PROJECT_ROOT -------------------------------------------------------------------------------- /.swiftformat: -------------------------------------------------------------------------------- 1 | # file options 2 | 3 | --symlinks ignore 4 | --disable hoistAwait 5 | --disable hoistTry 6 | --swiftversion 5.7 7 | 8 | # format options 9 | 10 | --allman false 11 | --binarygrouping 4,8 12 | --closingparen balanced 13 | --commas always 14 | --comments indent 15 | --decimalgrouping 3,6 16 | --elseposition same-line 17 | --empty void 18 | --exponentcase lowercase 19 | --exponentgrouping disabled 20 | --extensionacl on-declarations 21 | --fractiongrouping disabled 22 | --header strip 23 | --hexgrouping 4,8 24 | --hexliteralcase uppercase 25 | --ifdef indent 26 | --indent 4 27 | --indentcase false 28 | --importgrouping testable-bottom 29 | --linebreaks lf 30 | --octalgrouping 4,8 31 | --operatorfunc spaced 32 | --patternlet hoist 33 | --ranges spaced 34 | --self remove 35 | --semicolons inline 36 | --stripunusedargs always 37 | --trimwhitespace always 38 | --maxwidth 130 39 | --wraparguments before-first 40 | --wrapcollections before-first 41 | --wrapconditions after-first 42 | --wrapparameters before-first -------------------------------------------------------------------------------- /.swiftlint.yml: -------------------------------------------------------------------------------- 1 | disabled_rules: 2 | - trailing_whitespace 3 | - trailing_comma 4 | - nesting 5 | - cyclomatic_complexity 6 | - file_length 7 | - todo 8 | - function_parameter_count 9 | - opening_brace 10 | - line_length 11 | identifier_name: 12 | min_length: 13 | error: 1 14 | warning: 1 15 | max_length: 16 | warning: 60 17 | error: 80 18 | inclusive_language: 19 | override_allowed_terms: 20 | - masterKey 21 | type_name: 22 | min_length: 23 | error: 1 24 | warning: 1 -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## What's Changed in 0.1.119 2 | * chore(deps): lock file maintenance by @pepicrft in [#144](https://github.com/tuist/virtualOS/pull/144) 3 | * chore(deps): lock file maintenance by @renovate[bot] 4 | * chore(deps): update dependency tuist/filesystem to from: "0.7.2" by @pepicrft in [#149](https://github.com/tuist/virtualOS/pull/149) 5 | * chore(deps): update dependency tuist/filesystem to from: "0.7.2" by @renovate[bot] 6 | * chore(deps): update dependency wrangler to v3.105.1 by @pepicrft in [#147](https://github.com/tuist/virtualOS/pull/147) 7 | * chore(deps): update dependency wrangler to v3.105.1 by @renovate[bot] 8 | * chore(deps): update dependency tuist to v4.40.0 by @pepicrft in [#148](https://github.com/tuist/virtualOS/pull/148) 9 | * chore(deps): update dependency tuist to v4.40.0 by @renovate[bot] 10 | * chore(deps): update dependency pnpm to v9.15.4 by @pepicrft in [#145](https://github.com/tuist/virtualOS/pull/145) 11 | * chore(deps): update dependency pnpm to v9.15.4 by @renovate[bot] 12 | * chore(deps): update dependency node to v22.13.1 by @pepicrft in [#146](https://github.com/tuist/virtualOS/pull/146) 13 | * chore(deps): update dependency node to v22.13.1 by @renovate[bot] 14 | * chore(deps): update dependency vitepress to v1.6.3 by @pepicrft in [#150](https://github.com/tuist/virtualOS/pull/150) 15 | * chore(deps): update dependency vitepress to v1.6.3 by @renovate[bot] 16 | 17 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.118...0.1.119 18 | 19 | ## What's Changed in 0.1.118 20 | * release 0.1.118 by @pepicrft 21 | * Refactor .mise.toml: Change plugin definitions to alias format for asdf integration by @pepicrft 22 | 23 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.117...0.1.118 24 | 25 | ## What's Changed in 0.1.117 26 | * release 0.1.117 by @pepicrft 27 | * Fixes by @pepicrft 28 | * Set up environment and logging infrastructure by @pepicrft in [#142](https://github.com/tuist/virtualOS/pull/142) 29 | * Set up logging by @pepicrft 30 | 31 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.116...0.1.117 32 | 33 | ## What's Changed in 0.1.116 34 | * release 0.1.116 by @renovate[bot] 35 | * chore(deps): update dependency pnpm to v9.15.2 by @renovate[bot] in [#141](https://github.com/tuist/virtualOS/pull/141) 36 | 37 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.115...0.1.116 38 | 39 | ## What's Changed in 0.1.115 40 | * release 0.1.115 by @renovate[bot] 41 | * chore(deps): update dependency apple/swift-service-context to from: "1.1.0" by @renovate[bot] in [#140](https://github.com/tuist/virtualOS/pull/140) 42 | 43 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.114...0.1.115 44 | 45 | ## What's Changed in 0.1.114 46 | * release 0.1.114 by @pepicrft 47 | * Set up default environment and logger instances by @pepicrft in [#139](https://github.com/tuist/virtualOS/pull/139) 48 | * Create VirtualOSEnvironmentInterface by @pepicrft 49 | * Add directories to Environment by @pepicrft 50 | * Add logger setup by @pepicrft 51 | 52 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.113...0.1.114 53 | 54 | ## What's Changed in 0.1.113 55 | * release 0.1.113 by @pepicrft 56 | * chore(deps): update dependency tuist to v4.38.2 by @pepicrft in [#137](https://github.com/tuist/virtualOS/pull/137) 57 | * chore(deps): update dependency tuist to v4.38.2 by @renovate[bot] 58 | * chore(deps): update dependency macos to v14 by @pepicrft in [#138](https://github.com/tuist/virtualOS/pull/138) 59 | * chore(deps): update dependency macos to v14 by @renovate[bot] 60 | 61 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.112...0.1.113 62 | 63 | ## What's Changed in 0.1.112 64 | * release 0.1.112 by @pepicrft 65 | * Add a home page by @pepicrft 66 | 67 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.111...0.1.112 68 | 69 | ## What's Changed in 0.1.111 70 | * release 0.1.111 by @pepicrft 71 | * Expose the GitHub token to prevent hitting 403 with Mise by @pepicrft 72 | * Fix continuous integration by @pepicrft in [#136](https://github.com/tuist/virtualOS/pull/136) 73 | * Run on macOS 15 by @pepicrft 74 | * Adopt the most recent Tuist conventions and fix the compilation by @pepicrft 75 | * Expose GITHUB_TOKEN to prevent 403 errors when we do mise install by @pepicrft 76 | * Update dependency tuist to v4.38.1 by @pepicrft in [#102](https://github.com/tuist/virtualOS/pull/102) 77 | * Update dependency tuist to v4.38.1 by @renovate[bot] 78 | * Update dependency node to v22 by @pepicrft in [#99](https://github.com/tuist/virtualOS/pull/99) 79 | * Update dependency node to v22 by @renovate[bot] 80 | * Update dependency Kolos65/Mockable to from: "0.2.0" by @pepicrft in [#80](https://github.com/tuist/virtualOS/pull/80) 81 | * Update dependency Kolos65/Mockable to from: "0.2.0" by @renovate[bot] 82 | 83 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.110...0.1.111 84 | 85 | ## What's Changed in 0.1.110 86 | * release 0.1.110 by @renovate[bot] 87 | * Lock file maintenance by @renovate[bot] in [#135](https://github.com/tuist/virtualOS/pull/135) 88 | * Update dependency pnpm to v9.15.1 by @renovate[bot] in [#134](https://github.com/tuist/virtualOS/pull/134) 89 | 90 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.109...0.1.110 91 | 92 | ## What's Changed in 0.1.109 93 | * release 0.1.109 by @renovate[bot] 94 | * Update dependency wrangler to v3.99.0 by @renovate[bot] in [#133](https://github.com/tuist/virtualOS/pull/133) 95 | 96 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.108...0.1.109 97 | 98 | ## What's Changed in 0.1.108 99 | * release 0.1.108 by @renovate[bot] 100 | * Update dependency wrangler to v3.98.0 by @renovate[bot] in [#132](https://github.com/tuist/virtualOS/pull/132) 101 | 102 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.107...0.1.108 103 | 104 | ## What's Changed in 0.1.107 105 | * release 0.1.107 by @renovate[bot] 106 | * Update dependency wrangler to v3.97.0 by @renovate[bot] in [#131](https://github.com/tuist/virtualOS/pull/131) 107 | 108 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.106...0.1.107 109 | 110 | ## What's Changed in 0.1.106 111 | * release 0.1.106 by @renovate[bot] 112 | * Update dependency wrangler to v3.96.0 by @renovate[bot] in [#130](https://github.com/tuist/virtualOS/pull/130) 113 | 114 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.105...0.1.106 115 | 116 | ## What's Changed in 0.1.105 117 | * release 0.1.105 by @renovate[bot] 118 | * Lock file maintenance by @renovate[bot] in [#129](https://github.com/tuist/virtualOS/pull/129) 119 | 120 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.104...0.1.105 121 | 122 | ## What's Changed in 0.1.104 123 | * release 0.1.104 by @renovate[bot] 124 | * Update dependency wrangler to v3.95.0 by @renovate[bot] in [#128](https://github.com/tuist/virtualOS/pull/128) 125 | 126 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.103...0.1.104 127 | 128 | ## What's Changed in 0.1.103 129 | * release 0.1.103 by @renovate[bot] 130 | * Update dependency wrangler to v3.94.0 by @renovate[bot] in [#127](https://github.com/tuist/virtualOS/pull/127) 131 | 132 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.102...0.1.103 133 | 134 | ## What's Changed in 0.1.102 135 | * release 0.1.102 by @renovate[bot] 136 | * Lock file maintenance by @renovate[bot] in [#126](https://github.com/tuist/virtualOS/pull/126) 137 | 138 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.101...0.1.102 139 | 140 | ## What's Changed in 0.1.101 141 | * release 0.1.101 by @renovate[bot] 142 | * Update dependency pnpm to v9.15.0 by @renovate[bot] in [#124](https://github.com/tuist/virtualOS/pull/124) 143 | 144 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.100...0.1.101 145 | 146 | ## What's Changed in 0.1.100 147 | * release 0.1.100 by @renovate[bot] 148 | * Update dependency wrangler to v3.93.0 by @renovate[bot] in [#125](https://github.com/tuist/virtualOS/pull/125) 149 | 150 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.99...0.1.100 151 | 152 | ## What's Changed in 0.1.99 153 | * release 0.1.99 by @renovate[bot] 154 | * Update dependency wrangler to v3.92.0 by @renovate[bot] in [#123](https://github.com/tuist/virtualOS/pull/123) 155 | 156 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.98...0.1.99 157 | 158 | ## What's Changed in 0.1.98 159 | * release 0.1.98 by @renovate[bot] 160 | * Update dependency pnpm to v9.14.4 by @renovate[bot] in [#121](https://github.com/tuist/virtualOS/pull/121) 161 | 162 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.97...0.1.98 163 | 164 | ## What's Changed in 0.1.97 165 | * release 0.1.97 by @renovate[bot] 166 | * Lock file maintenance by @renovate[bot] in [#122](https://github.com/tuist/virtualOS/pull/122) 167 | 168 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.96...0.1.97 169 | 170 | ## What's Changed in 0.1.96 171 | * release 0.1.96 by @renovate[bot] 172 | * Update dependency wrangler to v3.91.0 by @renovate[bot] in [#120](https://github.com/tuist/virtualOS/pull/120) 173 | 174 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.95...0.1.96 175 | 176 | ## What's Changed in 0.1.95 177 | * release 0.1.95 by @renovate[bot] 178 | * Lock file maintenance by @renovate[bot] in [#119](https://github.com/tuist/virtualOS/pull/119) 179 | 180 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.94...0.1.95 181 | 182 | ## What's Changed in 0.1.94 183 | * release 0.1.94 by @renovate[bot] 184 | * Update dependency wrangler to v3.90.0 by @renovate[bot] in [#118](https://github.com/tuist/virtualOS/pull/118) 185 | 186 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.93...0.1.94 187 | 188 | ## What's Changed in 0.1.93 189 | * release 0.1.93 by @renovate[bot] 190 | * Update dependency pnpm to v9.14.2 by @renovate[bot] in [#112](https://github.com/tuist/virtualOS/pull/112) 191 | 192 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.92...0.1.93 193 | 194 | ## What's Changed in 0.1.92 195 | * release 0.1.92 by @renovate[bot] 196 | * Update dependency node to v20.18.1 by @renovate[bot] in [#116](https://github.com/tuist/virtualOS/pull/116) 197 | 198 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.91...0.1.92 199 | 200 | ## What's Changed in 0.1.91 201 | * release 0.1.91 by @renovate[bot] 202 | * Update dependency wrangler to v3.89.0 by @renovate[bot] in [#117](https://github.com/tuist/virtualOS/pull/117) 203 | 204 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.90...0.1.91 205 | 206 | ## What's Changed in 0.1.90 207 | * release 0.1.90 by @renovate[bot] 208 | * Update dependency wrangler to v3.88.0 by @renovate[bot] in [#115](https://github.com/tuist/virtualOS/pull/115) 209 | 210 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.89...0.1.90 211 | 212 | ## What's Changed in 0.1.89 213 | * release 0.1.89 by @renovate[bot] 214 | * Lock file maintenance by @renovate[bot] in [#114](https://github.com/tuist/virtualOS/pull/114) 215 | 216 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.88...0.1.89 217 | 218 | ## What's Changed in 0.1.88 219 | * release 0.1.88 by @renovate[bot] 220 | * Update dependency wrangler to v3.87.0 by @renovate[bot] in [#113](https://github.com/tuist/virtualOS/pull/113) 221 | 222 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.87...0.1.88 223 | 224 | ## What's Changed in 0.1.87 225 | * release 0.1.87 by @renovate[bot] 226 | * Update dependency pnpm to v9.13.0 by @renovate[bot] in [#111](https://github.com/tuist/virtualOS/pull/111) 227 | 228 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.86...0.1.87 229 | 230 | ## What's Changed in 0.1.86 231 | * release 0.1.86 by @renovate[bot] 232 | * Update dependency wrangler to v3.86.1 by @renovate[bot] in [#110](https://github.com/tuist/virtualOS/pull/110) 233 | 234 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.85...0.1.86 235 | 236 | ## What's Changed in 0.1.85 237 | * release 0.1.85 by @renovate[bot] 238 | * Lock file maintenance by @renovate[bot] in [#109](https://github.com/tuist/virtualOS/pull/109) 239 | 240 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.84...0.1.85 241 | 242 | ## What's Changed in 0.1.84 243 | * release 0.1.84 by @renovate[bot] 244 | * Update dependency wrangler to v3.86.0 by @renovate[bot] in [#108](https://github.com/tuist/virtualOS/pull/108) 245 | 246 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.83...0.1.84 247 | 248 | ## What's Changed in 0.1.83 249 | * release 0.1.83 by @renovate[bot] 250 | * Update dependency wrangler to v3.85.0 by @renovate[bot] in [#107](https://github.com/tuist/virtualOS/pull/107) 251 | 252 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.82...0.1.83 253 | 254 | ## What's Changed in 0.1.82 255 | * release 0.1.82 by @renovate[bot] 256 | * Update dependency vitepress to v1.5.0 by @renovate[bot] in [#106](https://github.com/tuist/virtualOS/pull/106) 257 | 258 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.81...0.1.82 259 | 260 | ## What's Changed in 0.1.81 261 | * release 0.1.81 by @renovate[bot] 262 | * Lock file maintenance by @renovate[bot] in [#105](https://github.com/tuist/virtualOS/pull/105) 263 | 264 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.80...0.1.81 265 | 266 | ## What's Changed in 0.1.80 267 | * release 0.1.80 by @renovate[bot] 268 | * Update dependency vitepress to v1.4.5 by @renovate[bot] in [#104](https://github.com/tuist/virtualOS/pull/104) 269 | 270 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.79...0.1.80 271 | 272 | ## What's Changed in 0.1.79 273 | * release 0.1.79 by @renovate[bot] 274 | * Update dependency wrangler to v3.84.1 by @renovate[bot] in [#103](https://github.com/tuist/virtualOS/pull/103) 275 | 276 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.78...0.1.79 277 | 278 | ## What's Changed in 0.1.78 279 | * release 0.1.78 by @renovate[bot] 280 | * Update dependency vitepress to v1.4.3 by @renovate[bot] in [#101](https://github.com/tuist/virtualOS/pull/101) 281 | 282 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.77...0.1.78 283 | 284 | ## What's Changed in 0.1.77 285 | * release 0.1.77 by @renovate[bot] 286 | * Update dependency wrangler to v3.84.0 by @renovate[bot] in [#100](https://github.com/tuist/virtualOS/pull/100) 287 | 288 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.76...0.1.77 289 | 290 | ## What's Changed in 0.1.76 291 | * release 0.1.76 by @renovate[bot] 292 | * Update dependency vitepress to v1.4.2 by @renovate[bot] in [#98](https://github.com/tuist/virtualOS/pull/98) 293 | 294 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.75...0.1.76 295 | 296 | ## What's Changed in 0.1.75 297 | * release 0.1.75 by @renovate[bot] 298 | * Update dependency pnpm to v9.12.3 by @renovate[bot] in [#97](https://github.com/tuist/virtualOS/pull/97) 299 | 300 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.74...0.1.75 301 | 302 | ## What's Changed in 0.1.74 303 | * release 0.1.74 by @renovate[bot] 304 | * Lock file maintenance by @renovate[bot] in [#96](https://github.com/tuist/virtualOS/pull/96) 305 | 306 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.73...0.1.74 307 | 308 | ## What's Changed in 0.1.73 309 | * release 0.1.73 by @renovate[bot] 310 | * Update dependency wrangler to v3.83.0 by @renovate[bot] in [#95](https://github.com/tuist/virtualOS/pull/95) 311 | 312 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.72...0.1.73 313 | 314 | ## What's Changed in 0.1.72 315 | * release 0.1.72 by @renovate[bot] 316 | * Update actions/checkout digest to 11bd719 by @renovate[bot] in [#94](https://github.com/tuist/virtualOS/pull/94) 317 | 318 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.71...0.1.72 319 | 320 | ## What's Changed in 0.1.71 321 | * release 0.1.71 by @renovate[bot] 322 | * Update dependency tuist to v4.31.0 by @renovate[bot] in [#93](https://github.com/tuist/virtualOS/pull/93) 323 | 324 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.70...0.1.71 325 | 326 | ## What's Changed in 0.1.70 327 | * release 0.1.70 by @renovate[bot] 328 | * Update dependency wrangler to v3.82.0 by @renovate[bot] in [#92](https://github.com/tuist/virtualOS/pull/92) 329 | 330 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.69...0.1.70 331 | 332 | ## What's Changed in 0.1.69 333 | * release 0.1.69 by @renovate[bot] 334 | * Update dependency wrangler to v3.81.0 by @renovate[bot] in [#91](https://github.com/tuist/virtualOS/pull/91) 335 | 336 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.68...0.1.69 337 | 338 | ## What's Changed in 0.1.68 339 | * release 0.1.68 by @renovate[bot] 340 | * Update dependency vitepress to v1.4.1 by @renovate[bot] in [#87](https://github.com/tuist/virtualOS/pull/87) 341 | 342 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.67...0.1.68 343 | 344 | ## What's Changed in 0.1.67 345 | * release 0.1.67 by @renovate[bot] 346 | * Update dependency tuist to v4.30.0 by @renovate[bot] in [#83](https://github.com/tuist/virtualOS/pull/83) 347 | 348 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.66...0.1.67 349 | 350 | ## What's Changed in 0.1.66 351 | * release 0.1.66 by @renovate[bot] 352 | * Update dependency node to v20.18.0 by @renovate[bot] in [#84](https://github.com/tuist/virtualOS/pull/84) 353 | 354 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.65...0.1.66 355 | 356 | ## What's Changed in 0.1.65 357 | * release 0.1.65 by @renovate[bot] 358 | * Update dependency tuist/path to from: "0.3.8" by @renovate[bot] in [#90](https://github.com/tuist/virtualOS/pull/90) 359 | 360 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.64...0.1.65 361 | 362 | ## What's Changed in 0.1.64 363 | * release 0.1.64 by @renovate[bot] 364 | * Update dependency pnpm to v9.12.2 by @renovate[bot] in [#88](https://github.com/tuist/virtualOS/pull/88) 365 | 366 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.63...0.1.64 367 | 368 | ## What's Changed in 0.1.63 369 | * release 0.1.63 by @renovate[bot] 370 | * Update actions/checkout digest to eef6144 by @renovate[bot] in [#89](https://github.com/tuist/virtualOS/pull/89) 371 | 372 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.62...0.1.63 373 | 374 | ## What's Changed in 0.1.62 375 | * release 0.1.62 by @renovate[bot] 376 | * Update dependency wrangler to v3.80.5 by @renovate[bot] in [#85](https://github.com/tuist/virtualOS/pull/85) 377 | * Implement `virtualos` pull command by @pepicrft in [#26](https://github.com/tuist/virtualOS/pull/26) 378 | * Lint the code changes by @pepicrft 379 | * Start working on the pull command by @pepicrft 380 | 381 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.61...0.1.62 382 | 383 | ## What's Changed in 0.1.61 384 | * release 0.1.61 by @renovate[bot] 385 | * Update dependency pnpm to v9.12.0 by @renovate[bot] in [#82](https://github.com/tuist/virtualOS/pull/82) 386 | 387 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.60...0.1.61 388 | 389 | ## What's Changed in 0.1.60 390 | * release 0.1.60 by @renovate[bot] 391 | * Update dependency wrangler to v3.79.0 by @renovate[bot] in [#81](https://github.com/tuist/virtualOS/pull/81) 392 | 393 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.59...0.1.60 394 | 395 | ## What's Changed in 0.1.59 396 | * release 0.1.59 by @renovate[bot] 397 | * Lock file maintenance by @renovate[bot] in [#79](https://github.com/tuist/virtualOS/pull/79) 398 | 399 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.58...0.1.59 400 | 401 | ## What's Changed in 0.1.58 402 | * release 0.1.58 by @renovate[bot] 403 | * Update dependency wrangler to v3.78.12 by @renovate[bot] in [#78](https://github.com/tuist/virtualOS/pull/78) 404 | 405 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.57...0.1.58 406 | 407 | ## What's Changed in 0.1.57 408 | * release 0.1.57 by @renovate[bot] 409 | * Update dependency wrangler to v3.78.11 by @renovate[bot] in [#77](https://github.com/tuist/virtualOS/pull/77) 410 | * Update dependency tuist to v4.28.1 by @renovate[bot] in [#76](https://github.com/tuist/virtualOS/pull/76) 411 | 412 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.56...0.1.57 413 | 414 | ## What's Changed in 0.1.56 415 | * release 0.1.56 by @renovate[bot] 416 | * Update dependency wrangler to v3.78.10 by @renovate[bot] in [#75](https://github.com/tuist/virtualOS/pull/75) 417 | 418 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.55...0.1.56 419 | 420 | ## What's Changed in 0.1.55 421 | * release 0.1.55 by @renovate[bot] 422 | * Update dependency tuist to v4.28.0 by @renovate[bot] in [#74](https://github.com/tuist/virtualOS/pull/74) 423 | 424 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.54...0.1.55 425 | 426 | ## What's Changed in 0.1.54 427 | * release 0.1.54 by @renovate[bot] 428 | * Update dependency wrangler to v3.78.9 by @renovate[bot] in [#73](https://github.com/tuist/virtualOS/pull/73) 429 | 430 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.53...0.1.54 431 | 432 | ## What's Changed in 0.1.53 433 | * release 0.1.53 by @renovate[bot] 434 | * Update dependency wrangler to v3.78.8 by @renovate[bot] in [#72](https://github.com/tuist/virtualOS/pull/72) 435 | 436 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.52...0.1.53 437 | 438 | ## What's Changed in 0.1.52 439 | * release 0.1.52 by @renovate[bot] 440 | * Lock file maintenance by @renovate[bot] in [#71](https://github.com/tuist/virtualOS/pull/71) 441 | 442 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.51...0.1.52 443 | 444 | ## What's Changed in 0.1.51 445 | * release 0.1.51 by @renovate[bot] 446 | * Update dependency wrangler to v3.78.7 by @renovate[bot] in [#70](https://github.com/tuist/virtualOS/pull/70) 447 | 448 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.50...0.1.51 449 | 450 | ## What's Changed in 0.1.50 451 | * release 0.1.50 by @renovate[bot] 452 | * Update dependency pnpm to v9.11.0 by @renovate[bot] in [#69](https://github.com/tuist/virtualOS/pull/69) 453 | 454 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.49...0.1.50 455 | 456 | ## What's Changed in 0.1.49 457 | * release 0.1.49 by @renovate[bot] 458 | * Update dependency wrangler to v3.78.6 by @renovate[bot] in [#68](https://github.com/tuist/virtualOS/pull/68) 459 | 460 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.48...0.1.49 461 | 462 | ## What's Changed in 0.1.48 463 | * release 0.1.48 by @renovate[bot] 464 | * Update dependency tuist to v4.27.0 by @renovate[bot] in [#67](https://github.com/tuist/virtualOS/pull/67) 465 | 466 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.47...0.1.48 467 | 468 | ## What's Changed in 0.1.47 469 | * release 0.1.47 by @renovate[bot] 470 | * Update dependency wrangler to v3.78.5 by @renovate[bot] in [#66](https://github.com/tuist/virtualOS/pull/66) 471 | 472 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.46...0.1.47 473 | 474 | ## What's Changed in 0.1.46 475 | * release 0.1.46 by @renovate[bot] 476 | * Update dependency wrangler to v3.78.4 by @renovate[bot] in [#65](https://github.com/tuist/virtualOS/pull/65) 477 | 478 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.45...0.1.46 479 | 480 | ## What's Changed in 0.1.45 481 | * release 0.1.45 by @renovate[bot] 482 | * Update dependency wrangler to v3.78.3 by @renovate[bot] in [#64](https://github.com/tuist/virtualOS/pull/64) 483 | 484 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.44...0.1.45 485 | 486 | ## What's Changed in 0.1.44 487 | * release 0.1.44 by @renovate[bot] 488 | * Lock file maintenance by @renovate[bot] in [#63](https://github.com/tuist/virtualOS/pull/63) 489 | 490 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.43...0.1.44 491 | 492 | ## What's Changed in 0.1.43 493 | * release 0.1.43 by @renovate[bot] 494 | * Update dependency wrangler to v3.78.2 by @renovate[bot] in [#62](https://github.com/tuist/virtualOS/pull/62) 495 | 496 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.42...0.1.43 497 | 498 | ## What's Changed in 0.1.42 499 | * release 0.1.42 by @renovate[bot] 500 | * Update dependency wrangler to v3.78.1 by @renovate[bot] in [#61](https://github.com/tuist/virtualOS/pull/61) 501 | 502 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.41...0.1.42 503 | 504 | ## What's Changed in 0.1.41 505 | * release 0.1.41 by @renovate[bot] 506 | * Update dependency wrangler to v3.77.0 by @renovate[bot] in [#60](https://github.com/tuist/virtualOS/pull/60) 507 | 508 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.40...0.1.41 509 | 510 | ## What's Changed in 0.1.40 511 | * release 0.1.40 by @renovate[bot] 512 | * Update dependency wrangler to v3.76.0 by @renovate[bot] in [#59](https://github.com/tuist/virtualOS/pull/59) 513 | 514 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.39...0.1.40 515 | 516 | ## What's Changed in 0.1.39 517 | * release 0.1.39 by @renovate[bot] 518 | * Update dependency pnpm to v9.10.0 by @renovate[bot] in [#58](https://github.com/tuist/virtualOS/pull/58) 519 | 520 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.38...0.1.39 521 | 522 | ## What's Changed in 0.1.38 523 | * release 0.1.38 by @renovate[bot] 524 | * Lock file maintenance by @renovate[bot] in [#57](https://github.com/tuist/virtualOS/pull/57) 525 | 526 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.37...0.1.38 527 | 528 | ## What's Changed in 0.1.37 529 | * release 0.1.37 by @renovate[bot] 530 | * Update dependency wrangler to v3.75.0 by @renovate[bot] in [#56](https://github.com/tuist/virtualOS/pull/56) 531 | 532 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.36...0.1.37 533 | 534 | ## What's Changed in 0.1.36 535 | * release 0.1.36 by @renovate[bot] 536 | * Update dependency wrangler to v3.74.0 by @renovate[bot] in [#55](https://github.com/tuist/virtualOS/pull/55) 537 | 538 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.35...0.1.36 539 | 540 | ## What's Changed in 0.1.35 541 | * release 0.1.35 by @renovate[bot] 542 | * Update dependency tuist to v4.26.0 by @renovate[bot] in [#54](https://github.com/tuist/virtualOS/pull/54) 543 | 544 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.34...0.1.35 545 | 546 | ## What's Changed in 0.1.34 547 | * release 0.1.34 by @renovate[bot] 548 | * Lock file maintenance by @renovate[bot] in [#53](https://github.com/tuist/virtualOS/pull/53) 549 | 550 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.33...0.1.34 551 | 552 | ## What's Changed in 0.1.33 553 | * release 0.1.33 by @renovate[bot] 554 | * Update dependency wrangler to v3.73.0 by @renovate[bot] in [#52](https://github.com/tuist/virtualOS/pull/52) 555 | 556 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.32...0.1.33 557 | 558 | ## What's Changed in 0.1.32 559 | * release 0.1.32 by @renovate[bot] 560 | * Update dependency wrangler to v3.72.3 by @renovate[bot] in [#51](https://github.com/tuist/virtualOS/pull/51) 561 | 562 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.31...0.1.32 563 | 564 | ## What's Changed in 0.1.31 565 | * release 0.1.31 by @renovate[bot] 566 | * Update dependency tuist to v4.25.0 by @renovate[bot] in [#50](https://github.com/tuist/virtualOS/pull/50) 567 | 568 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.30...0.1.31 569 | 570 | ## What's Changed in 0.1.30 571 | * release 0.1.30 by @renovate[bot] 572 | * Update dependency pnpm to v9.9.0 by @renovate[bot] in [#49](https://github.com/tuist/virtualOS/pull/49) 573 | 574 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.29...0.1.30 575 | 576 | ## What's Changed in 0.1.29 577 | * release 0.1.29 by @renovate[bot] 578 | * Lock file maintenance by @renovate[bot] in [#48](https://github.com/tuist/virtualOS/pull/48) 579 | 580 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.28...0.1.29 581 | 582 | ## What's Changed in 0.1.28 583 | * release 0.1.28 by @renovate[bot] 584 | * Update dependency vitepress to v1.3.4 by @renovate[bot] in [#47](https://github.com/tuist/virtualOS/pull/47) 585 | 586 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.27...0.1.28 587 | 588 | ## What's Changed in 0.1.27 589 | * release 0.1.27 by @renovate[bot] 590 | * Update dependency wrangler to v3.72.2 by @renovate[bot] in [#46](https://github.com/tuist/virtualOS/pull/46) 591 | 592 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.26...0.1.27 593 | 594 | ## What's Changed in 0.1.26 595 | * release 0.1.26 by @renovate[bot] 596 | * Update dependency pnpm to v9.8.0 by @renovate[bot] in [#45](https://github.com/tuist/virtualOS/pull/45) 597 | 598 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.25...0.1.26 599 | 600 | ## What's Changed in 0.1.25 601 | * release 0.1.25 by @renovate[bot] 602 | * Update dependency node to v20.17.0 by @renovate[bot] in [#44](https://github.com/tuist/virtualOS/pull/44) 603 | 604 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.24...0.1.25 605 | 606 | ## What's Changed in 0.1.24 607 | * release 0.1.24 by @renovate[bot] 608 | * Update dependency wrangler to v3.72.1 by @renovate[bot] in [#43](https://github.com/tuist/virtualOS/pull/43) 609 | 610 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.23...0.1.24 611 | 612 | ## What's Changed in 0.1.23 613 | * release 0.1.23 by @renovate[bot] 614 | * Update dependency tuist to v4.24.0 by @renovate[bot] in [#42](https://github.com/tuist/virtualOS/pull/42) 615 | 616 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.22...0.1.23 617 | 618 | ## What's Changed in 0.1.22 619 | * release 0.1.22 by @renovate[bot] 620 | * Lock file maintenance by @renovate[bot] in [#41](https://github.com/tuist/virtualOS/pull/41) 621 | 622 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.21...0.1.22 623 | 624 | ## What's Changed in 0.1.21 625 | * release 0.1.21 by @renovate[bot] 626 | * Lock file maintenance by @renovate[bot] in [#40](https://github.com/tuist/virtualOS/pull/40) 627 | 628 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.20...0.1.21 629 | 630 | ## What's Changed in 0.1.20 631 | * release 0.1.20 by @renovate[bot] 632 | * Update dependency vitepress to v1.3.3 by @renovate[bot] in [#39](https://github.com/tuist/virtualOS/pull/39) 633 | 634 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.19...0.1.20 635 | 636 | ## What's Changed in 0.1.19 637 | * release 0.1.19 by @renovate[bot] 638 | * Update dependency wrangler to v3.72.0 by @renovate[bot] in [#38](https://github.com/tuist/virtualOS/pull/38) 639 | 640 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.18...0.1.19 641 | 642 | ## What's Changed in 0.1.18 643 | * release 0.1.18 by @renovate[bot] 644 | * Update dependency pnpm to v9.7.1 by @renovate[bot] in [#37](https://github.com/tuist/virtualOS/pull/37) 645 | 646 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.17...0.1.18 647 | 648 | ## What's Changed in 0.1.17 649 | * release 0.1.17 by @renovate[bot] 650 | * Update dependency wrangler to v3.71.0 by @renovate[bot] in [#36](https://github.com/tuist/virtualOS/pull/36) 651 | 652 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.16...0.1.17 653 | 654 | ## What's Changed in 0.1.16 655 | * release 0.1.16 by @renovate[bot] 656 | * Lock file maintenance by @renovate[bot] in [#35](https://github.com/tuist/virtualOS/pull/35) 657 | 658 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.15...0.1.16 659 | 660 | ## What's Changed in 0.1.15 661 | * release 0.1.15 by @renovate[bot] 662 | * Update dependency wrangler to v3.70.0 by @renovate[bot] in [#34](https://github.com/tuist/virtualOS/pull/34) 663 | 664 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.14...0.1.15 665 | 666 | ## What's Changed in 0.1.14 667 | * release 0.1.14 by @renovate[bot] 668 | * Update dependency pnpm to v9.7.0 by @renovate[bot] in [#33](https://github.com/tuist/virtualOS/pull/33) 669 | 670 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.13...0.1.14 671 | 672 | ## What's Changed in 0.1.13 673 | * release 0.1.13 by @renovate[bot] 674 | * Update dependency wrangler to v3.69.1 by @renovate[bot] in [#32](https://github.com/tuist/virtualOS/pull/32) 675 | 676 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.12...0.1.13 677 | 678 | ## What's Changed in 0.1.12 679 | * release 0.1.12 by @renovate[bot] 680 | * Update dependency vitepress to v1.3.2 by @renovate[bot] in [#31](https://github.com/tuist/virtualOS/pull/31) 681 | 682 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.11...0.1.12 683 | 684 | ## What's Changed in 0.1.11 685 | * release 0.1.11 by @renovate[bot] 686 | * Update dependency tuist to v4.23.0 by @renovate[bot] in [#30](https://github.com/tuist/virtualOS/pull/30) 687 | 688 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.10...0.1.11 689 | 690 | ## What's Changed in 0.1.10 691 | * release 0.1.10 by @renovate[bot] 692 | * Lock file maintenance by @renovate[bot] in [#29](https://github.com/tuist/virtualOS/pull/29) 693 | 694 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.9...0.1.10 695 | 696 | ## What's Changed in 0.1.9 697 | * release 0.1.9 by @renovate[bot] 698 | * Update dependency Kolos65/Mockable to from: "0.0.10" by @renovate[bot] in [#28](https://github.com/tuist/virtualOS/pull/28) 699 | 700 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.8...0.1.9 701 | 702 | ## What's Changed in 0.1.8 703 | * release 0.1.8 by @renovate[bot] 704 | * Update dependency wrangler to v3.68.0 by @renovate[bot] in [#27](https://github.com/tuist/virtualOS/pull/27) 705 | 706 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.7...0.1.8 707 | 708 | ## What's Changed in 0.1.7 709 | * release 0.1.7 by @renovate[bot] 710 | * Update dependency tuist to v4.22.0 by @renovate[bot] in [#25](https://github.com/tuist/virtualOS/pull/25) 711 | 712 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.6...0.1.7 713 | 714 | ## What's Changed in 0.1.6 715 | * release 0.1.6 by @renovate[bot] 716 | * Lock file maintenance by @renovate[bot] in [#24](https://github.com/tuist/virtualOS/pull/24) 717 | 718 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.5...0.1.6 719 | 720 | ## What's Changed in 0.1.5 721 | * release 0.1.5 by @renovate[bot] 722 | * Update dependency wrangler to v3.67.1 by @renovate[bot] in [#23](https://github.com/tuist/virtualOS/pull/23) 723 | 724 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.4...0.1.5 725 | 726 | ## What's Changed in 0.1.4 727 | * release 0.1.4 by @renovate[bot] 728 | * Update dependency wrangler to v3.67.0 by @renovate[bot] in [#22](https://github.com/tuist/virtualOS/pull/22) 729 | 730 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.3...0.1.4 731 | 732 | ## What's Changed in 0.1.3 733 | * release 0.1.3 by @renovate[bot] 734 | * Update dependency node to v20.16.0 by @renovate[bot] in [#21](https://github.com/tuist/virtualOS/pull/21) 735 | 736 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.2...0.1.3 737 | 738 | ## What's Changed in 0.1.2 739 | * release 0.1.2 by @renovate[bot] 740 | * Update dependency wrangler to v3.66.0 by @renovate[bot] in [#20](https://github.com/tuist/virtualOS/pull/20) 741 | 742 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.1...0.1.2 743 | 744 | ## What's Changed in 0.1.1 745 | * release 0.1.1 by @pepicrft 746 | * Read the right value by @pepicrft 747 | * release by @pepicrft 748 | * Auto generate release notes by @pepicrft 749 | * release by @pepicrft 750 | 751 | **Full Changelog**: https://github.com/tuist/virtualOS/compare/0.1.0...0.1.1 752 | 753 | ## What's Changed in 0.1.0 754 | * Add the remote configuration by @pepicrft 755 | * Another attempt by @pepicrft 756 | * Use the right version by @pepicrft 757 | * Use --unreleased by @pepicrft 758 | * Fix by @pepicrft 759 | * Fetch tags by @pepicrft 760 | * Clone the whole history by @pepicrft 761 | * Fix release pipeline by @pepicrft 762 | * Use the GitHub token when using git cliff by @pepicrft 763 | * Fix by @pepicrft 764 | * Fix release pipeline by @pepicrft 765 | * Fix by @pepicrft 766 | * Automate the release by @pepicrft 767 | * Lock file maintenance by @renovate[bot] in [#19](https://github.com/tuist/virtualOS/pull/19) 768 | * Update dependency pnpm to v9.6.0 by @renovate[bot] in [#18](https://github.com/tuist/virtualOS/pull/18) 769 | * Implement bundle workflow by @pepicrft in [#16](https://github.com/tuist/virtualOS/pull/16) 770 | * Set the default keychain by @pepicrft 771 | * Expose the Tuist token to authenticate requests by @pepicrft 772 | * Skip the Xcode selection by @pepicrft 773 | * Implement bundle workflow by @pepicrft 774 | * Create the project by @pepicrft 775 | 776 | 777 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Tuist 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "pins" : [ 3 | { 4 | "identity" : "filesystem", 5 | "kind" : "remoteSourceControl", 6 | "location" : "https://github.com/tuist/FileSystem/", 7 | "state" : { 8 | "revision" : "b2c6c9a68fd7609ca1b7b3e8dd4d2fc76396eac3", 9 | "version" : "0.7.2" 10 | } 11 | }, 12 | { 13 | "identity" : "mockable", 14 | "kind" : "remoteSourceControl", 15 | "location" : "https://github.com/Kolos65/Mockable", 16 | "state" : { 17 | "revision" : "e1b311b01c11415099341eee49769185e965ac4c", 18 | "version" : "0.2.0" 19 | } 20 | }, 21 | { 22 | "identity" : "path", 23 | "kind" : "remoteSourceControl", 24 | "location" : "https://github.com/tuist/path", 25 | "state" : { 26 | "revision" : "7c74ac435e03a927c3a73134c48b61e60221abcb", 27 | "version" : "0.3.8" 28 | } 29 | }, 30 | { 31 | "identity" : "swift-argument-parser", 32 | "kind" : "remoteSourceControl", 33 | "location" : "https://github.com/apple/swift-argument-parser", 34 | "state" : { 35 | "revision" : "41982a3656a71c768319979febd796c6fd111d5c", 36 | "version" : "1.5.0" 37 | } 38 | }, 39 | { 40 | "identity" : "swift-atomics", 41 | "kind" : "remoteSourceControl", 42 | "location" : "https://github.com/apple/swift-atomics.git", 43 | "state" : { 44 | "revision" : "cd142fd2f64be2100422d658e7411e39489da985", 45 | "version" : "1.2.0" 46 | } 47 | }, 48 | { 49 | "identity" : "swift-collections", 50 | "kind" : "remoteSourceControl", 51 | "location" : "https://github.com/apple/swift-collections.git", 52 | "state" : { 53 | "revision" : "671108c96644956dddcd89dd59c203dcdb36cec7", 54 | "version" : "1.1.4" 55 | } 56 | }, 57 | { 58 | "identity" : "swift-log", 59 | "kind" : "remoteSourceControl", 60 | "location" : "https://github.com/apple/swift-log", 61 | "state" : { 62 | "revision" : "96a2f8a0fa41e9e09af4585e2724c4e825410b91", 63 | "version" : "1.6.2" 64 | } 65 | }, 66 | { 67 | "identity" : "swift-log-file", 68 | "kind" : "remoteSourceControl", 69 | "location" : "https://github.com/crspybits/swift-log-file", 70 | "state" : { 71 | "revision" : "aa94b38bf88c7d9cbc87ceafcdffadaffbc2bffa", 72 | "version" : "0.1.0" 73 | } 74 | }, 75 | { 76 | "identity" : "swift-log-oslog", 77 | "kind" : "remoteSourceControl", 78 | "location" : "https://github.com/chrisaljoudi/swift-log-oslog", 79 | "state" : { 80 | "revision" : "176d41d46429e79c806333025b226e0c50a0c602", 81 | "version" : "0.2.2" 82 | } 83 | }, 84 | { 85 | "identity" : "swift-log-testing", 86 | "kind" : "remoteSourceControl", 87 | "location" : "https://github.com/neallester/swift-log-testing", 88 | "state" : { 89 | "revision" : "8459cec10d45da4c566aaec9052fa4a1bef3b861", 90 | "version" : "0.0.1" 91 | } 92 | }, 93 | { 94 | "identity" : "swift-nio", 95 | "kind" : "remoteSourceControl", 96 | "location" : "https://github.com/apple/swift-nio", 97 | "state" : { 98 | "revision" : "ba72f31e11275fc5bf060c966cf6c1f36842a291", 99 | "version" : "2.79.0" 100 | } 101 | }, 102 | { 103 | "identity" : "swift-service-context", 104 | "kind" : "remoteSourceControl", 105 | "location" : "https://github.com/apple/swift-service-context", 106 | "state" : { 107 | "revision" : "0c62c5b4601d6c125050b5c3a97f20cce881d32b", 108 | "version" : "1.1.0" 109 | } 110 | }, 111 | { 112 | "identity" : "swift-syntax", 113 | "kind" : "remoteSourceControl", 114 | "location" : "https://github.com/swiftlang/swift-syntax.git", 115 | "state" : { 116 | "revision" : "0687f71944021d616d34d922343dcef086855920", 117 | "version" : "600.0.1" 118 | } 119 | }, 120 | { 121 | "identity" : "swift-system", 122 | "kind" : "remoteSourceControl", 123 | "location" : "https://github.com/apple/swift-system.git", 124 | "state" : { 125 | "revision" : "c8a44d836fe7913603e246acab7c528c2e780168", 126 | "version" : "1.4.0" 127 | } 128 | }, 129 | { 130 | "identity" : "xcglogger", 131 | "kind" : "remoteSourceControl", 132 | "location" : "https://github.com/DaveWoodCom/XCGLogger.git", 133 | "state" : { 134 | "revision" : "4def3c1c772ca90ad5e7bfc8ac437c3b0b4276cf", 135 | "version" : "7.1.5" 136 | } 137 | }, 138 | { 139 | "identity" : "xctest-dynamic-overlay", 140 | "kind" : "remoteSourceControl", 141 | "location" : "https://github.com/pointfreeco/xctest-dynamic-overlay", 142 | "state" : { 143 | "revision" : "a3f634d1a409c7979cabc0a71b3f26ffa9fc8af1", 144 | "version" : "1.4.3" 145 | } 146 | }, 147 | { 148 | "identity" : "zipfoundation", 149 | "kind" : "remoteSourceControl", 150 | "location" : "https://github.com/weichsel/ZIPFoundation", 151 | "state" : { 152 | "revision" : "02b6abe5f6eef7e3cbd5f247c5cc24e246efcfe0", 153 | "version" : "0.9.19" 154 | } 155 | } 156 | ], 157 | "version" : 2 158 | } 159 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version: 5.8.1 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | @preconcurrency import PackageDescription 5 | 6 | #if TUIST 7 | import ProjectDescription 8 | 9 | let packageSettings = PackageSettings(baseSettings: .settings(base: [ 10 | "SWIFT_STRICT_CONCURRENCY": "complete", 11 | "GENERATE_MASTER_OBJECT_FILE": "YES", 12 | ])) 13 | #endif 14 | 15 | let package = Package( 16 | name: "virtualOS", 17 | dependencies: [ 18 | .package(url: "https://github.com/Kolos65/Mockable", .upToNextMajor(from: "0.2.0")), 19 | .package(url: "https://github.com/apple/swift-argument-parser", .upToNextMajor(from: "1.5.0")), 20 | .package(url: "https://github.com/tuist/path", .upToNextMajor(from: "0.3.8")), 21 | .package(url: "https://github.com/tuist/FileSystem/", .upToNextMajor(from: "0.7.2")), 22 | .package(url: "https://github.com/apple/swift-service-context", .upToNextMajor(from: "1.1.0")), 23 | .package(url: "https://github.com/apple/swift-log", .upToNextMajor(from: "1.6.2")), 24 | .package(url: "https://github.com/chrisaljoudi/swift-log-oslog", .upToNextMajor(from: "0.2.2")), 25 | .package(url: "https://github.com/crspybits/swift-log-file", .upToNextMajor(from: "0.1.0")), 26 | .package(url: "https://github.com/neallester/swift-log-testing", .upToNextMajor(from: "0.0.1")), 27 | ] 28 | ) 29 | -------------------------------------------------------------------------------- /Project.swift: -------------------------------------------------------------------------------- 1 | import ProjectDescription 2 | import ProjectDescriptionHelpers 3 | 4 | let project = Project( 5 | name: "virtualOS", 6 | settings: .settings(base: ["SWIFT_STRICT_CONCURRENCY": "complete"]), 7 | targets: Module.allCases.flatMap(\.targets) 8 | ) 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # virtualOS 2 | 3 | virtualOS is an OCI-compliant virtualization tool for macOS environments. 4 | It builds on Apple's powerful [Virtualization](https://developer.apple.com/documentation/virtualization) framework. 5 | 6 | ## Motivation 7 | 8 | With the [Virtualization](https://developer.apple.com/documentation/virtualization) framework, Apple made virtualization a commodity upon which organizations and businesses could develop their virtualization solutions. However, the framework is a very low-level API, and it requires a lot of work to build a virtualization solution on top of it. VirtualOS aims to provide a high-level API that resembles Docker's API and makes the solution compliant with the [OCI specification](https://github.com/opencontainers/image-spec). We developed it for some of our business products, and we are gifting this piece to the community. 9 | 10 | ## Usage 11 | 12 | ### Installation 13 | 14 | You can install virtualOS using [Mise](https://mise.jdx.dev/): 15 | 16 | ```bash 17 | mise install virtualos 18 | mise use -g virtualos@latest # To activate it globally 19 | ``` 20 | 21 | Alternatively, you can [download the binary from the releases page](https://github.com/tuist/virtualOS/releases). 22 | 23 | ## Development 24 | 25 | ### Using Tuist 26 | 27 | 1. Clone the repository: `git clone https://github.com/tuist/virtualOS.git` 28 | 2. Install system dependencies: `mise install` 29 | 3. Install project dependencies: `mise run install` 30 | 2. Generate the project: `tuist generate` 31 | 32 | ## Documentation 33 | 34 | The documentation is available at [https://virtualos.tuist.dev](https://virtualos.tuist.dev). 35 | -------------------------------------------------------------------------------- /Sources/VirtualOSEnvironment/Environment.swift: -------------------------------------------------------------------------------- 1 | import FileSystem 2 | import Foundation 3 | import Path 4 | import VirtualOSEnvironmentInterface 5 | 6 | public enum EnvironmentError: Error, Equatable, CustomStringConvertible { 7 | case couldntObtainCacheDirectory 8 | case couldntObtainDataDirectory 9 | case couldntObtainConfigDirectory 10 | 11 | public var description: String { 12 | switch self { 13 | case .couldntObtainCacheDirectory: 14 | "We couldn't obtain the cache directory. Make sure either $XDG_CACHE_HOME or $HOME are present in the environment." 15 | case .couldntObtainDataDirectory: 16 | "We couldn't obtain the data directory. Make sure either $XDG_DATA_HOME or $HOME are present in the environment." 17 | case .couldntObtainConfigDirectory: 18 | "We couldn't obtain the config directory. Make sure either $XDG_CONFIG_HOME or $HOME are present in the environment." 19 | } 20 | } 21 | } 22 | 23 | /// Environment represents the environment variable. 24 | public struct Environment: Environmenting { 25 | /// Environment variables of the environment in which virtualOS is running. 26 | public var variables: [String: String] 27 | 28 | /// The current working directory. 29 | public var currentWorkingDirectory: AbsolutePath 30 | 31 | /// The cache directory. 32 | public var cacheDirectory: AbsolutePath 33 | 34 | /// The data directory. 35 | public var dataDirectory: AbsolutePath 36 | 37 | /// The config directory. 38 | public var configDirectory: AbsolutePath 39 | 40 | /// It returns the current environment. 41 | /// - Returns: It should not be used directly, but dependency-injected down from the root of the program. 42 | public static func current() async throws -> Environment { 43 | let variables = ProcessInfo.processInfo.environment 44 | let fileSystem = FileSystem() 45 | let homeDirectory = try variables["HOME"].map { try AbsolutePath(validating: $0) } 46 | 47 | let cacheDirectory = if let xdgCacheHomeDirectory = try variables["XDG_CACHE_HOME"] 48 | .map({ try AbsolutePath(validating: $0) }) ?? homeDirectory?.appending(components: [".cache"]) 49 | { 50 | xdgCacheHomeDirectory.appending(component: "virtualOS") 51 | } else { 52 | throw EnvironmentError.couldntObtainCacheDirectory 53 | } 54 | 55 | let dataDirectory = if let xdgDataHomeDirectory = try variables["XDG_DATA_HOME"] 56 | .map({ try AbsolutePath(validating: $0) }) ?? homeDirectory? 57 | .appending(components: [".local", "share"]) 58 | { 59 | xdgDataHomeDirectory.appending(component: "virtualOS") 60 | } else { 61 | throw EnvironmentError.couldntObtainDataDirectory 62 | } 63 | let configDirectory = if let xdgConfigHomeDirectory = try variables["XDG_CONFIG_HOME"] 64 | .map({ try AbsolutePath(validating: $0) }) ?? homeDirectory?.appending(components: [".config"]) 65 | { 66 | xdgConfigHomeDirectory.appending(component: "virtualOS") 67 | } else { 68 | throw EnvironmentError.couldntObtainConfigDirectory 69 | } 70 | 71 | return Environment( 72 | variables: variables, 73 | currentWorkingDirectory: try await fileSystem.currentWorkingDirectory(), 74 | cacheDirectory: cacheDirectory, 75 | dataDirectory: dataDirectory, 76 | configDirectory: configDirectory 77 | ) 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /Sources/VirtualOSEnvironmentInterface/Environmenting.swift: -------------------------------------------------------------------------------- 1 | import Path 2 | 3 | public protocol Environmenting: Sendable { 4 | /// The environment variables. 5 | var variables: [String: String] { get } 6 | 7 | /// The current working directory. 8 | var currentWorkingDirectory: AbsolutePath { get } 9 | 10 | /// The directory where virtualOS should store cache files. 11 | var cacheDirectory: AbsolutePath { get } 12 | 13 | /// The directory where virtualOS should store data files. 14 | var dataDirectory: AbsolutePath { get } 15 | 16 | /// The directory where virtualOS should store configuration files. 17 | var configDirectory: AbsolutePath { get } 18 | } 19 | -------------------------------------------------------------------------------- /Sources/VirtualOSEnvironmentInterface/ServiceContext+Environment.swift: -------------------------------------------------------------------------------- 1 | import ServiceContextModule 2 | 3 | enum EnvironmentKey: Sendable, ServiceContextKey { 4 | typealias Value = Environmenting 5 | } 6 | 7 | extension ServiceContext { 8 | public var environment: Environmenting? { 9 | get { 10 | self[EnvironmentKey.self] 11 | } 12 | set { 13 | self[EnvironmentKey.self] = newValue 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Sources/VirtualOSLogging/Logger.swift: -------------------------------------------------------------------------------- 1 | import FileLogging 2 | import Foundation 3 | import Logging 4 | import LoggingOSLog 5 | import Path 6 | import ServiceContextModule 7 | 8 | enum LoggerKey: ServiceContextKey { 9 | typealias Value = Logger 10 | } 11 | 12 | extension ServiceContext { 13 | public var logger: Logger? { 14 | get { 15 | self[LoggerKey.self] 16 | } 17 | set { 18 | self[LoggerKey.self] = newValue 19 | } 20 | } 21 | } 22 | 23 | extension Logger { 24 | /// Creates an instance of the default logger. 25 | /// - Parameter logFilePath: The file where file logs should be stored. 26 | /// - Returns: An instance of `Logger`. 27 | public static func makeDefaultLogger(logFilePath: AbsolutePath) -> Logger { 28 | Logger(label: "dev.tuist.virtualos") { label in 29 | MultiplexLogHandler([ 30 | // swiftlint:disable:next force_try 31 | try! FileLogHandler(label: label, localFile: URL(fileURLWithPath: logFilePath.pathString)), 32 | LoggingOSLog(label: label), 33 | ]) 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Sources/VirtualOSNetwork/VirtualOSNetwork.swift: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Sources/VirtualOSNetworkInterface/NetworkInterface.swift: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Sources/VirtualOSOCI/VirtualOSOCI.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import VirtualOSOCIInterface 3 | -------------------------------------------------------------------------------- /Sources/VirtualOSOCIInterface/OCIContentDescriptor.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | /// Content descriptors, or simply descriptors, declare references between the components 4 | /// in the Merkle Directed Acyclic Graph (DAG). 5 | public struct OCIContentDescriptor: Codable { 6 | /// Describes the media type of the referenced content. 7 | /// The value must complain with [RFC6838](https://tools.ietf.org/html/rfc6838) 8 | public var mediaType: String 9 | 10 | /// It represents the digest of the targeted content. 11 | /// Any retrieved content from untrusted sources should be verified against this digest. 12 | public var digest: String 13 | 14 | /// Specifies the size in bytes of the raw content. 15 | /// The client should use this to check the size before doing further validations like digest validation. 16 | public var size: Int64 17 | 18 | /// Specifies a list of URLs from where the referred content might be downloaded. 19 | /// URLs must conform to [RFC3986](https://tools.ietf.org/html/rfc3986) and should use 20 | /// either the `http` or the `https` schemes. 21 | public var urls: [URL]? 22 | 23 | /// Contains arbitrary metadata. 24 | public var annotations: [String: String]? 25 | 26 | /// Contains an embedded representation of the referenced content. 27 | /// The value must conform to the [Base 64](https://tools.ietf.org/html/rfc4648#section-4) encoding. 28 | public var data: String? 29 | 30 | /// Contains the type of an artifact when the descriptor points to an artifact. 31 | /// This is the value of the config descriptor `mediaType` when the descriptor references an image manifest. 32 | /// The value must conform to [RFC6838](https://tools.ietf.org/html/rfc6838) 33 | public var artifactType: String? 34 | } 35 | -------------------------------------------------------------------------------- /Sources/VirtualOSOCIInterface/OCIImage.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | /// Defines the [OCI Image Schema](https://github.com/opencontainers/image-spec/blob/main/manifest.md) in Swift. 4 | public struct OCIImage: Codable { 5 | /// Specifies the manifest schema version. 6 | /// It must be 2 to ensure backward compatible with older Docker versions. 7 | public var schemaVersion: Int 8 | 9 | /// It contains the media type `application/vnd.oci.image.manifest.v1+json` 10 | public var mediaType: String 11 | 12 | /// Contains the artifact type when the manifest is used as an artifact. 13 | public var artifactType: String? 14 | 15 | /// References a configuration object for a container, by digest. 16 | /// Some important notes: 17 | /// - The referenced content should not be parsed if this media type is unknown and instead considered the referenced 18 | /// content as arbitrary binary data (e.g., `application/octet-stream`). The implementations should support at least 19 | /// `application/vnd.oci.image.config.v1+json`. 20 | /// 21 | public var config: OCIContentDescriptor 22 | 23 | /// It contains the image layers. For portability, layers should contain at least one item. 24 | /// - When `config.mediaType` is `application/vnd.oci.image.config.v1+json`: 25 | /// - The array must have the base layer at index 0. 26 | /// - Subsequent layers must follow in stack order. 27 | /// - The final filesystem layout must match the result of applying the layers to an empty directory. 28 | /// - The ownership, mode, and other attributes of the initial empty directory are unspecified. 29 | /// - The `mediaType` of layers must support at least one of the following types. 30 | /// - `application/vnd.oci.image.layer.v1.tar` 31 | /// - `application/vnd.oci.image.layer.v1.tar+gzip` 32 | /// - `application/vnd.oci.image.layer.nondistributable.v1.tar` 33 | /// - `application/vnd.oci.image.layer.nondistributable.v1.tar+gzip` 34 | public var layers: [OCIContentDescriptor] 35 | 36 | /// Specifies a descriptor of another manifest. 37 | /// It defines a weak association to a separate Merkle Directed Acyclic Graph (DAG), 38 | /// and is used by the referrers API to include this manifest in the list of responses for the subject digest. 39 | public var subject: OCIContentDescriptor? 40 | 41 | /// Contains arbitrary metadata for the image manifest. 42 | public var annotations: [String: String]? 43 | } 44 | -------------------------------------------------------------------------------- /Sources/VirtualOSPull/PullCommand.swift: -------------------------------------------------------------------------------- 1 | import ArgumentParser 2 | import Logging 3 | import ServiceContextModule 4 | import VirtualOSLogging 5 | 6 | /** 7 | This command is responsible from pulling images from remote registries. 8 | - **Docker reference:** https://docs.docker.com/reference/cli/docker/image/pull/ 9 | */ 10 | public struct PullCommand: AsyncParsableCommand { 11 | public static let configuration = CommandConfiguration( 12 | commandName: "pull", 13 | abstract: "Pulls an image from the registry" 14 | ) 15 | 16 | @Flag(help: "Suppress verbose output.") 17 | var insecure: Bool = false 18 | 19 | @Argument(help: "The identifier of the image to pull") 20 | var image: String 21 | 22 | public init() {} 23 | 24 | public func run() async throws { 25 | ServiceContext.current?.logger?.info("Pulling images") 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Sources/VirtualOSPull/PullService.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | protocol PullServicing {} 4 | -------------------------------------------------------------------------------- /Sources/VirtualOSPullInterface/VirtualOSPullInterface.swift: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Sources/VirtualOSPushInterface/VirtualOSPushInterface.swift: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Sources/VirtualOSRun/RunCommand.swift: -------------------------------------------------------------------------------- 1 | import ArgumentParser 2 | 3 | /** 4 | This command is responsible from pulling images from remote registries. 5 | - **Docker reference:** https://docs.docker.com/reference/cli/docker/image/run/ 6 | */ 7 | public struct RunCommand: AsyncParsableCommand { 8 | public static var configuration: CommandConfiguration = .init( 9 | commandName: "run", 10 | abstract: "Runs an image" 11 | ) 12 | 13 | public init() {} 14 | 15 | @Argument(help: "The phrase to repeat.") 16 | public var image: String 17 | 18 | public func run() async throws {} 19 | } 20 | -------------------------------------------------------------------------------- /Sources/VirtualOSRunInterface/VirtualOSRunInterface.swift: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Sources/VirtualOSStorage/Storage.swift: -------------------------------------------------------------------------------- 1 | import Path 2 | import VirtualOSStorageInterface 3 | 4 | struct Storage: Storaging { 5 | func images(cacheDirectory _: AbsolutePath) async throws -> [VirtualOSStorageInterface.Image] { 6 | [] 7 | } 8 | 9 | private func imagesDirectory(cacheDirectory: AbsolutePath) -> AbsolutePath { 10 | cacheDirectory.appending(component: "images") 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Sources/VirtualOSStorageInterface/Image.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | public struct Image {} 4 | -------------------------------------------------------------------------------- /Sources/VirtualOSStorageInterface/Storaging.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import Path 3 | 4 | public protocol Storaging { 5 | func images(cacheDirectory: AbsolutePath) async throws -> [Image] 6 | } 7 | -------------------------------------------------------------------------------- /Sources/virtualos/VirtualOS.swift: -------------------------------------------------------------------------------- 1 | import ArgumentParser 2 | import FileSystem 3 | import Foundation 4 | import Logging 5 | import Path 6 | import ServiceContextModule 7 | import VirtualOSEnvironment 8 | import VirtualOSEnvironmentInterface 9 | import VirtualOSLogging 10 | 11 | @main 12 | private enum VirtualOS { 13 | static func main() async throws { 14 | let fileSystem = FileSystem() 15 | let environment = try await Environment.current() 16 | let logFilePath = environment.cacheDirectory.appending(components: ["logs", "\(UUID().uuidString).log"]) 17 | if try await !fileSystem.exists(logFilePath.parentDirectory) { 18 | try await fileSystem.makeDirectory(at: logFilePath.parentDirectory) 19 | } 20 | let logger = Logger.makeDefaultLogger(logFilePath: logFilePath) 21 | var serviceContext = ServiceContext.topLevel 22 | serviceContext.logger = logger 23 | serviceContext.environment = environment 24 | 25 | await ServiceContext.$current.withValue(serviceContext) { 26 | defer { 27 | showCompletion(logFilePath: logFilePath) 28 | } 29 | 30 | do { 31 | var command = try VirtualOSCommand.parseAsRoot() 32 | if var asyncCommand = command as? AsyncParsableCommand { 33 | try await asyncCommand.run() 34 | } else { 35 | try command.run() 36 | } 37 | } catch { 38 | showCompletion(logFilePath: logFilePath) 39 | VirtualOSCommand.exit(withError: error) 40 | } 41 | } 42 | } 43 | 44 | private static func showCompletion(logFilePath: AbsolutePath) { 45 | if !CommandLine.arguments.contains("--help"), !CommandLine.arguments.contains("-h") { 46 | print("Logs available at: \(logFilePath.pathString)") 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Sources/virtualos/VirtualOSCommand.swift: -------------------------------------------------------------------------------- 1 | import ArgumentParser 2 | import Foundation 3 | import VirtualOSPull 4 | import VirtualOSRun 5 | 6 | struct VirtualOSCommand: AsyncParsableCommand { 7 | static let configuration = CommandConfiguration( 8 | commandName: "virtualos", 9 | abstract: "Virtualized macOS environments", 10 | subcommands: [PullCommand.self, RunCommand.self] 11 | ) 12 | } 13 | -------------------------------------------------------------------------------- /Tests/VirtualOSEnvironmentTests/VirtualOSEnvironmentTests.swift: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuist/virtualOS/7d0919db5d510bceb7b808289ca9aab432cab7d6/Tests/VirtualOSEnvironmentTests/VirtualOSEnvironmentTests.swift -------------------------------------------------------------------------------- /Tests/VirtualOSLoggingTests/LoggerTests.swift: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuist/virtualOS/7d0919db5d510bceb7b808289ca9aab432cab7d6/Tests/VirtualOSLoggingTests/LoggerTests.swift -------------------------------------------------------------------------------- /Tests/VirtualOSNetworkTests/VirtualOSNetworkTests.swift: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuist/virtualOS/7d0919db5d510bceb7b808289ca9aab432cab7d6/Tests/VirtualOSNetworkTests/VirtualOSNetworkTests.swift -------------------------------------------------------------------------------- /Tests/VirtualOSOCITests/VirtualOSOCITests.swift: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuist/virtualOS/7d0919db5d510bceb7b808289ca9aab432cab7d6/Tests/VirtualOSOCITests/VirtualOSOCITests.swift -------------------------------------------------------------------------------- /Tests/VirtualOSPullTests/VirtualOSPullTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | @testable import VirtualOSPull 3 | 4 | final class VirtualOSPullTests: XCTestCase { 5 | func testExample() throws { 6 | // XCTest Documentation 7 | // https://developer.apple.com/documentation/xctest 8 | 9 | // Defining Test Cases and Test Methods 10 | // https://developer.apple.com/documentation/xctest/defining_test_cases_and_test_methods 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Tests/VirtualOSRunTests/VirtualOSRunTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | @testable import VirtualOSRun 3 | 4 | final class VirtualOSRunTests: XCTestCase { 5 | func testExample() throws { 6 | // XCTest Documentation 7 | // https://developer.apple.com/documentation/xctest 8 | 9 | // Defining Test Cases and Test Methods 10 | // https://developer.apple.com/documentation/xctest/defining_test_cases_and_test_methods 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Tests/VirtualOSStorageTests/VirtualOSStorageTests.swift: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuist/virtualOS/7d0919db5d510bceb7b808289ca9aab432cab7d6/Tests/VirtualOSStorageTests/VirtualOSStorageTests.swift -------------------------------------------------------------------------------- /Tuist.swift: -------------------------------------------------------------------------------- 1 | import ProjectDescription 2 | 3 | let tuist = Tuist(fullHandle: "tuist/virtualos") 4 | -------------------------------------------------------------------------------- /Tuist/ProjectDescriptionHelpers/Module.swift: -------------------------------------------------------------------------------- 1 | import ProjectDescription 2 | 3 | public enum Module: CaseIterable { 4 | case virtualos 5 | case pull 6 | case run 7 | case network 8 | case oci 9 | case storage 10 | case environment 11 | case logging 12 | 13 | public var targetName: String { 14 | switch self { 15 | case .virtualos: "virtualos" 16 | case .pull: "VirtualOSPull" 17 | case .run: "VirtualOSRun" 18 | case .network: "VirtualOSNetwork" 19 | case .oci: "VirtualOSOCI" 20 | case .storage: "VirtualOSStorage" 21 | case .environment: "VirtualOSEnvironment" 22 | case .logging: "VirtualOSLogging" 23 | } 24 | } 25 | 26 | public var product: Product { 27 | switch self { 28 | case .virtualos: 29 | return .commandLineTool 30 | case .pull, .run, .network, .oci, .storage, .environment, .logging: 31 | return .staticLibrary 32 | } 33 | } 34 | 35 | public var destination: Destination { 36 | .mac 37 | } 38 | 39 | public var interfaceTargetName: String? { 40 | switch self { 41 | case .virtualos, .logging: 42 | return nil 43 | case .pull, .run, .network, .oci, .storage, .environment: 44 | return "\(targetName)Interface" 45 | } 46 | } 47 | 48 | public var dependencies: [TargetDependency] { 49 | switch self { 50 | case .virtualos: return [ 51 | .target(name: Module.pull.targetName), 52 | .target(name: Module.run.targetName), 53 | .target(name: Module.logging.targetName), 54 | .target(name: Module.environment.targetName), 55 | .target(name: Module.environment.interfaceTargetName!), 56 | .external(name: "ServiceContextModule"), 57 | .external(name: "ArgumentParser"), 58 | .external(name: "Logging"), 59 | .external(name: "Path"), 60 | .external(name: "FileSystem"), 61 | ] 62 | case .pull: return [ 63 | .target(name: Module.logging.targetName), 64 | .external(name: "ArgumentParser"), 65 | .external(name: "Path"), 66 | .external(name: "ServiceContextModule"), 67 | .external(name: "Logging"), 68 | ] 69 | case .run: return [ 70 | .external(name: "ArgumentParser"), 71 | .external(name: "Path"), 72 | ] 73 | case .network, .oci, .storage: 74 | return [ 75 | .external(name: "Path"), 76 | ] 77 | case .environment: 78 | return [ 79 | .external(name: "Path"), 80 | .external(name: "ServiceContextModule"), 81 | .external(name: "FileSystem"), 82 | ] 83 | case .logging: 84 | return [ 85 | .external(name: "ServiceContextModule"), 86 | .external(name: "Logging"), 87 | .external(name: "LoggingOSLog"), 88 | .external(name: "FileLogging"), 89 | .external(name: "Path"), 90 | ] 91 | } 92 | } 93 | 94 | public var bundleId: String { 95 | "io.tuist.\(targetName)" 96 | } 97 | 98 | public func sources(targetName: String) -> SourceFilesList { 99 | [ 100 | "Sources/\(targetName)/**/*.swift", 101 | ] 102 | } 103 | 104 | public func testSources(targetName: String) -> SourceFilesList { 105 | [ 106 | "Tests/\(targetName)Tests/**/*.swift", 107 | ] 108 | } 109 | 110 | var testsTargetName: String? { 111 | switch self { 112 | case .virtualos: 113 | return nil 114 | case .pull, .run, .oci, .storage, .network, .environment, .logging: 115 | return "\(targetName)Tests" 116 | } 117 | } 118 | 119 | public var targets: [Target] { 120 | var targets: [Target] = [] 121 | 122 | if let interfaceTargetName { 123 | targets.append(.target( 124 | name: interfaceTargetName, 125 | destinations: Set(arrayLiteral: destination), 126 | product: product, 127 | bundleId: "\(bundleId).interface", 128 | deploymentTargets: .macOS("13.0.0"), 129 | sources: sources(targetName: interfaceTargetName), 130 | dependencies: dependencies + [.external(name: "Mockable")], 131 | settings: .settings(configurations: [ 132 | .debug(name: .debug, settings: [:]), 133 | .release(name: .release, settings: [:]), 134 | ]) 135 | )) 136 | } 137 | 138 | targets.append(.target( 139 | name: targetName, 140 | destinations: Set(arrayLiteral: destination), 141 | product: product, 142 | bundleId: bundleId, 143 | deploymentTargets: .macOS("13.0.0"), 144 | sources: sources(targetName: targetName), 145 | dependencies: dependencies + [.external(name: "Mockable")] + 146 | (interfaceTargetName != nil ? [.target(name: interfaceTargetName!)] : []), 147 | settings: .settings(configurations: [ 148 | // This is important to exclude the mock implementations from release builds 149 | .debug(name: .debug, settings: ["SWIFT_ACTIVE_COMPILATION_CONDITIONS": "$(inherited) MOCKING"]), 150 | .release(name: .release, settings: [:]), 151 | ]) 152 | )) 153 | 154 | if let testsTargetName { 155 | targets.append(.target( 156 | name: testsTargetName, 157 | destinations: Set(arrayLiteral: destination), 158 | product: .unitTests, 159 | bundleId: bundleId, 160 | deploymentTargets: .macOS("13.0.0"), 161 | sources: testSources(targetName: targetName), 162 | dependencies: dependencies + [.xctest, .target(name: targetName)] 163 | )) 164 | } 165 | return targets 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /assets/logo.svg: -------------------------------------------------------------------------------- 1 | 20 | -------------------------------------------------------------------------------- /certificates/certificate.p12.enc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuist/virtualOS/7d0919db5d510bceb7b808289ca9aab432cab7d6/certificates/certificate.p12.enc -------------------------------------------------------------------------------- /cliff.toml: -------------------------------------------------------------------------------- 1 | # git-cliff ~ configuration file 2 | # https://git-cliff.org/docs/configuration 3 | 4 | [bump] 5 | initial_tag = "0.1.0" 6 | 7 | [remote.github] 8 | owner = "tuist" 9 | repo = "virtualOS" 10 | 11 | [changelog] 12 | # template for the changelog body 13 | # https://keats.github.io/tera/docs/#introduction 14 | body = """ 15 | ## What's Changed 16 | 17 | {%- if version %} in {{ version }}{%- endif -%} 18 | {% for commit in commits %} 19 | {% if commit.github.pr_title -%} 20 | {%- set commit_message = commit.github.pr_title -%} 21 | {%- else -%} 22 | {%- set commit_message = commit.message -%} 23 | {%- endif -%} 24 | * {{ commit_message | split(pat="\n") | first | trim }}\ 25 | {% if commit.github.username %} by @{{ commit.github.username }}{%- endif -%} 26 | {% if commit.github.pr_number %} in \ 27 | [#{{ commit.github.pr_number }}]({{ self::remote_url() }}/pull/{{ commit.github.pr_number }}) \ 28 | {%- endif %} 29 | {%- endfor -%} 30 | 31 | {%- if github -%} 32 | {% if github.contributors | filter(attribute="is_first_time", value=true) | length != 0 %} 33 | {% raw %}\n{% endraw -%} 34 | ## New Contributors 35 | {%- endif %}\ 36 | {% for contributor in github.contributors | filter(attribute="is_first_time", value=true) %} 37 | * @{{ contributor.username }} made their first contribution 38 | {%- if contributor.pr_number %} in \ 39 | [#{{ contributor.pr_number }}]({{ self::remote_url() }}/pull/{{ contributor.pr_number }}) \ 40 | {%- endif %} 41 | {%- endfor -%} 42 | {%- endif -%} 43 | 44 | {% if version %} 45 | {% if previous.version %} 46 | **Full Changelog**: {{ self::remote_url() }}/compare/{{ previous.version }}...{{ version }} 47 | {% endif %} 48 | {% else -%} 49 | {% raw %}\n{% endraw %} 50 | {% endif %} 51 | 52 | {%- macro remote_url() -%} 53 | https://github.com/{{ remote.github.owner }}/{{ remote.github.repo }} 54 | {%- endmacro -%} 55 | """ 56 | # remove the leading and trailing whitespace from the template 57 | trim = true 58 | # changelog footer 59 | footer = """ 60 | 61 | """ 62 | # postprocessors 63 | postprocessors = [] 64 | 65 | [git] 66 | # parse the commits based on https://www.conventionalcommits.org 67 | conventional_commits = false 68 | # filter out the commits that are not conventional 69 | filter_unconventional = true 70 | # process each line of a commit as an individual commit 71 | split_commits = false 72 | # regex for preprocessing the commit messages 73 | commit_preprocessors = [ 74 | # remove issue numbers from commits 75 | { pattern = '\((\w+\s)?#([0-9]+)\)', replace = "" }, 76 | ] 77 | # protect breaking changes from being skipped due to matching a skipping commit_parser 78 | protect_breaking_commits = false 79 | # filter out the commits that are not matched by commit parsers 80 | filter_commits = true 81 | # regex for matching git tags 82 | tag_pattern = "[0-9].*" 83 | # regex for skipping tags 84 | skip_tags = "beta|alpha" 85 | # regex for ignoring tags 86 | ignore_tags = "rc" 87 | # sort the tags topologically 88 | topo_order = false 89 | # sort the commits inside sections by oldest/newest order 90 | sort_commits = "newest" 91 | -------------------------------------------------------------------------------- /docs/.vitepress/config.mjs: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vitepress"; 2 | import { atom01Icon } from "./icons.mjs"; 3 | 4 | // https://vitepress.dev/reference/site-config 5 | export default defineConfig({ 6 | title: "virtualOS", 7 | titleTemplate: ":title | virtualOS", 8 | srcDir: "content", 9 | lastUpdated: true, 10 | description: "A virtualization CLI for macOS environments", 11 | cleanUrls: true, 12 | sitemap: { 13 | hostname: "https://virtualos.tuist.dev", 14 | }, 15 | head: [ 16 | [ 17 | "meta", 18 | { property: "og:url", content: "https://virtualos.tuist.dev" }, 19 | "", 20 | ], 21 | ["meta", { property: "og:type", content: "website" }, ""], 22 | [ 23 | "meta", 24 | { property: "og:image", content: "https://virtualos.tuist.dev/og.jpeg" }, 25 | "", 26 | ], 27 | ["meta", { name: "twitter:card", content: "summary" }, ""], 28 | [ 29 | "meta", 30 | { property: "twitter:domain", content: "virtualos.tuist.dev" }, 31 | "", 32 | ], 33 | [ 34 | "meta", 35 | { property: "twitter:url", content: "https://virtualos.tuist.dev" }, 36 | "", 37 | ], 38 | [ 39 | "meta", 40 | { 41 | name: "twitter:image", 42 | content: "https://virtualos.tuist.dev/og.jpeg", 43 | }, 44 | "", 45 | ], 46 | ], 47 | themeConfig: { 48 | logo: "/logo.png", 49 | editLink: { 50 | pattern: "https://github.com/tuist/virtualos/edit/main/docs/:path", 51 | }, 52 | nav: [ 53 | { text: "Tuist", link: "https://tuist.dev" }, 54 | { text: "Community", link: "https://community.tuist.dev" }, 55 | { text: "Slack", link: "https://slack.tuist.dev" }, 56 | ], 57 | search: { 58 | provider: "local", 59 | }, 60 | sidebar: [ 61 | { 62 | text: `