├── .editorconfig ├── .github ├── FUNDING.yml └── workflows │ ├── build-nanoutimes.yml │ ├── build-sample-app.yml │ ├── test.yml │ └── update_dist.yml ├── .gitignore ├── .idea ├── caches │ └── deviceStreaming.xml ├── misc.xml ├── modules.xml ├── vcs.xml └── xcode-cache.iml ├── .node-version ├── CHANGELOG.md ├── LICENSE ├── README.md ├── action.yml ├── dist ├── lib ├── main │ ├── index.js │ ├── index.js.map │ ├── licenses.txt │ └── sourcemap-register.js └── post │ ├── index.js │ ├── index.js.map │ ├── licenses.txt │ └── sourcemap-register.js ├── lib ├── node-v115-darwin-arm64 │ └── nanoutimes.node ├── node-v115-darwin-x64 │ └── nanoutimes.node ├── node-v120-darwin-arm64 │ └── nanoutimes.node ├── node-v93-darwin-arm64 │ └── nanoutimes.node └── node-v93-darwin-x64 │ └── nanoutimes.node ├── package-lock.json ├── package.json ├── renovate.json ├── sample └── MyApp │ ├── Localizable.strings │ ├── MyApp.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── swiftpm │ │ └── Package.resolved │ ├── MyApp │ ├── Assets.xcassets │ │ ├── AccentColor.colorset │ │ │ └── Contents.json │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ ├── Contents.json │ │ └── sample.imageset │ │ │ ├── Contents.json │ │ │ └── sample.png │ ├── ContentView.swift │ ├── Model.xcdatamodeld │ │ └── Model.xcdatamodel │ │ │ └── contents │ ├── MyAppApp.swift │ ├── Preview Content │ │ └── Preview Assets.xcassets │ │ │ └── Contents.json │ ├── PropertyList.plist │ ├── Storyboard.storyboard │ └── View.xib │ ├── MyLibrary │ └── MyLibrary.swift │ └── Settings.bundle │ ├── Root.plist │ └── en.lproj │ └── Root.strings ├── src ├── input.ts ├── json.ts ├── main.ts ├── post.ts └── util.ts ├── test └── input.json └── tsconfig.json /.editorconfig: -------------------------------------------------------------------------------- 1 | [*.ts] 2 | indent_style = space 3 | indent_size = 2 4 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: irgaly 2 | custom: ["https://github.com/irgaly/irgaly"] 3 | -------------------------------------------------------------------------------- /.github/workflows/build-nanoutimes.yml: -------------------------------------------------------------------------------- 1 | name: Build nanoutimes node binding 2 | 3 | on: push 4 | 5 | jobs: 6 | build: 7 | runs-on: macos-latest 8 | steps: 9 | - uses: actions/checkout@v4 10 | with: 11 | repository: josepharhar/nanoutimes 12 | - uses: actions/setup-node@v4 13 | with: 14 | node-version: 22.14.0 15 | - id: artifact-name 16 | run: | 17 | echo "name=$(node -p '`node-v${process.versions.modules}-darwin-${os.arch()}`')" >> "$GITHUB_OUTPUT" 18 | - run: | 19 | npm install -g node-gyp 20 | node-gyp configure && node-gyp build 21 | mkdir -p "artifact/${{ steps.artifact-name.outputs.name }}" 22 | mv build/Release/nanoutimes.node "artifact/${{ steps.artifact-name.outputs.name }}" 23 | - uses: actions/upload-artifact@v4 24 | with: 25 | name: ${{ steps.artifact-name.outputs.name }} 26 | path: artifact 27 | -------------------------------------------------------------------------------- /.github/workflows/build-sample-app.yml: -------------------------------------------------------------------------------- 1 | name: Build Sample Xcode iOS Application for demonstration 2 | 3 | on: 4 | push: 5 | 6 | permissions: 7 | actions: write 8 | 9 | jobs: 10 | build-sample-app: 11 | runs-on: macos-latest 12 | steps: 13 | - uses: actions/checkout@v4 14 | - uses: maxim-lobanov/setup-xcode@v1 15 | with: 16 | xcode-version: latest-stable 17 | - uses: ruby/setup-ruby@v1 18 | with: 19 | ruby-version: '3.2.0' 20 | - uses: irgaly/xcode-cache@main 21 | with: 22 | key: xcode-cache-deriveddata-${{ github.workflow }}-${{ github.sha }} 23 | restore-keys: xcode-cache-deriveddata-${{ github.workflow }}- 24 | delete-used-deriveddata-cache: true 25 | verbose: true 26 | - run: gem install fastlane 27 | - shell: bash -xeu {0} 28 | run: | 29 | cd sample/MyApp 30 | fastlane gym --project MyApp.xcodeproj --scheme MyApp --disable_package_automatic_updates --skip_codesigning --skip_archive 31 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | on: 4 | push: 5 | 6 | jobs: 7 | build-test: 8 | runs-on: macos-latest 9 | steps: 10 | - uses: actions/checkout@v4 11 | - uses: actions/setup-node@v4 12 | with: 13 | cache: npm 14 | - run: npm install 15 | - shell: bash -xeu {0} 16 | run: npm run build 17 | -------------------------------------------------------------------------------- /.github/workflows/update_dist.yml: -------------------------------------------------------------------------------- 1 | name: Build distributions & commit dist 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | permissions: 9 | contents: write 10 | 11 | concurrency: 12 | group: ${{ github.workflow }}-${{ github.ref }} 13 | cancel-in-progress: true 14 | 15 | jobs: 16 | update-dist: 17 | runs-on: ubuntu-latest 18 | steps: 19 | - uses: actions/checkout@v4 20 | - uses: actions/setup-node@v4 21 | with: 22 | cache: npm 23 | - run: npm install 24 | - shell: bash -xeu {0} 25 | run: npm run build 26 | - uses: crazy-max/ghaction-import-gpg@v6 27 | id: gpg 28 | with: 29 | gpg_private_key: ${{ secrets.SIGNING_PGP_KEY }} 30 | passphrase: ${{ secrets.SIGNING_PGP_PASSWORD }} 31 | git_config_global: true 32 | git_user_signingkey: true 33 | git_commit_gpgsign: true 34 | - name: Commit changes 35 | env: 36 | GIT_AUTHOR_NAME: irgaly 37 | GIT_AUTHOR_EMAIL: ${{ steps.gpg.outputs.email }} 38 | GIT_COMMITTER_NAME: irgaly 39 | GIT_COMMITTER_EMAIL: ${{ steps.gpg.outputs.email }} 40 | shell: bash +e {0} 41 | run: | 42 | git commit -am "Update dist" && git push origin HEAD 43 | exit 0 44 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.toptal.com/developers/gitignore/api/node,intellij,xcode 2 | # Edit at https://www.toptal.com/developers/gitignore?templates=node,intellij,xcode 3 | 4 | ### Intellij ### 5 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider 6 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 7 | 8 | # User-specific stuff 9 | .idea/**/workspace.xml 10 | .idea/**/tasks.xml 11 | .idea/**/usage.statistics.xml 12 | .idea/**/dictionaries 13 | .idea/**/shelf 14 | 15 | # AWS User-specific 16 | .idea/**/aws.xml 17 | 18 | # Generated files 19 | .idea/**/contentModel.xml 20 | 21 | # Sensitive or high-churn files 22 | .idea/**/dataSources/ 23 | .idea/**/dataSources.ids 24 | .idea/**/dataSources.local.xml 25 | .idea/**/sqlDataSources.xml 26 | .idea/**/dynamic.xml 27 | .idea/**/uiDesigner.xml 28 | .idea/**/dbnavigator.xml 29 | 30 | # Gradle 31 | .idea/**/gradle.xml 32 | .idea/**/libraries 33 | 34 | # Gradle and Maven with auto-import 35 | # When using Gradle or Maven with auto-import, you should exclude module files, 36 | # since they will be recreated, and may cause churn. Uncomment if using 37 | # auto-import. 38 | .idea/artifacts 39 | .idea/compiler.xml 40 | .idea/jarRepositories.xml 41 | .idea/modules.xml 42 | .idea/*.iml 43 | .idea/modules 44 | *.iml 45 | *.ipr 46 | 47 | # CMake 48 | cmake-build-*/ 49 | 50 | # Mongo Explorer plugin 51 | .idea/**/mongoSettings.xml 52 | 53 | # File-based project format 54 | *.iws 55 | 56 | # IntelliJ 57 | out/ 58 | 59 | # mpeltonen/sbt-idea plugin 60 | .idea_modules/ 61 | 62 | # JIRA plugin 63 | atlassian-ide-plugin.xml 64 | 65 | # Cursive Clojure plugin 66 | .idea/replstate.xml 67 | 68 | # SonarLint plugin 69 | .idea/sonarlint/ 70 | 71 | # Crashlytics plugin (for Android Studio and IntelliJ) 72 | com_crashlytics_export_strings.xml 73 | crashlytics.properties 74 | crashlytics-build.properties 75 | fabric.properties 76 | 77 | # Editor-based Rest Client 78 | .idea/httpRequests 79 | 80 | # Android studio 3.1+ serialized cache file 81 | .idea/caches/build_file_checksums.ser 82 | 83 | ### Intellij Patch ### 84 | # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 85 | 86 | # *.iml 87 | # modules.xml 88 | # .idea/misc.xml 89 | # *.ipr 90 | 91 | # Sonarlint plugin 92 | # https://plugins.jetbrains.com/plugin/7973-sonarlint 93 | .idea/**/sonarlint/ 94 | 95 | # SonarQube Plugin 96 | # https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin 97 | .idea/**/sonarIssues.xml 98 | 99 | # Markdown Navigator plugin 100 | # https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced 101 | .idea/**/markdown-navigator.xml 102 | .idea/**/markdown-navigator-enh.xml 103 | .idea/**/markdown-navigator/ 104 | 105 | # Cache file creation bug 106 | # See https://youtrack.jetbrains.com/issue/JBR-2257 107 | .idea/$CACHE_FILE$ 108 | 109 | # CodeStream plugin 110 | # https://plugins.jetbrains.com/plugin/12206-codestream 111 | .idea/codestream.xml 112 | 113 | # Azure Toolkit for IntelliJ plugin 114 | # https://plugins.jetbrains.com/plugin/8053-azure-toolkit-for-intellij 115 | .idea/**/azureSettings.xml 116 | 117 | ### Node ### 118 | # Logs 119 | logs 120 | *.log 121 | npm-debug.log* 122 | yarn-debug.log* 123 | yarn-error.log* 124 | lerna-debug.log* 125 | .pnpm-debug.log* 126 | 127 | # Diagnostic reports (https://nodejs.org/api/report.html) 128 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 129 | 130 | # Runtime data 131 | pids 132 | *.pid 133 | *.seed 134 | *.pid.lock 135 | 136 | # Directory for instrumented libs generated by jscoverage/JSCover 137 | lib-cov 138 | 139 | # Coverage directory used by tools like istanbul 140 | coverage 141 | *.lcov 142 | 143 | # nyc test coverage 144 | .nyc_output 145 | 146 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 147 | .grunt 148 | 149 | # Bower dependency directory (https://bower.io/) 150 | bower_components 151 | 152 | # node-waf configuration 153 | .lock-wscript 154 | 155 | # Compiled binary addons (https://nodejs.org/api/addons.html) 156 | build/Release 157 | 158 | # Dependency directories 159 | node_modules/ 160 | jspm_packages/ 161 | 162 | # Snowpack dependency directory (https://snowpack.dev/) 163 | web_modules/ 164 | 165 | # TypeScript cache 166 | *.tsbuildinfo 167 | 168 | # Optional npm cache directory 169 | .npm 170 | 171 | # Optional eslint cache 172 | .eslintcache 173 | 174 | # Optional stylelint cache 175 | .stylelintcache 176 | 177 | # Microbundle cache 178 | .rpt2_cache/ 179 | .rts2_cache_cjs/ 180 | .rts2_cache_es/ 181 | .rts2_cache_umd/ 182 | 183 | # Optional REPL history 184 | .node_repl_history 185 | 186 | # Output of 'npm pack' 187 | *.tgz 188 | 189 | # Yarn Integrity file 190 | .yarn-integrity 191 | 192 | # dotenv environment variable files 193 | .env 194 | .env.development.local 195 | .env.test.local 196 | .env.production.local 197 | .env.local 198 | 199 | # parcel-bundler cache (https://parceljs.org/) 200 | .cache 201 | .parcel-cache 202 | 203 | # Next.js build output 204 | .next 205 | out 206 | 207 | # Nuxt.js build / generate output 208 | .nuxt 209 | #dist 210 | 211 | # Gatsby files 212 | .cache/ 213 | # Comment in the public line in if your project uses Gatsby and not Next.js 214 | # https://nextjs.org/blog/next-9-1#public-directory-support 215 | # public 216 | 217 | # vuepress build output 218 | .vuepress/dist 219 | 220 | # vuepress v2.x temp and cache directory 221 | .temp 222 | 223 | # Docusaurus cache and generated files 224 | .docusaurus 225 | 226 | # Serverless directories 227 | .serverless/ 228 | 229 | # FuseBox cache 230 | .fusebox/ 231 | 232 | # DynamoDB Local files 233 | .dynamodb/ 234 | 235 | # TernJS port file 236 | .tern-port 237 | 238 | # Stores VSCode versions used for testing VSCode extensions 239 | .vscode-test 240 | 241 | # yarn v2 242 | .yarn/cache 243 | .yarn/unplugged 244 | .yarn/build-state.yml 245 | .yarn/install-state.gz 246 | .pnp.* 247 | 248 | ### Node Patch ### 249 | # Serverless Webpack directories 250 | .webpack/ 251 | 252 | # Optional stylelint cache 253 | 254 | # SvelteKit build / generate output 255 | .svelte-kit 256 | 257 | ### Xcode ### 258 | ## User settings 259 | xcuserdata/ 260 | 261 | ## Xcode 8 and earlier 262 | *.xcscmblueprint 263 | *.xccheckout 264 | 265 | ### Xcode Patch ### 266 | *.xcodeproj/* 267 | !*.xcodeproj/project.pbxproj 268 | !*.xcodeproj/xcshareddata/ 269 | !*.xcodeproj/project.xcworkspace/ 270 | !*.xcworkspace/contents.xcworkspacedata 271 | /*.gcno 272 | **/xcshareddata/WorkspaceSettings.xcsettings 273 | 274 | # End of https://www.toptal.com/developers/gitignore/api/node,intellij,xcode 275 | -------------------------------------------------------------------------------- /.idea/caches/deviceStreaming.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 606 | 607 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/xcode-cache.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.node-version: -------------------------------------------------------------------------------- 1 | 20.12.1 2 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # v1.9.0 - 2025/4/20 JST 2 | 3 | * update `@actions/cache` v4 [#78](https://github.com/irgaly/xcode-cache/pull/78) 4 | 5 | # v1.8.1 - 2024/11/20 JST 6 | 7 | #### Maintenance 8 | 9 | * update `@actions/cache`, `@actions/core` [#72](https://github.com/irgaly/xcode-cache/pull/72) 10 | * handle uncaughtException in post job [#73](https://github.com/irgaly/xcode-cache/pull/73) 11 | 12 | # v1.8.0 - 2024/10/02 JST 13 | 14 | #### Improve 15 | 16 | * add cache-read-only feature [#63](https://github.com/irgaly/xcode-cache/pull/63) 17 | * refactor: cacheReadOnly condition [#68](https://github.com/irgaly/xcode-cache/pull/68) 18 | * Add *.xcstrings to default mtime targets [#69](https://github.com/irgaly/xcode-cache/pull/69) 19 | 20 | #### Maintenance 21 | 22 | * CI: update dist on ubuntu-latest [#60](https://github.com/irgaly/xcode-cache/pull/60) 23 | * fix error message typo [#67](https://github.com/irgaly/xcode-cache/pull/67) 24 | 25 | # v1.7.2 - 2024/04/06 JST 26 | 27 | #### Maintenance 28 | 29 | * update node 20.12.1 [#58](https://github.com/irgaly/xcode-cache/pull/58) 30 | * Support GitHub Actions node20 runtime 31 | 32 | # v1.7.1 - 2023/12/01 JST 33 | 34 | #### Fix 35 | 36 | * Fix deleting cache API's 404 error handling [#50](https://github.com/irgaly/xcode-cache/pull/50) 37 | 38 | # v1.7.0 - 2023/12/01 JST 39 | 40 | #### Improve 41 | 42 | * add output: restored-key, 43 | swiftpm-restored-key [#46](https://github.com/irgaly/xcode-cache/pull/46) 44 | * add node-v120-darwin-arm64/nanoutimes.node [#47](https://github.com/irgaly/xcode-cache/pull/47) 45 | * add delete-used-deriveddata-cache feature [#48](https://github.com/irgaly/xcode-cache/pull/48) 46 | 47 | # v1.6.0 - 2023/11/16 JST 48 | 49 | #### Improve 50 | 51 | * add node-v93-darwin-arm64/nanoutimes.node [#44](https://github.com/irgaly/xcode-cache/pull/44) 52 | * Support GitHub Actions M1 Mac (macos-13-xlarge) 53 | 54 | # v1.5.0 - 2023/10/05 JST 55 | 56 | #### Improve 57 | 58 | * add timestamp to logging [#41](https://github.com/irgaly/xcode-cache/pull/41) 59 | 60 | # v1.4.0 - 2023/10/05 JST 61 | 62 | #### Improve 63 | 64 | * add set-output restored / swiftpm-restored [#39](https://github.com/irgaly/xcode-cache/pull/39) 65 | 66 | # v1.3.0 - 2023/09/29 JST 67 | 68 | #### Improve 69 | 70 | * Add default targets: `**/*.xcassets/**/*` [#37](https://github.com/irgaly/xcode-cache/pull/37) 71 | 72 | # v1.2.0 - 2023/09/28 JST 73 | 74 | #### Improve 75 | 76 | * Add default targets: .intentdefinition [#35](https://github.com/irgaly/xcode-cache/pull/35) 77 | 78 | # v1.1.0 - 2023/09/27 JST 79 | 80 | #### Improve 81 | 82 | * Add default targets: .json, .xcframework, .framework [#34](https://github.com/irgaly/xcode-cache/pull/34) 83 | 84 | # v1.0.0 - 2023/09/15 JST 85 | 86 | Initial release. 87 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2023 irgaly 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | https://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # xcode-cache 2 | 3 | A GitHub Action to store Xcode's Build Cache for incremental build on CI. 4 | 5 | * This action caches: 6 | * `DerivedData` 7 | * That contains Xcode's Build Cache. 8 | * `SourcePackages` 9 | * That contains SwiftPM cloned repositories. 10 | * Your source code's `modified time` (mtime) 11 | 12 | # Usage 13 | 14 | Use this action in GitHub Actions workflow. 15 | 16 | ```yaml 17 | - uses: actions/checkout@v4 18 | ... 19 | - uses: irgaly/xcode-cache@v1 20 | with: 21 | key: xcode-cache-deriveddata-${{ github.workflow }}-${{ github.sha }} 22 | restore-keys: xcode-cache-deriveddata-${{ github.workflow }}- 23 | ... 24 | - name: (Your build step) 25 | run: | 26 | fastlane ... 27 | ``` 28 | 29 | Xcode's DerivedData is used for incremental build, so it's recommended to use `github.sha` in cache 30 | key. 31 | 32 | # Configuration examples 33 | 34 | ## Custom DerivedData and SourcePackages locations 35 | 36 | ```yaml 37 | - uses: irgaly/xcode-cache@v1 38 | with: 39 | key: xcode-cache-deriveddata-${{ github.workflow }}-${{ github.sha }} 40 | restore-keys: xcode-cache-deriveddata-${{ github.workflow }}- 41 | deriveddata-directory: DerivedData 42 | sourcepackages-directory: SourcePackages 43 | ... 44 | ``` 45 | 46 | ## Store all project file's mtime attributes 47 | 48 | ```yaml 49 | - uses: irgaly/xcode-cache@v1 50 | with: 51 | key: xcode-cache-deriveddata-${{ github.workflow }}-${{ github.sha }} 52 | restore-keys: xcode-cache-deriveddata-${{ github.workflow }}- 53 | restore-mtime-targets: | 54 | YourApp/**/* 55 | ... 56 | ``` 57 | 58 | ## Use custom cache key for SourcePackages cache 59 | 60 | The cache key of SourcePackages is default 61 | to `irgaly/xcode-cache-sourcepackages-${{ hashFiles('.../Package.resolved') }}`. 62 | You can specify your custom key. 63 | 64 | ```yaml 65 | - uses: irgaly/xcode-cache@v1 66 | with: 67 | key: xcode-cache-deriveddata-${{ github.workflow }}-${{ github.sha }} 68 | restore-keys: xcode-cache-deriveddata-${{ github.workflow }}- 69 | swiftpm-cache-key: your-soucepackages-${{ hashFiles('your/path/to/Package.resolved') }} 70 | swiftpm-cache-restore-keys: | 71 | your-custom-restore-keys-here-... 72 | ... 73 | ``` 74 | 75 | # Platform 76 | 77 | This action is for only macOS runner. 78 | 79 | # Caching details 80 | 81 | This action caches below entries. 82 | 83 | ## DerivedData 84 | 85 | The DerivedData directory has all of intermediates build output files such as compiled objects. 86 | 87 | A DerivedData directory that is default to `~/Library/Developer/Xcode/DerivedData` or specified 88 | by `deriveddata-directory` input. 89 | 90 | This directory will be cached with nanosecond resolution mtime 91 | by [@actions/cache](https://github.com/actions/toolkit/). 92 | 93 | ## SourcePackages 94 | 95 | The SourcePackages directory has clones of SwiftPM if you used SwiftPM dependencies with Xcode. 96 | 97 | A SourcePackages directory that is default 98 | to `~/Library/Developer/Xcode/DerivedData/{App name}-{ID}/SourcePackages` or specified 99 | by `sourcepackages-directory` input. 100 | 101 | This directory will be cached with nanosecond resolution mtime 102 | by [@actions/cache](https://github.com/actions/toolkit/). 103 | 104 | ## Source Code's mtime attributes 105 | 106 | Xcode stores build input file's mtime information with **nanosecond resolution** to DerivedData. 107 | So, on CI environment, it's required to restore all input file's mtime from previous build after 108 | checkout sources. 109 | 110 | This action will store input file's mtime attributes and their SHA-256 hash 111 | to `(DerivedData directory)/xcode-cache-mtime.json`. 112 | 113 | Then this action will restore their mtime attributes if their SHA-256 are same after checkout 114 | sources. 115 | 116 | For example, `xcode-cache-mtime.json`'s contents will be: 117 | 118 | ```json 119 | [ 120 | { 121 | "path": "sample/MyApp/MyApp/ContentView.swift", 122 | "time": "1694751978.570357000", 123 | "sha256": "a1a6707fc09625c0a5f49c3b8127da42358085506bbe2246469f00c0a7a2276b" 124 | }, 125 | { 126 | "path": "sample/MyApp/MyApp/MyAppApp.swift", 127 | "time": "1694751978.543212000", 128 | "sha256": "0b97d516fc64a2ec833b9eefe769d658947c66cc528ada637ac916da7b87f5bc" 129 | }, 130 | ... 131 | ] 132 | ``` 133 | 134 | ### Default target file's to store mtime attributes 135 | 136 | If `use-default-mtime-targets` is set to true (default), 137 | this action will store these file's mtime attributes: 138 | 139 | * `**/*.swift` 140 | * `**/*.xib` 141 | * `**/*.storyboard` 142 | * `**/*.strings` 143 | * `**/*.xcstrings` 144 | * `**/*.plist` 145 | * `**/*.intentdefinition` 146 | * `**/*.json` 147 | * `**/*.xcassets` 148 | * `**/*.xcassets/**/*` 149 | * `**/*.bundle` 150 | * `**/*.bundle/**/*` 151 | * `**/*.xcdatamodel` 152 | * `**/*.xcdatamodel/**/*` 153 | * `**/*.framework`, 154 | * `**/*.framework/**/*`, 155 | * `**/*.xcframework`, 156 | * `**/*.xcframework/**/*`, 157 | * `**/*.m` 158 | * `**/*.mm` 159 | * `**/*.h` 160 | * `**/*.c` 161 | * `**/*.cc` 162 | * `**/*.cpp` 163 | * `**/*.hpp` 164 | * `**/*.hxx` 165 | 166 | You can add any target by glob pattern with `restore-mtime-targets` input. 167 | 168 | # Delete old incremental build cache when job succeeded 169 | 170 | If `delete-used-deriveddata-cache: true` is configured, xcode-cache will delete old DerivedData 171 | cache from GitHub Actions Cache Storage. 172 | This will help you to manage your repository's Cache Storage space. 173 | 174 | This operation will use GitHub Actions API for deleting cache. 175 | **Be sure `actions: write` has granted to your token.** 176 | 177 | * [REST API | GitHub Actions Cache](https://docs.github.com/en/rest/actions/cache?apiVersion=2022-11-28#delete-github-actions-caches-for-a-repository-using-a-cache-key) 178 | * [GitHub Actions | Assigning permissions to jobs](https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs) 179 | 180 | Please see the official document of GitHub Actions Cache management for more details. 181 | 182 | * [GitHub Docs | Caching dependencies to speed up workflows | Force deleting cache entries](https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#force-deleting-cache-entries) 183 | 184 | # All Options 185 | 186 | ```yaml 187 | - uses: irgaly/xcode-cache@v1 188 | with: 189 | # Cache key for DerivedData cache 190 | # 191 | # required 192 | key: { your derived data key } 193 | 194 | # Restore keys for DerivedData cache 195 | # 196 | # optional, multiline 197 | # dofault: empty 198 | restore-keys: | 199 | {your derived data restore keys} 200 | 201 | # DerivedData directory path 202 | # 203 | # optional 204 | # default: ~/Library/Developer/Xcode/DerivedData 205 | deriveddata-directory: { your DerivedData directory path } 206 | 207 | # SourcePackages directory path 208 | # 209 | # optional, multiline 210 | # default: {DerivedDirectory path}/SourcePackages 211 | sourcepackages-directory: { your SourcePackages directory path } 212 | 213 | # Target file glob patterns to store mtime attributes 214 | # This glob pattern is applied with GitHub Actions toolkit glob option implicitDescendants = false 215 | # 216 | # optional, multiline 217 | # default: empty 218 | restore-mtime-targets: | 219 | your/target/**/* 220 | 221 | # Xcode's Package.resolved file path glob patterns 222 | # Package.resolved file is used for swiftpm-cache-key if it is not specified 223 | # 224 | # optional, multiline 225 | # default: 226 | # **/*.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved 227 | # **/*.xcworkspace/xcshareddata/swiftpm/Package.resolved 228 | swiftpm-package-resolved-file: | 229 | YourApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved 230 | 231 | # Cache key for SourcePackages 232 | # 233 | # optional 234 | # default: irgaly/xcode-cache-sourcepackages-${{ hashFiles( {swiftpm-package-resolved-file} ) }}' 235 | swiftpm-cache-key: { your SourcePackages cache key } 236 | 237 | # Cache restore keys for SourcePackages 238 | # 239 | # optional 240 | # default: empty 241 | swiftpm-cache-restore-keys: 242 | 243 | # Use default target file glob patterns to store mtime attributes 244 | # 245 | # optional 246 | # default: true 247 | use-default-mtime-targets: true 248 | 249 | # Delete the DerivedData cache that used for this build, 250 | # only when this job has succeeded, the cache has hit from `restore-keys` and 251 | # the Cache belongs to same branch from this job. 252 | # 253 | # actions: write permission is required for your token to use this feature. 254 | # 255 | # Cache will be deleted by GitHub Actions API 256 | # https://docs.github.com/en/rest/actions/cache?apiVersion=2022-11-28#delete-github-actions-caches-for-a-repository-using-a-cache-key 257 | # 258 | # optional 259 | # default: false 260 | delete-used-deriveddata-cache: false 261 | 262 | # The GitHub Token for deleting DerivedData cache 263 | # This is used to access GitHub Actions Cache API 264 | # 265 | # optional 266 | # default: ${{ github.token }} 267 | token: ${{ github.token }} 268 | 269 | # More detailed logging 270 | # 271 | # optional 272 | # default: false 273 | verbose: false 274 | 275 | # Cache read-only mode 276 | # If true, the action will only read from the cache and not write to it 277 | # 278 | # optional 279 | # default: false 280 | cache-read-only: false 281 | ``` 282 | 283 | # Outputs 284 | 285 | This action 286 | provides 287 | some [step outputs](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-output-parameter). 288 | 289 | For example, you can use these values by `${{ steps.{step id}.outputs.restored }}` 290 | 291 | | key | value | 292 | |------------------------|------------------------------------------------------------------------------------------------------------------------------| 293 | | `restored` | `true`: DerivedData restored from cache (includes restore-keys hit) / `false`: DerivedData cache not hit | 294 | | `restored-key` | The key of DerivedData cache hit. This will not set when cache has not hit. | 295 | | `swiftpm-restored` | `true`: SourcePackages restored from cache (includes swiftpm-cache-restore-keys hit) / `false`: SourcePackages cache not hit | 296 | | `swiftpm-restored-key` | The key of SourcePackages cache hit. This will not set when cache has not hit. | 297 | 298 | # Appendix 299 | 300 | ## Ruby one-liner for restoring mtimes 301 | 302 | This is a ruby one-liner for restoring mtimes from `xcode-cache-mtime.json`. 303 | You may use this one-liner if you'd like to restore at any time you want in GitHub Actions workflow 304 | step. 305 | 306 | ```shell 307 | % ruby -rjson -rdigest -rbigdecimal -e 'JSON.parse(STDIN.read).each{|i|f=i["path"];t=BigDecimal(i["time"]);File.utime(t,t,f)if(File.exist?(f)&&(File.directory?(f)?Digest::SHA256.new.yield_self{|s|Dir.children(f).sort.each{s.update(_1)};s.hexdigest}:Digest::SHA256.file(f).hexdigest)==i["sha256"])}' < DerivedData/xcode-cache-mtime.json 308 | ``` 309 | -------------------------------------------------------------------------------- /action.yml: -------------------------------------------------------------------------------- 1 | name: 'Xcode Cache' 2 | description: 'Cache Xcode''s DerivedData for incremental build.' 3 | author: 'irgaly' 4 | branding: 5 | icon: 'zap' 6 | color: 'blue' 7 | inputs: 8 | key: 9 | description: 'cache key for DerivedData' 10 | required: true 11 | restore-keys: 12 | description: 'cache restore keys for DerivedData.' 13 | required: false 14 | default: '' 15 | deriveddata-directory: 16 | description: 'a directory of project''s DerivedData. default: ~/Library/Developer/Xcode/DerivedData' 17 | required: false 18 | default: '' 19 | sourcepackages-directory: 20 | description: 'a directory of SourcePackages. default: {deriveddata-directory}/SourcePackages' 21 | required: false 22 | default: '' 23 | restore-mtime-targets: 24 | description: 'the targets glob pattern of restoring mtime. exclude pattern ''!{pattern}'' can be used. This glob pattern is applied with GitHub action toolkit glob option implicitDescendants = false' 25 | required: false 26 | default: '' 27 | swiftpm-package-resolved-file: 28 | description: 'Xcode''s Package.resolved file path glob pattern. default: **/*.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved , **/*.xcworkspace/xcshareddata/swiftpm/Package.resolved' 29 | required: false 30 | default: '' 31 | swiftpm-cache-key: 32 | description: 'cache key for SourcePackages. default: irgaly/xcode-cache-sourcepackages-{hashFiles({resolvedFiles})}' 33 | required: false 34 | default: '' 35 | swiftpm-cache-restore-keys: 36 | description: 'cache restore keys for SourcePackages' 37 | required: false 38 | default: '' 39 | use-default-mtime-targets: 40 | description: 'process default mtime targets: **/*.swift , **/*.xib , **/*.storyboard , **/*.strings , **/*.xcstrings, **/*.plist , **/*.xcassets , **/*.xcassets/**/* , **/*.bundle , **/*.bundle/**/*, **/*.xcdatamodel , **/*.xcdatamodel/**/* , **/*.framework , **/*.framework/**/* , **/*.xcframework , **/*.xcframework/**/* , **/*.m , **/*.mm , **/*.h , **/*.c , **/*.cc , **/*.cpp , **/*.hpp , **/*.hxx' 41 | required: false 42 | default: 'true' 43 | delete-used-deriveddata-cache: 44 | description: 'delete the DerivedData cache used for this job, when job has succeeded.' 45 | required: false 46 | default: 'false' 47 | token: 48 | description: 'an GitHub Token for deleting the DerivedData operation. default: github.token' 49 | required: false 50 | default: ${{ github.token }} 51 | verbose: 52 | description: 'enable verbose logging' 53 | required: false 54 | default: 'false' 55 | cache-read-only: 56 | description: 'When true, existing entries will be read from the cache but no entries will be written.' 57 | required: false 58 | default: 'false' 59 | runs: 60 | using: 'node20' 61 | main: 'dist/main/index.js' 62 | post: 'dist/post/index.js' 63 | post-if: success() 64 | -------------------------------------------------------------------------------- /dist/lib: -------------------------------------------------------------------------------- 1 | ../lib -------------------------------------------------------------------------------- /dist/main/sourcemap-register.js: -------------------------------------------------------------------------------- 1 | (()=>{var e={650:e=>{var r=Object.prototype.toString;var n=typeof Buffer.alloc==="function"&&typeof Buffer.allocUnsafe==="function"&&typeof Buffer.from==="function";function isArrayBuffer(e){return r.call(e).slice(8,-1)==="ArrayBuffer"}function fromArrayBuffer(e,r,t){r>>>=0;var o=e.byteLength-r;if(o<0){throw new RangeError("'offset' is out of bounds")}if(t===undefined){t=o}else{t>>>=0;if(t>o){throw new RangeError("'length' is out of bounds")}}return n?Buffer.from(e.slice(r,r+t)):new Buffer(new Uint8Array(e.slice(r,r+t)))}function fromString(e,r){if(typeof r!=="string"||r===""){r="utf8"}if(!Buffer.isEncoding(r)){throw new TypeError('"encoding" must be a valid string encoding')}return n?Buffer.from(e,r):new Buffer(e,r)}function bufferFrom(e,r,t){if(typeof e==="number"){throw new TypeError('"value" argument must not be a number')}if(isArrayBuffer(e)){return fromArrayBuffer(e,r,t)}if(typeof e==="string"){return fromString(e,r)}return n?Buffer.from(e):new Buffer(e)}e.exports=bufferFrom},274:(e,r,n)=>{var t=n(339);var o=Object.prototype.hasOwnProperty;var i=typeof Map!=="undefined";function ArraySet(){this._array=[];this._set=i?new Map:Object.create(null)}ArraySet.fromArray=function ArraySet_fromArray(e,r){var n=new ArraySet;for(var t=0,o=e.length;t=0){return r}}else{var n=t.toSetString(e);if(o.call(this._set,n)){return this._set[n]}}throw new Error('"'+e+'" is not in the set.')};ArraySet.prototype.at=function ArraySet_at(e){if(e>=0&&e{var t=n(190);var o=5;var i=1<>1;return r?-n:n}r.encode=function base64VLQ_encode(e){var r="";var n;var i=toVLQSigned(e);do{n=i&a;i>>>=o;if(i>0){n|=u}r+=t.encode(n)}while(i>0);return r};r.decode=function base64VLQ_decode(e,r,n){var i=e.length;var s=0;var l=0;var c,p;do{if(r>=i){throw new Error("Expected more digits in base 64 VLQ value.")}p=t.decode(e.charCodeAt(r++));if(p===-1){throw new Error("Invalid base64 digit: "+e.charAt(r-1))}c=!!(p&u);p&=a;s=s+(p<{var n="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("");r.encode=function(e){if(0<=e&&e{r.GREATEST_LOWER_BOUND=1;r.LEAST_UPPER_BOUND=2;function recursiveSearch(e,n,t,o,i,a){var u=Math.floor((n-e)/2)+e;var s=i(t,o[u],true);if(s===0){return u}else if(s>0){if(n-u>1){return recursiveSearch(u,n,t,o,i,a)}if(a==r.LEAST_UPPER_BOUND){return n1){return recursiveSearch(e,u,t,o,i,a)}if(a==r.LEAST_UPPER_BOUND){return u}else{return e<0?-1:e}}}r.search=function search(e,n,t,o){if(n.length===0){return-1}var i=recursiveSearch(-1,n.length,e,n,t,o||r.GREATEST_LOWER_BOUND);if(i<0){return-1}while(i-1>=0){if(t(n[i],n[i-1],true)!==0){break}--i}return i}},680:(e,r,n)=>{var t=n(339);function generatedPositionAfter(e,r){var n=e.generatedLine;var o=r.generatedLine;var i=e.generatedColumn;var a=r.generatedColumn;return o>n||o==n&&a>=i||t.compareByGeneratedPositionsInflated(e,r)<=0}function MappingList(){this._array=[];this._sorted=true;this._last={generatedLine:-1,generatedColumn:0}}MappingList.prototype.unsortedForEach=function MappingList_forEach(e,r){this._array.forEach(e,r)};MappingList.prototype.add=function MappingList_add(e){if(generatedPositionAfter(this._last,e)){this._last=e;this._array.push(e)}else{this._sorted=false;this._array.push(e)}};MappingList.prototype.toArray=function MappingList_toArray(){if(!this._sorted){this._array.sort(t.compareByGeneratedPositionsInflated);this._sorted=true}return this._array};r.H=MappingList},758:(e,r)=>{function swap(e,r,n){var t=e[r];e[r]=e[n];e[n]=t}function randomIntInRange(e,r){return Math.round(e+Math.random()*(r-e))}function doQuickSort(e,r,n,t){if(n{var t;var o=n(339);var i=n(345);var a=n(274).I;var u=n(449);var s=n(758).U;function SourceMapConsumer(e,r){var n=e;if(typeof e==="string"){n=o.parseSourceMapInput(e)}return n.sections!=null?new IndexedSourceMapConsumer(n,r):new BasicSourceMapConsumer(n,r)}SourceMapConsumer.fromSourceMap=function(e,r){return BasicSourceMapConsumer.fromSourceMap(e,r)};SourceMapConsumer.prototype._version=3;SourceMapConsumer.prototype.__generatedMappings=null;Object.defineProperty(SourceMapConsumer.prototype,"_generatedMappings",{configurable:true,enumerable:true,get:function(){if(!this.__generatedMappings){this._parseMappings(this._mappings,this.sourceRoot)}return this.__generatedMappings}});SourceMapConsumer.prototype.__originalMappings=null;Object.defineProperty(SourceMapConsumer.prototype,"_originalMappings",{configurable:true,enumerable:true,get:function(){if(!this.__originalMappings){this._parseMappings(this._mappings,this.sourceRoot)}return this.__originalMappings}});SourceMapConsumer.prototype._charIsMappingSeparator=function SourceMapConsumer_charIsMappingSeparator(e,r){var n=e.charAt(r);return n===";"||n===","};SourceMapConsumer.prototype._parseMappings=function SourceMapConsumer_parseMappings(e,r){throw new Error("Subclasses must implement _parseMappings")};SourceMapConsumer.GENERATED_ORDER=1;SourceMapConsumer.ORIGINAL_ORDER=2;SourceMapConsumer.GREATEST_LOWER_BOUND=1;SourceMapConsumer.LEAST_UPPER_BOUND=2;SourceMapConsumer.prototype.eachMapping=function SourceMapConsumer_eachMapping(e,r,n){var t=r||null;var i=n||SourceMapConsumer.GENERATED_ORDER;var a;switch(i){case SourceMapConsumer.GENERATED_ORDER:a=this._generatedMappings;break;case SourceMapConsumer.ORIGINAL_ORDER:a=this._originalMappings;break;default:throw new Error("Unknown order of iteration.")}var u=this.sourceRoot;a.map((function(e){var r=e.source===null?null:this._sources.at(e.source);r=o.computeSourceURL(u,r,this._sourceMapURL);return{source:r,generatedLine:e.generatedLine,generatedColumn:e.generatedColumn,originalLine:e.originalLine,originalColumn:e.originalColumn,name:e.name===null?null:this._names.at(e.name)}}),this).forEach(e,t)};SourceMapConsumer.prototype.allGeneratedPositionsFor=function SourceMapConsumer_allGeneratedPositionsFor(e){var r=o.getArg(e,"line");var n={source:o.getArg(e,"source"),originalLine:r,originalColumn:o.getArg(e,"column",0)};n.source=this._findSourceIndex(n.source);if(n.source<0){return[]}var t=[];var a=this._findMapping(n,this._originalMappings,"originalLine","originalColumn",o.compareByOriginalPositions,i.LEAST_UPPER_BOUND);if(a>=0){var u=this._originalMappings[a];if(e.column===undefined){var s=u.originalLine;while(u&&u.originalLine===s){t.push({line:o.getArg(u,"generatedLine",null),column:o.getArg(u,"generatedColumn",null),lastColumn:o.getArg(u,"lastGeneratedColumn",null)});u=this._originalMappings[++a]}}else{var l=u.originalColumn;while(u&&u.originalLine===r&&u.originalColumn==l){t.push({line:o.getArg(u,"generatedLine",null),column:o.getArg(u,"generatedColumn",null),lastColumn:o.getArg(u,"lastGeneratedColumn",null)});u=this._originalMappings[++a]}}}return t};r.SourceMapConsumer=SourceMapConsumer;function BasicSourceMapConsumer(e,r){var n=e;if(typeof e==="string"){n=o.parseSourceMapInput(e)}var t=o.getArg(n,"version");var i=o.getArg(n,"sources");var u=o.getArg(n,"names",[]);var s=o.getArg(n,"sourceRoot",null);var l=o.getArg(n,"sourcesContent",null);var c=o.getArg(n,"mappings");var p=o.getArg(n,"file",null);if(t!=this._version){throw new Error("Unsupported version: "+t)}if(s){s=o.normalize(s)}i=i.map(String).map(o.normalize).map((function(e){return s&&o.isAbsolute(s)&&o.isAbsolute(e)?o.relative(s,e):e}));this._names=a.fromArray(u.map(String),true);this._sources=a.fromArray(i,true);this._absoluteSources=this._sources.toArray().map((function(e){return o.computeSourceURL(s,e,r)}));this.sourceRoot=s;this.sourcesContent=l;this._mappings=c;this._sourceMapURL=r;this.file=p}BasicSourceMapConsumer.prototype=Object.create(SourceMapConsumer.prototype);BasicSourceMapConsumer.prototype.consumer=SourceMapConsumer;BasicSourceMapConsumer.prototype._findSourceIndex=function(e){var r=e;if(this.sourceRoot!=null){r=o.relative(this.sourceRoot,r)}if(this._sources.has(r)){return this._sources.indexOf(r)}var n;for(n=0;n1){v.source=l+_[1];l+=_[1];v.originalLine=i+_[2];i=v.originalLine;v.originalLine+=1;v.originalColumn=a+_[3];a=v.originalColumn;if(_.length>4){v.name=c+_[4];c+=_[4]}}m.push(v);if(typeof v.originalLine==="number"){d.push(v)}}}s(m,o.compareByGeneratedPositionsDeflated);this.__generatedMappings=m;s(d,o.compareByOriginalPositions);this.__originalMappings=d};BasicSourceMapConsumer.prototype._findMapping=function SourceMapConsumer_findMapping(e,r,n,t,o,a){if(e[n]<=0){throw new TypeError("Line must be greater than or equal to 1, got "+e[n])}if(e[t]<0){throw new TypeError("Column must be greater than or equal to 0, got "+e[t])}return i.search(e,r,o,a)};BasicSourceMapConsumer.prototype.computeColumnSpans=function SourceMapConsumer_computeColumnSpans(){for(var e=0;e=0){var t=this._generatedMappings[n];if(t.generatedLine===r.generatedLine){var i=o.getArg(t,"source",null);if(i!==null){i=this._sources.at(i);i=o.computeSourceURL(this.sourceRoot,i,this._sourceMapURL)}var a=o.getArg(t,"name",null);if(a!==null){a=this._names.at(a)}return{source:i,line:o.getArg(t,"originalLine",null),column:o.getArg(t,"originalColumn",null),name:a}}}return{source:null,line:null,column:null,name:null}};BasicSourceMapConsumer.prototype.hasContentsOfAllSources=function BasicSourceMapConsumer_hasContentsOfAllSources(){if(!this.sourcesContent){return false}return this.sourcesContent.length>=this._sources.size()&&!this.sourcesContent.some((function(e){return e==null}))};BasicSourceMapConsumer.prototype.sourceContentFor=function SourceMapConsumer_sourceContentFor(e,r){if(!this.sourcesContent){return null}var n=this._findSourceIndex(e);if(n>=0){return this.sourcesContent[n]}var t=e;if(this.sourceRoot!=null){t=o.relative(this.sourceRoot,t)}var i;if(this.sourceRoot!=null&&(i=o.urlParse(this.sourceRoot))){var a=t.replace(/^file:\/\//,"");if(i.scheme=="file"&&this._sources.has(a)){return this.sourcesContent[this._sources.indexOf(a)]}if((!i.path||i.path=="/")&&this._sources.has("/"+t)){return this.sourcesContent[this._sources.indexOf("/"+t)]}}if(r){return null}else{throw new Error('"'+t+'" is not in the SourceMap.')}};BasicSourceMapConsumer.prototype.generatedPositionFor=function SourceMapConsumer_generatedPositionFor(e){var r=o.getArg(e,"source");r=this._findSourceIndex(r);if(r<0){return{line:null,column:null,lastColumn:null}}var n={source:r,originalLine:o.getArg(e,"line"),originalColumn:o.getArg(e,"column")};var t=this._findMapping(n,this._originalMappings,"originalLine","originalColumn",o.compareByOriginalPositions,o.getArg(e,"bias",SourceMapConsumer.GREATEST_LOWER_BOUND));if(t>=0){var i=this._originalMappings[t];if(i.source===n.source){return{line:o.getArg(i,"generatedLine",null),column:o.getArg(i,"generatedColumn",null),lastColumn:o.getArg(i,"lastGeneratedColumn",null)}}}return{line:null,column:null,lastColumn:null}};t=BasicSourceMapConsumer;function IndexedSourceMapConsumer(e,r){var n=e;if(typeof e==="string"){n=o.parseSourceMapInput(e)}var t=o.getArg(n,"version");var i=o.getArg(n,"sections");if(t!=this._version){throw new Error("Unsupported version: "+t)}this._sources=new a;this._names=new a;var u={line:-1,column:0};this._sections=i.map((function(e){if(e.url){throw new Error("Support for url field in sections not implemented.")}var n=o.getArg(e,"offset");var t=o.getArg(n,"line");var i=o.getArg(n,"column");if(t{var t=n(449);var o=n(339);var i=n(274).I;var a=n(680).H;function SourceMapGenerator(e){if(!e){e={}}this._file=o.getArg(e,"file",null);this._sourceRoot=o.getArg(e,"sourceRoot",null);this._skipValidation=o.getArg(e,"skipValidation",false);this._sources=new i;this._names=new i;this._mappings=new a;this._sourcesContents=null}SourceMapGenerator.prototype._version=3;SourceMapGenerator.fromSourceMap=function SourceMapGenerator_fromSourceMap(e){var r=e.sourceRoot;var n=new SourceMapGenerator({file:e.file,sourceRoot:r});e.eachMapping((function(e){var t={generated:{line:e.generatedLine,column:e.generatedColumn}};if(e.source!=null){t.source=e.source;if(r!=null){t.source=o.relative(r,t.source)}t.original={line:e.originalLine,column:e.originalColumn};if(e.name!=null){t.name=e.name}}n.addMapping(t)}));e.sources.forEach((function(t){var i=t;if(r!==null){i=o.relative(r,t)}if(!n._sources.has(i)){n._sources.add(i)}var a=e.sourceContentFor(t);if(a!=null){n.setSourceContent(t,a)}}));return n};SourceMapGenerator.prototype.addMapping=function SourceMapGenerator_addMapping(e){var r=o.getArg(e,"generated");var n=o.getArg(e,"original",null);var t=o.getArg(e,"source",null);var i=o.getArg(e,"name",null);if(!this._skipValidation){this._validateMapping(r,n,t,i)}if(t!=null){t=String(t);if(!this._sources.has(t)){this._sources.add(t)}}if(i!=null){i=String(i);if(!this._names.has(i)){this._names.add(i)}}this._mappings.add({generatedLine:r.line,generatedColumn:r.column,originalLine:n!=null&&n.line,originalColumn:n!=null&&n.column,source:t,name:i})};SourceMapGenerator.prototype.setSourceContent=function SourceMapGenerator_setSourceContent(e,r){var n=e;if(this._sourceRoot!=null){n=o.relative(this._sourceRoot,n)}if(r!=null){if(!this._sourcesContents){this._sourcesContents=Object.create(null)}this._sourcesContents[o.toSetString(n)]=r}else if(this._sourcesContents){delete this._sourcesContents[o.toSetString(n)];if(Object.keys(this._sourcesContents).length===0){this._sourcesContents=null}}};SourceMapGenerator.prototype.applySourceMap=function SourceMapGenerator_applySourceMap(e,r,n){var t=r;if(r==null){if(e.file==null){throw new Error("SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, "+'or the source map\'s "file" property. Both were omitted.')}t=e.file}var a=this._sourceRoot;if(a!=null){t=o.relative(a,t)}var u=new i;var s=new i;this._mappings.unsortedForEach((function(r){if(r.source===t&&r.originalLine!=null){var i=e.originalPositionFor({line:r.originalLine,column:r.originalColumn});if(i.source!=null){r.source=i.source;if(n!=null){r.source=o.join(n,r.source)}if(a!=null){r.source=o.relative(a,r.source)}r.originalLine=i.line;r.originalColumn=i.column;if(i.name!=null){r.name=i.name}}}var l=r.source;if(l!=null&&!u.has(l)){u.add(l)}var c=r.name;if(c!=null&&!s.has(c)){s.add(c)}}),this);this._sources=u;this._names=s;e.sources.forEach((function(r){var t=e.sourceContentFor(r);if(t!=null){if(n!=null){r=o.join(n,r)}if(a!=null){r=o.relative(a,r)}this.setSourceContent(r,t)}}),this)};SourceMapGenerator.prototype._validateMapping=function SourceMapGenerator_validateMapping(e,r,n,t){if(r&&typeof r.line!=="number"&&typeof r.column!=="number"){throw new Error("original.line and original.column are not numbers -- you probably meant to omit "+"the original mapping entirely and only map the generated position. If so, pass "+"null for the original mapping instead of an object with empty or null values.")}if(e&&"line"in e&&"column"in e&&e.line>0&&e.column>=0&&!r&&!n&&!t){return}else if(e&&"line"in e&&"column"in e&&r&&"line"in r&&"column"in r&&e.line>0&&e.column>=0&&r.line>0&&r.column>=0&&n){return}else{throw new Error("Invalid mapping: "+JSON.stringify({generated:e,source:n,original:r,name:t}))}};SourceMapGenerator.prototype._serializeMappings=function SourceMapGenerator_serializeMappings(){var e=0;var r=1;var n=0;var i=0;var a=0;var u=0;var s="";var l;var c;var p;var f;var g=this._mappings.toArray();for(var h=0,d=g.length;h0){if(!o.compareByGeneratedPositionsInflated(c,g[h-1])){continue}l+=","}}l+=t.encode(c.generatedColumn-e);e=c.generatedColumn;if(c.source!=null){f=this._sources.indexOf(c.source);l+=t.encode(f-u);u=f;l+=t.encode(c.originalLine-1-i);i=c.originalLine-1;l+=t.encode(c.originalColumn-n);n=c.originalColumn;if(c.name!=null){p=this._names.indexOf(c.name);l+=t.encode(p-a);a=p}}s+=l}return s};SourceMapGenerator.prototype._generateSourcesContent=function SourceMapGenerator_generateSourcesContent(e,r){return e.map((function(e){if(!this._sourcesContents){return null}if(r!=null){e=o.relative(r,e)}var n=o.toSetString(e);return Object.prototype.hasOwnProperty.call(this._sourcesContents,n)?this._sourcesContents[n]:null}),this)};SourceMapGenerator.prototype.toJSON=function SourceMapGenerator_toJSON(){var e={version:this._version,sources:this._sources.toArray(),names:this._names.toArray(),mappings:this._serializeMappings()};if(this._file!=null){e.file=this._file}if(this._sourceRoot!=null){e.sourceRoot=this._sourceRoot}if(this._sourcesContents){e.sourcesContent=this._generateSourcesContent(e.sources,e.sourceRoot)}return e};SourceMapGenerator.prototype.toString=function SourceMapGenerator_toString(){return JSON.stringify(this.toJSON())};r.h=SourceMapGenerator},351:(e,r,n)=>{var t;var o=n(591).h;var i=n(339);var a=/(\r?\n)/;var u=10;var s="$$$isSourceNode$$$";function SourceNode(e,r,n,t,o){this.children=[];this.sourceContents={};this.line=e==null?null:e;this.column=r==null?null:r;this.source=n==null?null:n;this.name=o==null?null:o;this[s]=true;if(t!=null)this.add(t)}SourceNode.fromStringWithSourceMap=function SourceNode_fromStringWithSourceMap(e,r,n){var t=new SourceNode;var o=e.split(a);var u=0;var shiftNextLine=function(){var e=getNextLine();var r=getNextLine()||"";return e+r;function getNextLine(){return u=0;r--){this.prepend(e[r])}}else if(e[s]||typeof e==="string"){this.children.unshift(e)}else{throw new TypeError("Expected a SourceNode, string, or an array of SourceNodes and strings. Got "+e)}return this};SourceNode.prototype.walk=function SourceNode_walk(e){var r;for(var n=0,t=this.children.length;n0){r=[];for(n=0;n{function getArg(e,r,n){if(r in e){return e[r]}else if(arguments.length===3){return n}else{throw new Error('"'+r+'" is a required argument.')}}r.getArg=getArg;var n=/^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/;var t=/^data:.+\,.+$/;function urlParse(e){var r=e.match(n);if(!r){return null}return{scheme:r[1],auth:r[2],host:r[3],port:r[4],path:r[5]}}r.urlParse=urlParse;function urlGenerate(e){var r="";if(e.scheme){r+=e.scheme+":"}r+="//";if(e.auth){r+=e.auth+"@"}if(e.host){r+=e.host}if(e.port){r+=":"+e.port}if(e.path){r+=e.path}return r}r.urlGenerate=urlGenerate;function normalize(e){var n=e;var t=urlParse(e);if(t){if(!t.path){return e}n=t.path}var o=r.isAbsolute(n);var i=n.split(/\/+/);for(var a,u=0,s=i.length-1;s>=0;s--){a=i[s];if(a==="."){i.splice(s,1)}else if(a===".."){u++}else if(u>0){if(a===""){i.splice(s+1,u);u=0}else{i.splice(s,2);u--}}}n=i.join("/");if(n===""){n=o?"/":"."}if(t){t.path=n;return urlGenerate(t)}return n}r.normalize=normalize;function join(e,r){if(e===""){e="."}if(r===""){r="."}var n=urlParse(r);var o=urlParse(e);if(o){e=o.path||"/"}if(n&&!n.scheme){if(o){n.scheme=o.scheme}return urlGenerate(n)}if(n||r.match(t)){return r}if(o&&!o.host&&!o.path){o.host=r;return urlGenerate(o)}var i=r.charAt(0)==="/"?r:normalize(e.replace(/\/+$/,"")+"/"+r);if(o){o.path=i;return urlGenerate(o)}return i}r.join=join;r.isAbsolute=function(e){return e.charAt(0)==="/"||n.test(e)};function relative(e,r){if(e===""){e="."}e=e.replace(/\/$/,"");var n=0;while(r.indexOf(e+"/")!==0){var t=e.lastIndexOf("/");if(t<0){return r}e=e.slice(0,t);if(e.match(/^([^\/]+:\/)?\/*$/)){return r}++n}return Array(n+1).join("../")+r.substr(e.length+1)}r.relative=relative;var o=function(){var e=Object.create(null);return!("__proto__"in e)}();function identity(e){return e}function toSetString(e){if(isProtoString(e)){return"$"+e}return e}r.toSetString=o?identity:toSetString;function fromSetString(e){if(isProtoString(e)){return e.slice(1)}return e}r.fromSetString=o?identity:fromSetString;function isProtoString(e){if(!e){return false}var r=e.length;if(r<9){return false}if(e.charCodeAt(r-1)!==95||e.charCodeAt(r-2)!==95||e.charCodeAt(r-3)!==111||e.charCodeAt(r-4)!==116||e.charCodeAt(r-5)!==111||e.charCodeAt(r-6)!==114||e.charCodeAt(r-7)!==112||e.charCodeAt(r-8)!==95||e.charCodeAt(r-9)!==95){return false}for(var n=r-10;n>=0;n--){if(e.charCodeAt(n)!==36){return false}}return true}function compareByOriginalPositions(e,r,n){var t=strcmp(e.source,r.source);if(t!==0){return t}t=e.originalLine-r.originalLine;if(t!==0){return t}t=e.originalColumn-r.originalColumn;if(t!==0||n){return t}t=e.generatedColumn-r.generatedColumn;if(t!==0){return t}t=e.generatedLine-r.generatedLine;if(t!==0){return t}return strcmp(e.name,r.name)}r.compareByOriginalPositions=compareByOriginalPositions;function compareByGeneratedPositionsDeflated(e,r,n){var t=e.generatedLine-r.generatedLine;if(t!==0){return t}t=e.generatedColumn-r.generatedColumn;if(t!==0||n){return t}t=strcmp(e.source,r.source);if(t!==0){return t}t=e.originalLine-r.originalLine;if(t!==0){return t}t=e.originalColumn-r.originalColumn;if(t!==0){return t}return strcmp(e.name,r.name)}r.compareByGeneratedPositionsDeflated=compareByGeneratedPositionsDeflated;function strcmp(e,r){if(e===r){return 0}if(e===null){return 1}if(r===null){return-1}if(e>r){return 1}return-1}function compareByGeneratedPositionsInflated(e,r){var n=e.generatedLine-r.generatedLine;if(n!==0){return n}n=e.generatedColumn-r.generatedColumn;if(n!==0){return n}n=strcmp(e.source,r.source);if(n!==0){return n}n=e.originalLine-r.originalLine;if(n!==0){return n}n=e.originalColumn-r.originalColumn;if(n!==0){return n}return strcmp(e.name,r.name)}r.compareByGeneratedPositionsInflated=compareByGeneratedPositionsInflated;function parseSourceMapInput(e){return JSON.parse(e.replace(/^\)]}'[^\n]*\n/,""))}r.parseSourceMapInput=parseSourceMapInput;function computeSourceURL(e,r,n){r=r||"";if(e){if(e[e.length-1]!=="/"&&r[0]!=="/"){e+="/"}r=e+r}if(n){var t=urlParse(n);if(!t){throw new Error("sourceMapURL could not be parsed")}if(t.path){var o=t.path.lastIndexOf("/");if(o>=0){t.path=t.path.substring(0,o+1)}}r=join(urlGenerate(t),r)}return normalize(r)}r.computeSourceURL=computeSourceURL},997:(e,r,n)=>{n(591).h;r.SourceMapConsumer=n(952).SourceMapConsumer;n(351)},284:(e,r,n)=>{e=n.nmd(e);var t=n(997).SourceMapConsumer;var o=n(17);var i;try{i=n(147);if(!i.existsSync||!i.readFileSync){i=null}}catch(e){}var a=n(650);function dynamicRequire(e,r){return e.require(r)}var u=false;var s=false;var l=false;var c="auto";var p={};var f={};var g=/^data:application\/json[^,]+base64,/;var h=[];var d=[];function isInBrowser(){if(c==="browser")return true;if(c==="node")return false;return typeof window!=="undefined"&&typeof XMLHttpRequest==="function"&&!(window.require&&window.module&&window.process&&window.process.type==="renderer")}function hasGlobalProcessEventEmitter(){return typeof process==="object"&&process!==null&&typeof process.on==="function"}function globalProcessVersion(){if(typeof process==="object"&&process!==null){return process.version}else{return""}}function globalProcessStderr(){if(typeof process==="object"&&process!==null){return process.stderr}}function globalProcessExit(e){if(typeof process==="object"&&process!==null&&typeof process.exit==="function"){return process.exit(e)}}function handlerExec(e){return function(r){for(var n=0;n"}var n=this.getLineNumber();if(n!=null){r+=":"+n;var t=this.getColumnNumber();if(t){r+=":"+t}}}var o="";var i=this.getFunctionName();var a=true;var u=this.isConstructor();var s=!(this.isToplevel()||u);if(s){var l=this.getTypeName();if(l==="[object Object]"){l="null"}var c=this.getMethodName();if(i){if(l&&i.indexOf(l)!=0){o+=l+"."}o+=i;if(c&&i.indexOf("."+c)!=i.length-c.length-1){o+=" [as "+c+"]"}}else{o+=l+"."+(c||"")}}else if(u){o+="new "+(i||"")}else if(i){o+=i}else{o+=r;a=false}if(a){o+=" ("+r+")"}return o}function cloneCallSite(e){var r={};Object.getOwnPropertyNames(Object.getPrototypeOf(e)).forEach((function(n){r[n]=/^(?:is|get)/.test(n)?function(){return e[n].call(e)}:e[n]}));r.toString=CallSiteToString;return r}function wrapCallSite(e,r){if(r===undefined){r={nextPosition:null,curPosition:null}}if(e.isNative()){r.curPosition=null;return e}var n=e.getFileName()||e.getScriptNameOrSourceURL();if(n){var t=e.getLineNumber();var o=e.getColumnNumber()-1;var i=/^v(10\.1[6-9]|10\.[2-9][0-9]|10\.[0-9]{3,}|1[2-9]\d*|[2-9]\d|\d{3,}|11\.11)/;var a=i.test(globalProcessVersion())?0:62;if(t===1&&o>a&&!isInBrowser()&&!e.isEval()){o-=a}var u=mapSourcePosition({source:n,line:t,column:o});r.curPosition=u;e=cloneCallSite(e);var s=e.getFunctionName;e.getFunctionName=function(){if(r.nextPosition==null){return s()}return r.nextPosition.name||s()};e.getFileName=function(){return u.source};e.getLineNumber=function(){return u.line};e.getColumnNumber=function(){return u.column+1};e.getScriptNameOrSourceURL=function(){return u.source};return e}var l=e.isEval()&&e.getEvalOrigin();if(l){l=mapEvalOrigin(l);e=cloneCallSite(e);e.getEvalOrigin=function(){return l};return e}return e}function prepareStackTrace(e,r){if(l){p={};f={}}var n=e.name||"Error";var t=e.message||"";var o=n+": "+t;var i={nextPosition:null,curPosition:null};var a=[];for(var u=r.length-1;u>=0;u--){a.push("\n at "+wrapCallSite(r[u],i));i.nextPosition=i.curPosition}i.curPosition=i.nextPosition=null;return o+a.reverse().join("")}function getErrorSource(e){var r=/\n at [^(]+ \((.*):(\d+):(\d+)\)/.exec(e.stack);if(r){var n=r[1];var t=+r[2];var o=+r[3];var a=p[n];if(!a&&i&&i.existsSync(n)){try{a=i.readFileSync(n,"utf8")}catch(e){a=""}}if(a){var u=a.split(/(?:\r\n|\r|\n)/)[t-1];if(u){return n+":"+t+"\n"+u+"\n"+new Array(o).join(" ")+"^"}}}return null}function printErrorAndExit(e){var r=getErrorSource(e);var n=globalProcessStderr();if(n&&n._handle&&n._handle.setBlocking){n._handle.setBlocking(true)}if(r){console.error();console.error(r)}console.error(e.stack);globalProcessExit(1)}function shimEmitUncaughtException(){var e=process.emit;process.emit=function(r){if(r==="uncaughtException"){var n=arguments[1]&&arguments[1].stack;var t=this.listeners(r).length>0;if(n&&!t){return printErrorAndExit(arguments[1])}}return e.apply(this,arguments)}}var S=h.slice(0);var _=d.slice(0);r.wrapCallSite=wrapCallSite;r.getErrorSource=getErrorSource;r.mapSourcePosition=mapSourcePosition;r.retrieveSourceMap=v;r.install=function(r){r=r||{};if(r.environment){c=r.environment;if(["node","browser","auto"].indexOf(c)===-1){throw new Error("environment "+c+" was unknown. Available options are {auto, browser, node}")}}if(r.retrieveFile){if(r.overrideRetrieveFile){h.length=0}h.unshift(r.retrieveFile)}if(r.retrieveSourceMap){if(r.overrideRetrieveSourceMap){d.length=0}d.unshift(r.retrieveSourceMap)}if(r.hookRequire&&!isInBrowser()){var n=dynamicRequire(e,"module");var t=n.prototype._compile;if(!t.__sourceMapSupport){n.prototype._compile=function(e,r){p[r]=e;f[r]=undefined;return t.call(this,e,r)};n.prototype._compile.__sourceMapSupport=true}}if(!l){l="emptyCacheBetweenOperations"in r?r.emptyCacheBetweenOperations:false}if(!u){u=true;Error.prepareStackTrace=prepareStackTrace}if(!s){var o="handleUncaughtExceptions"in r?r.handleUncaughtExceptions:true;try{var i=dynamicRequire(e,"worker_threads");if(i.isMainThread===false){o=false}}catch(e){}if(o&&hasGlobalProcessEventEmitter()){s=true;shimEmitUncaughtException()}}};r.resetRetrieveHandlers=function(){h.length=0;d.length=0;h=S.slice(0);d=_.slice(0);v=handlerExec(d);m=handlerExec(h)}},147:e=>{"use strict";e.exports=require("fs")},17:e=>{"use strict";e.exports=require("path")}};var r={};function __webpack_require__(n){var t=r[n];if(t!==undefined){return t.exports}var o=r[n]={id:n,loaded:false,exports:{}};var i=true;try{e[n](o,o.exports,__webpack_require__);i=false}finally{if(i)delete r[n]}o.loaded=true;return o.exports}(()=>{__webpack_require__.nmd=e=>{e.paths=[];if(!e.children)e.children=[];return e}})();if(typeof __webpack_require__!=="undefined")__webpack_require__.ab=__dirname+"/";var n={};(()=>{__webpack_require__(284).install()})();module.exports=n})(); -------------------------------------------------------------------------------- /dist/post/sourcemap-register.js: -------------------------------------------------------------------------------- 1 | (()=>{var e={650:e=>{var r=Object.prototype.toString;var n=typeof Buffer.alloc==="function"&&typeof Buffer.allocUnsafe==="function"&&typeof Buffer.from==="function";function isArrayBuffer(e){return r.call(e).slice(8,-1)==="ArrayBuffer"}function fromArrayBuffer(e,r,t){r>>>=0;var o=e.byteLength-r;if(o<0){throw new RangeError("'offset' is out of bounds")}if(t===undefined){t=o}else{t>>>=0;if(t>o){throw new RangeError("'length' is out of bounds")}}return n?Buffer.from(e.slice(r,r+t)):new Buffer(new Uint8Array(e.slice(r,r+t)))}function fromString(e,r){if(typeof r!=="string"||r===""){r="utf8"}if(!Buffer.isEncoding(r)){throw new TypeError('"encoding" must be a valid string encoding')}return n?Buffer.from(e,r):new Buffer(e,r)}function bufferFrom(e,r,t){if(typeof e==="number"){throw new TypeError('"value" argument must not be a number')}if(isArrayBuffer(e)){return fromArrayBuffer(e,r,t)}if(typeof e==="string"){return fromString(e,r)}return n?Buffer.from(e):new Buffer(e)}e.exports=bufferFrom},274:(e,r,n)=>{var t=n(339);var o=Object.prototype.hasOwnProperty;var i=typeof Map!=="undefined";function ArraySet(){this._array=[];this._set=i?new Map:Object.create(null)}ArraySet.fromArray=function ArraySet_fromArray(e,r){var n=new ArraySet;for(var t=0,o=e.length;t=0){return r}}else{var n=t.toSetString(e);if(o.call(this._set,n)){return this._set[n]}}throw new Error('"'+e+'" is not in the set.')};ArraySet.prototype.at=function ArraySet_at(e){if(e>=0&&e{var t=n(190);var o=5;var i=1<>1;return r?-n:n}r.encode=function base64VLQ_encode(e){var r="";var n;var i=toVLQSigned(e);do{n=i&a;i>>>=o;if(i>0){n|=u}r+=t.encode(n)}while(i>0);return r};r.decode=function base64VLQ_decode(e,r,n){var i=e.length;var s=0;var l=0;var c,p;do{if(r>=i){throw new Error("Expected more digits in base 64 VLQ value.")}p=t.decode(e.charCodeAt(r++));if(p===-1){throw new Error("Invalid base64 digit: "+e.charAt(r-1))}c=!!(p&u);p&=a;s=s+(p<{var n="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("");r.encode=function(e){if(0<=e&&e{r.GREATEST_LOWER_BOUND=1;r.LEAST_UPPER_BOUND=2;function recursiveSearch(e,n,t,o,i,a){var u=Math.floor((n-e)/2)+e;var s=i(t,o[u],true);if(s===0){return u}else if(s>0){if(n-u>1){return recursiveSearch(u,n,t,o,i,a)}if(a==r.LEAST_UPPER_BOUND){return n1){return recursiveSearch(e,u,t,o,i,a)}if(a==r.LEAST_UPPER_BOUND){return u}else{return e<0?-1:e}}}r.search=function search(e,n,t,o){if(n.length===0){return-1}var i=recursiveSearch(-1,n.length,e,n,t,o||r.GREATEST_LOWER_BOUND);if(i<0){return-1}while(i-1>=0){if(t(n[i],n[i-1],true)!==0){break}--i}return i}},680:(e,r,n)=>{var t=n(339);function generatedPositionAfter(e,r){var n=e.generatedLine;var o=r.generatedLine;var i=e.generatedColumn;var a=r.generatedColumn;return o>n||o==n&&a>=i||t.compareByGeneratedPositionsInflated(e,r)<=0}function MappingList(){this._array=[];this._sorted=true;this._last={generatedLine:-1,generatedColumn:0}}MappingList.prototype.unsortedForEach=function MappingList_forEach(e,r){this._array.forEach(e,r)};MappingList.prototype.add=function MappingList_add(e){if(generatedPositionAfter(this._last,e)){this._last=e;this._array.push(e)}else{this._sorted=false;this._array.push(e)}};MappingList.prototype.toArray=function MappingList_toArray(){if(!this._sorted){this._array.sort(t.compareByGeneratedPositionsInflated);this._sorted=true}return this._array};r.H=MappingList},758:(e,r)=>{function swap(e,r,n){var t=e[r];e[r]=e[n];e[n]=t}function randomIntInRange(e,r){return Math.round(e+Math.random()*(r-e))}function doQuickSort(e,r,n,t){if(n{var t;var o=n(339);var i=n(345);var a=n(274).I;var u=n(449);var s=n(758).U;function SourceMapConsumer(e,r){var n=e;if(typeof e==="string"){n=o.parseSourceMapInput(e)}return n.sections!=null?new IndexedSourceMapConsumer(n,r):new BasicSourceMapConsumer(n,r)}SourceMapConsumer.fromSourceMap=function(e,r){return BasicSourceMapConsumer.fromSourceMap(e,r)};SourceMapConsumer.prototype._version=3;SourceMapConsumer.prototype.__generatedMappings=null;Object.defineProperty(SourceMapConsumer.prototype,"_generatedMappings",{configurable:true,enumerable:true,get:function(){if(!this.__generatedMappings){this._parseMappings(this._mappings,this.sourceRoot)}return this.__generatedMappings}});SourceMapConsumer.prototype.__originalMappings=null;Object.defineProperty(SourceMapConsumer.prototype,"_originalMappings",{configurable:true,enumerable:true,get:function(){if(!this.__originalMappings){this._parseMappings(this._mappings,this.sourceRoot)}return this.__originalMappings}});SourceMapConsumer.prototype._charIsMappingSeparator=function SourceMapConsumer_charIsMappingSeparator(e,r){var n=e.charAt(r);return n===";"||n===","};SourceMapConsumer.prototype._parseMappings=function SourceMapConsumer_parseMappings(e,r){throw new Error("Subclasses must implement _parseMappings")};SourceMapConsumer.GENERATED_ORDER=1;SourceMapConsumer.ORIGINAL_ORDER=2;SourceMapConsumer.GREATEST_LOWER_BOUND=1;SourceMapConsumer.LEAST_UPPER_BOUND=2;SourceMapConsumer.prototype.eachMapping=function SourceMapConsumer_eachMapping(e,r,n){var t=r||null;var i=n||SourceMapConsumer.GENERATED_ORDER;var a;switch(i){case SourceMapConsumer.GENERATED_ORDER:a=this._generatedMappings;break;case SourceMapConsumer.ORIGINAL_ORDER:a=this._originalMappings;break;default:throw new Error("Unknown order of iteration.")}var u=this.sourceRoot;a.map((function(e){var r=e.source===null?null:this._sources.at(e.source);r=o.computeSourceURL(u,r,this._sourceMapURL);return{source:r,generatedLine:e.generatedLine,generatedColumn:e.generatedColumn,originalLine:e.originalLine,originalColumn:e.originalColumn,name:e.name===null?null:this._names.at(e.name)}}),this).forEach(e,t)};SourceMapConsumer.prototype.allGeneratedPositionsFor=function SourceMapConsumer_allGeneratedPositionsFor(e){var r=o.getArg(e,"line");var n={source:o.getArg(e,"source"),originalLine:r,originalColumn:o.getArg(e,"column",0)};n.source=this._findSourceIndex(n.source);if(n.source<0){return[]}var t=[];var a=this._findMapping(n,this._originalMappings,"originalLine","originalColumn",o.compareByOriginalPositions,i.LEAST_UPPER_BOUND);if(a>=0){var u=this._originalMappings[a];if(e.column===undefined){var s=u.originalLine;while(u&&u.originalLine===s){t.push({line:o.getArg(u,"generatedLine",null),column:o.getArg(u,"generatedColumn",null),lastColumn:o.getArg(u,"lastGeneratedColumn",null)});u=this._originalMappings[++a]}}else{var l=u.originalColumn;while(u&&u.originalLine===r&&u.originalColumn==l){t.push({line:o.getArg(u,"generatedLine",null),column:o.getArg(u,"generatedColumn",null),lastColumn:o.getArg(u,"lastGeneratedColumn",null)});u=this._originalMappings[++a]}}}return t};r.SourceMapConsumer=SourceMapConsumer;function BasicSourceMapConsumer(e,r){var n=e;if(typeof e==="string"){n=o.parseSourceMapInput(e)}var t=o.getArg(n,"version");var i=o.getArg(n,"sources");var u=o.getArg(n,"names",[]);var s=o.getArg(n,"sourceRoot",null);var l=o.getArg(n,"sourcesContent",null);var c=o.getArg(n,"mappings");var p=o.getArg(n,"file",null);if(t!=this._version){throw new Error("Unsupported version: "+t)}if(s){s=o.normalize(s)}i=i.map(String).map(o.normalize).map((function(e){return s&&o.isAbsolute(s)&&o.isAbsolute(e)?o.relative(s,e):e}));this._names=a.fromArray(u.map(String),true);this._sources=a.fromArray(i,true);this._absoluteSources=this._sources.toArray().map((function(e){return o.computeSourceURL(s,e,r)}));this.sourceRoot=s;this.sourcesContent=l;this._mappings=c;this._sourceMapURL=r;this.file=p}BasicSourceMapConsumer.prototype=Object.create(SourceMapConsumer.prototype);BasicSourceMapConsumer.prototype.consumer=SourceMapConsumer;BasicSourceMapConsumer.prototype._findSourceIndex=function(e){var r=e;if(this.sourceRoot!=null){r=o.relative(this.sourceRoot,r)}if(this._sources.has(r)){return this._sources.indexOf(r)}var n;for(n=0;n1){v.source=l+_[1];l+=_[1];v.originalLine=i+_[2];i=v.originalLine;v.originalLine+=1;v.originalColumn=a+_[3];a=v.originalColumn;if(_.length>4){v.name=c+_[4];c+=_[4]}}m.push(v);if(typeof v.originalLine==="number"){d.push(v)}}}s(m,o.compareByGeneratedPositionsDeflated);this.__generatedMappings=m;s(d,o.compareByOriginalPositions);this.__originalMappings=d};BasicSourceMapConsumer.prototype._findMapping=function SourceMapConsumer_findMapping(e,r,n,t,o,a){if(e[n]<=0){throw new TypeError("Line must be greater than or equal to 1, got "+e[n])}if(e[t]<0){throw new TypeError("Column must be greater than or equal to 0, got "+e[t])}return i.search(e,r,o,a)};BasicSourceMapConsumer.prototype.computeColumnSpans=function SourceMapConsumer_computeColumnSpans(){for(var e=0;e=0){var t=this._generatedMappings[n];if(t.generatedLine===r.generatedLine){var i=o.getArg(t,"source",null);if(i!==null){i=this._sources.at(i);i=o.computeSourceURL(this.sourceRoot,i,this._sourceMapURL)}var a=o.getArg(t,"name",null);if(a!==null){a=this._names.at(a)}return{source:i,line:o.getArg(t,"originalLine",null),column:o.getArg(t,"originalColumn",null),name:a}}}return{source:null,line:null,column:null,name:null}};BasicSourceMapConsumer.prototype.hasContentsOfAllSources=function BasicSourceMapConsumer_hasContentsOfAllSources(){if(!this.sourcesContent){return false}return this.sourcesContent.length>=this._sources.size()&&!this.sourcesContent.some((function(e){return e==null}))};BasicSourceMapConsumer.prototype.sourceContentFor=function SourceMapConsumer_sourceContentFor(e,r){if(!this.sourcesContent){return null}var n=this._findSourceIndex(e);if(n>=0){return this.sourcesContent[n]}var t=e;if(this.sourceRoot!=null){t=o.relative(this.sourceRoot,t)}var i;if(this.sourceRoot!=null&&(i=o.urlParse(this.sourceRoot))){var a=t.replace(/^file:\/\//,"");if(i.scheme=="file"&&this._sources.has(a)){return this.sourcesContent[this._sources.indexOf(a)]}if((!i.path||i.path=="/")&&this._sources.has("/"+t)){return this.sourcesContent[this._sources.indexOf("/"+t)]}}if(r){return null}else{throw new Error('"'+t+'" is not in the SourceMap.')}};BasicSourceMapConsumer.prototype.generatedPositionFor=function SourceMapConsumer_generatedPositionFor(e){var r=o.getArg(e,"source");r=this._findSourceIndex(r);if(r<0){return{line:null,column:null,lastColumn:null}}var n={source:r,originalLine:o.getArg(e,"line"),originalColumn:o.getArg(e,"column")};var t=this._findMapping(n,this._originalMappings,"originalLine","originalColumn",o.compareByOriginalPositions,o.getArg(e,"bias",SourceMapConsumer.GREATEST_LOWER_BOUND));if(t>=0){var i=this._originalMappings[t];if(i.source===n.source){return{line:o.getArg(i,"generatedLine",null),column:o.getArg(i,"generatedColumn",null),lastColumn:o.getArg(i,"lastGeneratedColumn",null)}}}return{line:null,column:null,lastColumn:null}};t=BasicSourceMapConsumer;function IndexedSourceMapConsumer(e,r){var n=e;if(typeof e==="string"){n=o.parseSourceMapInput(e)}var t=o.getArg(n,"version");var i=o.getArg(n,"sections");if(t!=this._version){throw new Error("Unsupported version: "+t)}this._sources=new a;this._names=new a;var u={line:-1,column:0};this._sections=i.map((function(e){if(e.url){throw new Error("Support for url field in sections not implemented.")}var n=o.getArg(e,"offset");var t=o.getArg(n,"line");var i=o.getArg(n,"column");if(t{var t=n(449);var o=n(339);var i=n(274).I;var a=n(680).H;function SourceMapGenerator(e){if(!e){e={}}this._file=o.getArg(e,"file",null);this._sourceRoot=o.getArg(e,"sourceRoot",null);this._skipValidation=o.getArg(e,"skipValidation",false);this._sources=new i;this._names=new i;this._mappings=new a;this._sourcesContents=null}SourceMapGenerator.prototype._version=3;SourceMapGenerator.fromSourceMap=function SourceMapGenerator_fromSourceMap(e){var r=e.sourceRoot;var n=new SourceMapGenerator({file:e.file,sourceRoot:r});e.eachMapping((function(e){var t={generated:{line:e.generatedLine,column:e.generatedColumn}};if(e.source!=null){t.source=e.source;if(r!=null){t.source=o.relative(r,t.source)}t.original={line:e.originalLine,column:e.originalColumn};if(e.name!=null){t.name=e.name}}n.addMapping(t)}));e.sources.forEach((function(t){var i=t;if(r!==null){i=o.relative(r,t)}if(!n._sources.has(i)){n._sources.add(i)}var a=e.sourceContentFor(t);if(a!=null){n.setSourceContent(t,a)}}));return n};SourceMapGenerator.prototype.addMapping=function SourceMapGenerator_addMapping(e){var r=o.getArg(e,"generated");var n=o.getArg(e,"original",null);var t=o.getArg(e,"source",null);var i=o.getArg(e,"name",null);if(!this._skipValidation){this._validateMapping(r,n,t,i)}if(t!=null){t=String(t);if(!this._sources.has(t)){this._sources.add(t)}}if(i!=null){i=String(i);if(!this._names.has(i)){this._names.add(i)}}this._mappings.add({generatedLine:r.line,generatedColumn:r.column,originalLine:n!=null&&n.line,originalColumn:n!=null&&n.column,source:t,name:i})};SourceMapGenerator.prototype.setSourceContent=function SourceMapGenerator_setSourceContent(e,r){var n=e;if(this._sourceRoot!=null){n=o.relative(this._sourceRoot,n)}if(r!=null){if(!this._sourcesContents){this._sourcesContents=Object.create(null)}this._sourcesContents[o.toSetString(n)]=r}else if(this._sourcesContents){delete this._sourcesContents[o.toSetString(n)];if(Object.keys(this._sourcesContents).length===0){this._sourcesContents=null}}};SourceMapGenerator.prototype.applySourceMap=function SourceMapGenerator_applySourceMap(e,r,n){var t=r;if(r==null){if(e.file==null){throw new Error("SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, "+'or the source map\'s "file" property. Both were omitted.')}t=e.file}var a=this._sourceRoot;if(a!=null){t=o.relative(a,t)}var u=new i;var s=new i;this._mappings.unsortedForEach((function(r){if(r.source===t&&r.originalLine!=null){var i=e.originalPositionFor({line:r.originalLine,column:r.originalColumn});if(i.source!=null){r.source=i.source;if(n!=null){r.source=o.join(n,r.source)}if(a!=null){r.source=o.relative(a,r.source)}r.originalLine=i.line;r.originalColumn=i.column;if(i.name!=null){r.name=i.name}}}var l=r.source;if(l!=null&&!u.has(l)){u.add(l)}var c=r.name;if(c!=null&&!s.has(c)){s.add(c)}}),this);this._sources=u;this._names=s;e.sources.forEach((function(r){var t=e.sourceContentFor(r);if(t!=null){if(n!=null){r=o.join(n,r)}if(a!=null){r=o.relative(a,r)}this.setSourceContent(r,t)}}),this)};SourceMapGenerator.prototype._validateMapping=function SourceMapGenerator_validateMapping(e,r,n,t){if(r&&typeof r.line!=="number"&&typeof r.column!=="number"){throw new Error("original.line and original.column are not numbers -- you probably meant to omit "+"the original mapping entirely and only map the generated position. If so, pass "+"null for the original mapping instead of an object with empty or null values.")}if(e&&"line"in e&&"column"in e&&e.line>0&&e.column>=0&&!r&&!n&&!t){return}else if(e&&"line"in e&&"column"in e&&r&&"line"in r&&"column"in r&&e.line>0&&e.column>=0&&r.line>0&&r.column>=0&&n){return}else{throw new Error("Invalid mapping: "+JSON.stringify({generated:e,source:n,original:r,name:t}))}};SourceMapGenerator.prototype._serializeMappings=function SourceMapGenerator_serializeMappings(){var e=0;var r=1;var n=0;var i=0;var a=0;var u=0;var s="";var l;var c;var p;var f;var g=this._mappings.toArray();for(var h=0,d=g.length;h0){if(!o.compareByGeneratedPositionsInflated(c,g[h-1])){continue}l+=","}}l+=t.encode(c.generatedColumn-e);e=c.generatedColumn;if(c.source!=null){f=this._sources.indexOf(c.source);l+=t.encode(f-u);u=f;l+=t.encode(c.originalLine-1-i);i=c.originalLine-1;l+=t.encode(c.originalColumn-n);n=c.originalColumn;if(c.name!=null){p=this._names.indexOf(c.name);l+=t.encode(p-a);a=p}}s+=l}return s};SourceMapGenerator.prototype._generateSourcesContent=function SourceMapGenerator_generateSourcesContent(e,r){return e.map((function(e){if(!this._sourcesContents){return null}if(r!=null){e=o.relative(r,e)}var n=o.toSetString(e);return Object.prototype.hasOwnProperty.call(this._sourcesContents,n)?this._sourcesContents[n]:null}),this)};SourceMapGenerator.prototype.toJSON=function SourceMapGenerator_toJSON(){var e={version:this._version,sources:this._sources.toArray(),names:this._names.toArray(),mappings:this._serializeMappings()};if(this._file!=null){e.file=this._file}if(this._sourceRoot!=null){e.sourceRoot=this._sourceRoot}if(this._sourcesContents){e.sourcesContent=this._generateSourcesContent(e.sources,e.sourceRoot)}return e};SourceMapGenerator.prototype.toString=function SourceMapGenerator_toString(){return JSON.stringify(this.toJSON())};r.h=SourceMapGenerator},351:(e,r,n)=>{var t;var o=n(591).h;var i=n(339);var a=/(\r?\n)/;var u=10;var s="$$$isSourceNode$$$";function SourceNode(e,r,n,t,o){this.children=[];this.sourceContents={};this.line=e==null?null:e;this.column=r==null?null:r;this.source=n==null?null:n;this.name=o==null?null:o;this[s]=true;if(t!=null)this.add(t)}SourceNode.fromStringWithSourceMap=function SourceNode_fromStringWithSourceMap(e,r,n){var t=new SourceNode;var o=e.split(a);var u=0;var shiftNextLine=function(){var e=getNextLine();var r=getNextLine()||"";return e+r;function getNextLine(){return u=0;r--){this.prepend(e[r])}}else if(e[s]||typeof e==="string"){this.children.unshift(e)}else{throw new TypeError("Expected a SourceNode, string, or an array of SourceNodes and strings. Got "+e)}return this};SourceNode.prototype.walk=function SourceNode_walk(e){var r;for(var n=0,t=this.children.length;n0){r=[];for(n=0;n{function getArg(e,r,n){if(r in e){return e[r]}else if(arguments.length===3){return n}else{throw new Error('"'+r+'" is a required argument.')}}r.getArg=getArg;var n=/^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/;var t=/^data:.+\,.+$/;function urlParse(e){var r=e.match(n);if(!r){return null}return{scheme:r[1],auth:r[2],host:r[3],port:r[4],path:r[5]}}r.urlParse=urlParse;function urlGenerate(e){var r="";if(e.scheme){r+=e.scheme+":"}r+="//";if(e.auth){r+=e.auth+"@"}if(e.host){r+=e.host}if(e.port){r+=":"+e.port}if(e.path){r+=e.path}return r}r.urlGenerate=urlGenerate;function normalize(e){var n=e;var t=urlParse(e);if(t){if(!t.path){return e}n=t.path}var o=r.isAbsolute(n);var i=n.split(/\/+/);for(var a,u=0,s=i.length-1;s>=0;s--){a=i[s];if(a==="."){i.splice(s,1)}else if(a===".."){u++}else if(u>0){if(a===""){i.splice(s+1,u);u=0}else{i.splice(s,2);u--}}}n=i.join("/");if(n===""){n=o?"/":"."}if(t){t.path=n;return urlGenerate(t)}return n}r.normalize=normalize;function join(e,r){if(e===""){e="."}if(r===""){r="."}var n=urlParse(r);var o=urlParse(e);if(o){e=o.path||"/"}if(n&&!n.scheme){if(o){n.scheme=o.scheme}return urlGenerate(n)}if(n||r.match(t)){return r}if(o&&!o.host&&!o.path){o.host=r;return urlGenerate(o)}var i=r.charAt(0)==="/"?r:normalize(e.replace(/\/+$/,"")+"/"+r);if(o){o.path=i;return urlGenerate(o)}return i}r.join=join;r.isAbsolute=function(e){return e.charAt(0)==="/"||n.test(e)};function relative(e,r){if(e===""){e="."}e=e.replace(/\/$/,"");var n=0;while(r.indexOf(e+"/")!==0){var t=e.lastIndexOf("/");if(t<0){return r}e=e.slice(0,t);if(e.match(/^([^\/]+:\/)?\/*$/)){return r}++n}return Array(n+1).join("../")+r.substr(e.length+1)}r.relative=relative;var o=function(){var e=Object.create(null);return!("__proto__"in e)}();function identity(e){return e}function toSetString(e){if(isProtoString(e)){return"$"+e}return e}r.toSetString=o?identity:toSetString;function fromSetString(e){if(isProtoString(e)){return e.slice(1)}return e}r.fromSetString=o?identity:fromSetString;function isProtoString(e){if(!e){return false}var r=e.length;if(r<9){return false}if(e.charCodeAt(r-1)!==95||e.charCodeAt(r-2)!==95||e.charCodeAt(r-3)!==111||e.charCodeAt(r-4)!==116||e.charCodeAt(r-5)!==111||e.charCodeAt(r-6)!==114||e.charCodeAt(r-7)!==112||e.charCodeAt(r-8)!==95||e.charCodeAt(r-9)!==95){return false}for(var n=r-10;n>=0;n--){if(e.charCodeAt(n)!==36){return false}}return true}function compareByOriginalPositions(e,r,n){var t=strcmp(e.source,r.source);if(t!==0){return t}t=e.originalLine-r.originalLine;if(t!==0){return t}t=e.originalColumn-r.originalColumn;if(t!==0||n){return t}t=e.generatedColumn-r.generatedColumn;if(t!==0){return t}t=e.generatedLine-r.generatedLine;if(t!==0){return t}return strcmp(e.name,r.name)}r.compareByOriginalPositions=compareByOriginalPositions;function compareByGeneratedPositionsDeflated(e,r,n){var t=e.generatedLine-r.generatedLine;if(t!==0){return t}t=e.generatedColumn-r.generatedColumn;if(t!==0||n){return t}t=strcmp(e.source,r.source);if(t!==0){return t}t=e.originalLine-r.originalLine;if(t!==0){return t}t=e.originalColumn-r.originalColumn;if(t!==0){return t}return strcmp(e.name,r.name)}r.compareByGeneratedPositionsDeflated=compareByGeneratedPositionsDeflated;function strcmp(e,r){if(e===r){return 0}if(e===null){return 1}if(r===null){return-1}if(e>r){return 1}return-1}function compareByGeneratedPositionsInflated(e,r){var n=e.generatedLine-r.generatedLine;if(n!==0){return n}n=e.generatedColumn-r.generatedColumn;if(n!==0){return n}n=strcmp(e.source,r.source);if(n!==0){return n}n=e.originalLine-r.originalLine;if(n!==0){return n}n=e.originalColumn-r.originalColumn;if(n!==0){return n}return strcmp(e.name,r.name)}r.compareByGeneratedPositionsInflated=compareByGeneratedPositionsInflated;function parseSourceMapInput(e){return JSON.parse(e.replace(/^\)]}'[^\n]*\n/,""))}r.parseSourceMapInput=parseSourceMapInput;function computeSourceURL(e,r,n){r=r||"";if(e){if(e[e.length-1]!=="/"&&r[0]!=="/"){e+="/"}r=e+r}if(n){var t=urlParse(n);if(!t){throw new Error("sourceMapURL could not be parsed")}if(t.path){var o=t.path.lastIndexOf("/");if(o>=0){t.path=t.path.substring(0,o+1)}}r=join(urlGenerate(t),r)}return normalize(r)}r.computeSourceURL=computeSourceURL},997:(e,r,n)=>{n(591).h;r.SourceMapConsumer=n(952).SourceMapConsumer;n(351)},284:(e,r,n)=>{e=n.nmd(e);var t=n(997).SourceMapConsumer;var o=n(17);var i;try{i=n(147);if(!i.existsSync||!i.readFileSync){i=null}}catch(e){}var a=n(650);function dynamicRequire(e,r){return e.require(r)}var u=false;var s=false;var l=false;var c="auto";var p={};var f={};var g=/^data:application\/json[^,]+base64,/;var h=[];var d=[];function isInBrowser(){if(c==="browser")return true;if(c==="node")return false;return typeof window!=="undefined"&&typeof XMLHttpRequest==="function"&&!(window.require&&window.module&&window.process&&window.process.type==="renderer")}function hasGlobalProcessEventEmitter(){return typeof process==="object"&&process!==null&&typeof process.on==="function"}function globalProcessVersion(){if(typeof process==="object"&&process!==null){return process.version}else{return""}}function globalProcessStderr(){if(typeof process==="object"&&process!==null){return process.stderr}}function globalProcessExit(e){if(typeof process==="object"&&process!==null&&typeof process.exit==="function"){return process.exit(e)}}function handlerExec(e){return function(r){for(var n=0;n"}var n=this.getLineNumber();if(n!=null){r+=":"+n;var t=this.getColumnNumber();if(t){r+=":"+t}}}var o="";var i=this.getFunctionName();var a=true;var u=this.isConstructor();var s=!(this.isToplevel()||u);if(s){var l=this.getTypeName();if(l==="[object Object]"){l="null"}var c=this.getMethodName();if(i){if(l&&i.indexOf(l)!=0){o+=l+"."}o+=i;if(c&&i.indexOf("."+c)!=i.length-c.length-1){o+=" [as "+c+"]"}}else{o+=l+"."+(c||"")}}else if(u){o+="new "+(i||"")}else if(i){o+=i}else{o+=r;a=false}if(a){o+=" ("+r+")"}return o}function cloneCallSite(e){var r={};Object.getOwnPropertyNames(Object.getPrototypeOf(e)).forEach((function(n){r[n]=/^(?:is|get)/.test(n)?function(){return e[n].call(e)}:e[n]}));r.toString=CallSiteToString;return r}function wrapCallSite(e,r){if(r===undefined){r={nextPosition:null,curPosition:null}}if(e.isNative()){r.curPosition=null;return e}var n=e.getFileName()||e.getScriptNameOrSourceURL();if(n){var t=e.getLineNumber();var o=e.getColumnNumber()-1;var i=/^v(10\.1[6-9]|10\.[2-9][0-9]|10\.[0-9]{3,}|1[2-9]\d*|[2-9]\d|\d{3,}|11\.11)/;var a=i.test(globalProcessVersion())?0:62;if(t===1&&o>a&&!isInBrowser()&&!e.isEval()){o-=a}var u=mapSourcePosition({source:n,line:t,column:o});r.curPosition=u;e=cloneCallSite(e);var s=e.getFunctionName;e.getFunctionName=function(){if(r.nextPosition==null){return s()}return r.nextPosition.name||s()};e.getFileName=function(){return u.source};e.getLineNumber=function(){return u.line};e.getColumnNumber=function(){return u.column+1};e.getScriptNameOrSourceURL=function(){return u.source};return e}var l=e.isEval()&&e.getEvalOrigin();if(l){l=mapEvalOrigin(l);e=cloneCallSite(e);e.getEvalOrigin=function(){return l};return e}return e}function prepareStackTrace(e,r){if(l){p={};f={}}var n=e.name||"Error";var t=e.message||"";var o=n+": "+t;var i={nextPosition:null,curPosition:null};var a=[];for(var u=r.length-1;u>=0;u--){a.push("\n at "+wrapCallSite(r[u],i));i.nextPosition=i.curPosition}i.curPosition=i.nextPosition=null;return o+a.reverse().join("")}function getErrorSource(e){var r=/\n at [^(]+ \((.*):(\d+):(\d+)\)/.exec(e.stack);if(r){var n=r[1];var t=+r[2];var o=+r[3];var a=p[n];if(!a&&i&&i.existsSync(n)){try{a=i.readFileSync(n,"utf8")}catch(e){a=""}}if(a){var u=a.split(/(?:\r\n|\r|\n)/)[t-1];if(u){return n+":"+t+"\n"+u+"\n"+new Array(o).join(" ")+"^"}}}return null}function printErrorAndExit(e){var r=getErrorSource(e);var n=globalProcessStderr();if(n&&n._handle&&n._handle.setBlocking){n._handle.setBlocking(true)}if(r){console.error();console.error(r)}console.error(e.stack);globalProcessExit(1)}function shimEmitUncaughtException(){var e=process.emit;process.emit=function(r){if(r==="uncaughtException"){var n=arguments[1]&&arguments[1].stack;var t=this.listeners(r).length>0;if(n&&!t){return printErrorAndExit(arguments[1])}}return e.apply(this,arguments)}}var S=h.slice(0);var _=d.slice(0);r.wrapCallSite=wrapCallSite;r.getErrorSource=getErrorSource;r.mapSourcePosition=mapSourcePosition;r.retrieveSourceMap=v;r.install=function(r){r=r||{};if(r.environment){c=r.environment;if(["node","browser","auto"].indexOf(c)===-1){throw new Error("environment "+c+" was unknown. Available options are {auto, browser, node}")}}if(r.retrieveFile){if(r.overrideRetrieveFile){h.length=0}h.unshift(r.retrieveFile)}if(r.retrieveSourceMap){if(r.overrideRetrieveSourceMap){d.length=0}d.unshift(r.retrieveSourceMap)}if(r.hookRequire&&!isInBrowser()){var n=dynamicRequire(e,"module");var t=n.prototype._compile;if(!t.__sourceMapSupport){n.prototype._compile=function(e,r){p[r]=e;f[r]=undefined;return t.call(this,e,r)};n.prototype._compile.__sourceMapSupport=true}}if(!l){l="emptyCacheBetweenOperations"in r?r.emptyCacheBetweenOperations:false}if(!u){u=true;Error.prepareStackTrace=prepareStackTrace}if(!s){var o="handleUncaughtExceptions"in r?r.handleUncaughtExceptions:true;try{var i=dynamicRequire(e,"worker_threads");if(i.isMainThread===false){o=false}}catch(e){}if(o&&hasGlobalProcessEventEmitter()){s=true;shimEmitUncaughtException()}}};r.resetRetrieveHandlers=function(){h.length=0;d.length=0;h=S.slice(0);d=_.slice(0);v=handlerExec(d);m=handlerExec(h)}},147:e=>{"use strict";e.exports=require("fs")},17:e=>{"use strict";e.exports=require("path")}};var r={};function __webpack_require__(n){var t=r[n];if(t!==undefined){return t.exports}var o=r[n]={id:n,loaded:false,exports:{}};var i=true;try{e[n](o,o.exports,__webpack_require__);i=false}finally{if(i)delete r[n]}o.loaded=true;return o.exports}(()=>{__webpack_require__.nmd=e=>{e.paths=[];if(!e.children)e.children=[];return e}})();if(typeof __webpack_require__!=="undefined")__webpack_require__.ab=__dirname+"/";var n={};(()=>{__webpack_require__(284).install()})();module.exports=n})(); -------------------------------------------------------------------------------- /lib/node-v115-darwin-arm64/nanoutimes.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/irgaly/xcode-cache/7d303a62f4d1701699190a51e595234e3fe534b5/lib/node-v115-darwin-arm64/nanoutimes.node -------------------------------------------------------------------------------- /lib/node-v115-darwin-x64/nanoutimes.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/irgaly/xcode-cache/7d303a62f4d1701699190a51e595234e3fe534b5/lib/node-v115-darwin-x64/nanoutimes.node -------------------------------------------------------------------------------- /lib/node-v120-darwin-arm64/nanoutimes.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/irgaly/xcode-cache/7d303a62f4d1701699190a51e595234e3fe534b5/lib/node-v120-darwin-arm64/nanoutimes.node -------------------------------------------------------------------------------- /lib/node-v93-darwin-arm64/nanoutimes.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/irgaly/xcode-cache/7d303a62f4d1701699190a51e595234e3fe534b5/lib/node-v93-darwin-arm64/nanoutimes.node -------------------------------------------------------------------------------- /lib/node-v93-darwin-x64/nanoutimes.node: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/irgaly/xcode-cache/7d303a62f4d1701699190a51e595234e3fe534b5/lib/node-v93-darwin-x64/nanoutimes.node -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "xcode-cache", 3 | "version": "1.9.0", 4 | "main": "dist/main/index.js", 5 | "private": true, 6 | "license": "Apache-2.0", 7 | "scripts": { 8 | "build": "ncc build src/main.ts -o dist/main --source-map --license licenses.txt && ncc build src/post.ts -o dist/post --source-map --license licenses.txt && ln -sf ../lib dist/", 9 | "main": "ts-node src/main.ts", 10 | "post": "ts-node src/post.ts" 11 | }, 12 | "dependencies": { 13 | "@actions/cache": "4.0.0", 14 | "@actions/core": "1.11.1", 15 | "@actions/exec": "1.1.1", 16 | "@actions/glob": "0.5.0", 17 | "@actions/github": "6.0.0" 18 | }, 19 | "devDependencies": { 20 | "@types/node": "22.14.0", 21 | "@vercel/ncc": "0.38.0", 22 | "ts-node": "10.9.1", 23 | "typescript": "5.8.3" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "config:recommended", 4 | "schedule:quarterly" 5 | ], 6 | "packageRules": [ 7 | { 8 | "matchUpdateTypes": [ 9 | "patch" 10 | ], 11 | "enabled": false 12 | }, 13 | { 14 | "groupName": "node", 15 | "enabled": false, 16 | "matchPackageNames": [ 17 | "node" 18 | ] 19 | }, 20 | { 21 | "groupName": "@actions", 22 | "matchPackageNames": [ 23 | "@actions/*" 24 | ] 25 | } 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /sample/MyApp/Localizable.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /sample/MyApp/MyApp.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 56; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 90064A332AB1C304007E9376 /* MyAppApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90064A322AB1C304007E9376 /* MyAppApp.swift */; }; 11 | 90064A352AB1C304007E9376 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90064A342AB1C304007E9376 /* ContentView.swift */; }; 12 | 90064A372AB1C305007E9376 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 90064A362AB1C305007E9376 /* Assets.xcassets */; }; 13 | 90064A3A2AB1C305007E9376 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 90064A392AB1C305007E9376 /* Preview Assets.xcassets */; }; 14 | 90064A512AB1C3D3007E9376 /* MyLibrary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 90064A4B2AB1C3D3007E9376 /* MyLibrary.framework */; }; 15 | 90064A522AB1C3D3007E9376 /* MyLibrary.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 90064A4B2AB1C3D3007E9376 /* MyLibrary.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 16 | 90064A582AB1C437007E9376 /* MyLibrary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90064A572AB1C437007E9376 /* MyLibrary.swift */; }; 17 | 90064A5A2AB1C451007E9376 /* PropertyList.plist in Resources */ = {isa = PBXBuildFile; fileRef = 90064A592AB1C451007E9376 /* PropertyList.plist */; }; 18 | 90064A5D2AB1C460007E9376 /* Model.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 90064A5B2AB1C460007E9376 /* Model.xcdatamodeld */; }; 19 | 90064A5F2AB1C485007E9376 /* View.xib in Resources */ = {isa = PBXBuildFile; fileRef = 90064A5E2AB1C485007E9376 /* View.xib */; }; 20 | 90064A612AB1C490007E9376 /* Storyboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 90064A602AB1C490007E9376 /* Storyboard.storyboard */; }; 21 | 90064A632AB1C4AA007E9376 /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 90064A622AB1C4AA007E9376 /* Settings.bundle */; }; 22 | 90064A652AB1C4C3007E9376 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 90064A642AB1C4C3007E9376 /* Localizable.strings */; }; 23 | 90CBC6332AB1C6D500646C39 /* Reusable in Frameworks */ = {isa = PBXBuildFile; productRef = 90CBC6322AB1C6D500646C39 /* Reusable */; }; 24 | 90CBC6362AB1C6FC00646C39 /* FLEX in Frameworks */ = {isa = PBXBuildFile; productRef = 90CBC6352AB1C6FC00646C39 /* FLEX */; }; 25 | /* End PBXBuildFile section */ 26 | 27 | /* Begin PBXContainerItemProxy section */ 28 | 90064A4F2AB1C3D3007E9376 /* PBXContainerItemProxy */ = { 29 | isa = PBXContainerItemProxy; 30 | containerPortal = 90064A272AB1C304007E9376 /* Project object */; 31 | proxyType = 1; 32 | remoteGlobalIDString = 90064A4A2AB1C3D3007E9376; 33 | remoteInfo = MyLibrary; 34 | }; 35 | /* End PBXContainerItemProxy section */ 36 | 37 | /* Begin PBXCopyFilesBuildPhase section */ 38 | 90064A562AB1C3D3007E9376 /* Embed Frameworks */ = { 39 | isa = PBXCopyFilesBuildPhase; 40 | buildActionMask = 2147483647; 41 | dstPath = ""; 42 | dstSubfolderSpec = 10; 43 | files = ( 44 | 90064A522AB1C3D3007E9376 /* MyLibrary.framework in Embed Frameworks */, 45 | ); 46 | name = "Embed Frameworks"; 47 | runOnlyForDeploymentPostprocessing = 0; 48 | }; 49 | /* End PBXCopyFilesBuildPhase section */ 50 | 51 | /* Begin PBXFileReference section */ 52 | 90064A2F2AB1C304007E9376 /* MyApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MyApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; 53 | 90064A322AB1C304007E9376 /* MyAppApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyAppApp.swift; sourceTree = ""; }; 54 | 90064A342AB1C304007E9376 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; 55 | 90064A362AB1C305007E9376 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 56 | 90064A392AB1C305007E9376 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; 57 | 90064A4B2AB1C3D3007E9376 /* MyLibrary.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MyLibrary.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 58 | 90064A572AB1C437007E9376 /* MyLibrary.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyLibrary.swift; sourceTree = ""; }; 59 | 90064A592AB1C451007E9376 /* PropertyList.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = PropertyList.plist; sourceTree = ""; }; 60 | 90064A5C2AB1C460007E9376 /* Model.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Model.xcdatamodel; sourceTree = ""; }; 61 | 90064A5E2AB1C485007E9376 /* View.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = View.xib; sourceTree = ""; }; 62 | 90064A602AB1C490007E9376 /* Storyboard.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Storyboard.storyboard; sourceTree = ""; }; 63 | 90064A622AB1C4AA007E9376 /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = ""; }; 64 | 90064A642AB1C4C3007E9376 /* Localizable.strings */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; path = Localizable.strings; sourceTree = ""; }; 65 | /* End PBXFileReference section */ 66 | 67 | /* Begin PBXFrameworksBuildPhase section */ 68 | 90064A2C2AB1C304007E9376 /* Frameworks */ = { 69 | isa = PBXFrameworksBuildPhase; 70 | buildActionMask = 2147483647; 71 | files = ( 72 | 90064A512AB1C3D3007E9376 /* MyLibrary.framework in Frameworks */, 73 | 90CBC6332AB1C6D500646C39 /* Reusable in Frameworks */, 74 | 90CBC6362AB1C6FC00646C39 /* FLEX in Frameworks */, 75 | ); 76 | runOnlyForDeploymentPostprocessing = 0; 77 | }; 78 | 90064A482AB1C3D3007E9376 /* Frameworks */ = { 79 | isa = PBXFrameworksBuildPhase; 80 | buildActionMask = 2147483647; 81 | files = ( 82 | ); 83 | runOnlyForDeploymentPostprocessing = 0; 84 | }; 85 | /* End PBXFrameworksBuildPhase section */ 86 | 87 | /* Begin PBXGroup section */ 88 | 90064A262AB1C304007E9376 = { 89 | isa = PBXGroup; 90 | children = ( 91 | 90064A642AB1C4C3007E9376 /* Localizable.strings */, 92 | 90064A622AB1C4AA007E9376 /* Settings.bundle */, 93 | 90064A312AB1C304007E9376 /* MyApp */, 94 | 90064A4C2AB1C3D3007E9376 /* MyLibrary */, 95 | 90064A302AB1C304007E9376 /* Products */, 96 | ); 97 | sourceTree = ""; 98 | }; 99 | 90064A302AB1C304007E9376 /* Products */ = { 100 | isa = PBXGroup; 101 | children = ( 102 | 90064A2F2AB1C304007E9376 /* MyApp.app */, 103 | 90064A4B2AB1C3D3007E9376 /* MyLibrary.framework */, 104 | ); 105 | name = Products; 106 | sourceTree = ""; 107 | }; 108 | 90064A312AB1C304007E9376 /* MyApp */ = { 109 | isa = PBXGroup; 110 | children = ( 111 | 90064A322AB1C304007E9376 /* MyAppApp.swift */, 112 | 90064A342AB1C304007E9376 /* ContentView.swift */, 113 | 90064A362AB1C305007E9376 /* Assets.xcassets */, 114 | 90064A382AB1C305007E9376 /* Preview Content */, 115 | 90064A592AB1C451007E9376 /* PropertyList.plist */, 116 | 90064A5B2AB1C460007E9376 /* Model.xcdatamodeld */, 117 | 90064A5E2AB1C485007E9376 /* View.xib */, 118 | 90064A602AB1C490007E9376 /* Storyboard.storyboard */, 119 | ); 120 | path = MyApp; 121 | sourceTree = ""; 122 | }; 123 | 90064A382AB1C305007E9376 /* Preview Content */ = { 124 | isa = PBXGroup; 125 | children = ( 126 | 90064A392AB1C305007E9376 /* Preview Assets.xcassets */, 127 | ); 128 | path = "Preview Content"; 129 | sourceTree = ""; 130 | }; 131 | 90064A4C2AB1C3D3007E9376 /* MyLibrary */ = { 132 | isa = PBXGroup; 133 | children = ( 134 | 90064A572AB1C437007E9376 /* MyLibrary.swift */, 135 | ); 136 | path = MyLibrary; 137 | sourceTree = ""; 138 | }; 139 | /* End PBXGroup section */ 140 | 141 | /* Begin PBXHeadersBuildPhase section */ 142 | 90064A462AB1C3D3007E9376 /* Headers */ = { 143 | isa = PBXHeadersBuildPhase; 144 | buildActionMask = 2147483647; 145 | files = ( 146 | ); 147 | runOnlyForDeploymentPostprocessing = 0; 148 | }; 149 | /* End PBXHeadersBuildPhase section */ 150 | 151 | /* Begin PBXNativeTarget section */ 152 | 90064A2E2AB1C304007E9376 /* MyApp */ = { 153 | isa = PBXNativeTarget; 154 | buildConfigurationList = 90064A3D2AB1C305007E9376 /* Build configuration list for PBXNativeTarget "MyApp" */; 155 | buildPhases = ( 156 | 90064A2B2AB1C304007E9376 /* Sources */, 157 | 90064A2C2AB1C304007E9376 /* Frameworks */, 158 | 90064A2D2AB1C304007E9376 /* Resources */, 159 | 90064A562AB1C3D3007E9376 /* Embed Frameworks */, 160 | ); 161 | buildRules = ( 162 | ); 163 | dependencies = ( 164 | 90064A502AB1C3D3007E9376 /* PBXTargetDependency */, 165 | ); 166 | name = MyApp; 167 | packageProductDependencies = ( 168 | 90CBC6322AB1C6D500646C39 /* Reusable */, 169 | 90CBC6352AB1C6FC00646C39 /* FLEX */, 170 | ); 171 | productName = MyApp; 172 | productReference = 90064A2F2AB1C304007E9376 /* MyApp.app */; 173 | productType = "com.apple.product-type.application"; 174 | }; 175 | 90064A4A2AB1C3D3007E9376 /* MyLibrary */ = { 176 | isa = PBXNativeTarget; 177 | buildConfigurationList = 90064A532AB1C3D3007E9376 /* Build configuration list for PBXNativeTarget "MyLibrary" */; 178 | buildPhases = ( 179 | 90064A462AB1C3D3007E9376 /* Headers */, 180 | 90064A472AB1C3D3007E9376 /* Sources */, 181 | 90064A482AB1C3D3007E9376 /* Frameworks */, 182 | 90064A492AB1C3D3007E9376 /* Resources */, 183 | ); 184 | buildRules = ( 185 | ); 186 | dependencies = ( 187 | ); 188 | name = MyLibrary; 189 | productName = MyLibrary; 190 | productReference = 90064A4B2AB1C3D3007E9376 /* MyLibrary.framework */; 191 | productType = "com.apple.product-type.framework"; 192 | }; 193 | /* End PBXNativeTarget section */ 194 | 195 | /* Begin PBXProject section */ 196 | 90064A272AB1C304007E9376 /* Project object */ = { 197 | isa = PBXProject; 198 | attributes = { 199 | BuildIndependentTargetsInParallel = 1; 200 | LastSwiftUpdateCheck = 1430; 201 | LastUpgradeCheck = 1430; 202 | TargetAttributes = { 203 | 90064A2E2AB1C304007E9376 = { 204 | CreatedOnToolsVersion = 14.3.1; 205 | }; 206 | 90064A4A2AB1C3D3007E9376 = { 207 | CreatedOnToolsVersion = 14.3.1; 208 | LastSwiftMigration = 1430; 209 | }; 210 | }; 211 | }; 212 | buildConfigurationList = 90064A2A2AB1C304007E9376 /* Build configuration list for PBXProject "MyApp" */; 213 | compatibilityVersion = "Xcode 14.0"; 214 | developmentRegion = en; 215 | hasScannedForEncodings = 0; 216 | knownRegions = ( 217 | en, 218 | Base, 219 | ); 220 | mainGroup = 90064A262AB1C304007E9376; 221 | packageReferences = ( 222 | 90CBC6312AB1C6D500646C39 /* XCRemoteSwiftPackageReference "Reusable" */, 223 | 90CBC6342AB1C6FC00646C39 /* XCRemoteSwiftPackageReference "FLEX" */, 224 | ); 225 | productRefGroup = 90064A302AB1C304007E9376 /* Products */; 226 | projectDirPath = ""; 227 | projectRoot = ""; 228 | targets = ( 229 | 90064A2E2AB1C304007E9376 /* MyApp */, 230 | 90064A4A2AB1C3D3007E9376 /* MyLibrary */, 231 | ); 232 | }; 233 | /* End PBXProject section */ 234 | 235 | /* Begin PBXResourcesBuildPhase section */ 236 | 90064A2D2AB1C304007E9376 /* Resources */ = { 237 | isa = PBXResourcesBuildPhase; 238 | buildActionMask = 2147483647; 239 | files = ( 240 | 90064A5F2AB1C485007E9376 /* View.xib in Resources */, 241 | 90064A3A2AB1C305007E9376 /* Preview Assets.xcassets in Resources */, 242 | 90064A5A2AB1C451007E9376 /* PropertyList.plist in Resources */, 243 | 90064A652AB1C4C3007E9376 /* Localizable.strings in Resources */, 244 | 90064A372AB1C305007E9376 /* Assets.xcassets in Resources */, 245 | 90064A632AB1C4AA007E9376 /* Settings.bundle in Resources */, 246 | 90064A612AB1C490007E9376 /* Storyboard.storyboard in Resources */, 247 | ); 248 | runOnlyForDeploymentPostprocessing = 0; 249 | }; 250 | 90064A492AB1C3D3007E9376 /* Resources */ = { 251 | isa = PBXResourcesBuildPhase; 252 | buildActionMask = 2147483647; 253 | files = ( 254 | ); 255 | runOnlyForDeploymentPostprocessing = 0; 256 | }; 257 | /* End PBXResourcesBuildPhase section */ 258 | 259 | /* Begin PBXSourcesBuildPhase section */ 260 | 90064A2B2AB1C304007E9376 /* Sources */ = { 261 | isa = PBXSourcesBuildPhase; 262 | buildActionMask = 2147483647; 263 | files = ( 264 | 90064A352AB1C304007E9376 /* ContentView.swift in Sources */, 265 | 90064A332AB1C304007E9376 /* MyAppApp.swift in Sources */, 266 | 90064A5D2AB1C460007E9376 /* Model.xcdatamodeld in Sources */, 267 | ); 268 | runOnlyForDeploymentPostprocessing = 0; 269 | }; 270 | 90064A472AB1C3D3007E9376 /* Sources */ = { 271 | isa = PBXSourcesBuildPhase; 272 | buildActionMask = 2147483647; 273 | files = ( 274 | 90064A582AB1C437007E9376 /* MyLibrary.swift in Sources */, 275 | ); 276 | runOnlyForDeploymentPostprocessing = 0; 277 | }; 278 | /* End PBXSourcesBuildPhase section */ 279 | 280 | /* Begin PBXTargetDependency section */ 281 | 90064A502AB1C3D3007E9376 /* PBXTargetDependency */ = { 282 | isa = PBXTargetDependency; 283 | target = 90064A4A2AB1C3D3007E9376 /* MyLibrary */; 284 | targetProxy = 90064A4F2AB1C3D3007E9376 /* PBXContainerItemProxy */; 285 | }; 286 | /* End PBXTargetDependency section */ 287 | 288 | /* Begin XCBuildConfiguration section */ 289 | 90064A3B2AB1C305007E9376 /* Debug */ = { 290 | isa = XCBuildConfiguration; 291 | buildSettings = { 292 | ALWAYS_SEARCH_USER_PATHS = NO; 293 | CLANG_ANALYZER_NONNULL = YES; 294 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 295 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 296 | CLANG_ENABLE_MODULES = YES; 297 | CLANG_ENABLE_OBJC_ARC = YES; 298 | CLANG_ENABLE_OBJC_WEAK = YES; 299 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 300 | CLANG_WARN_BOOL_CONVERSION = YES; 301 | CLANG_WARN_COMMA = YES; 302 | CLANG_WARN_CONSTANT_CONVERSION = YES; 303 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 304 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 305 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 306 | CLANG_WARN_EMPTY_BODY = YES; 307 | CLANG_WARN_ENUM_CONVERSION = YES; 308 | CLANG_WARN_INFINITE_RECURSION = YES; 309 | CLANG_WARN_INT_CONVERSION = YES; 310 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 311 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 312 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 313 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 314 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 315 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 316 | CLANG_WARN_STRICT_PROTOTYPES = YES; 317 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 318 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 319 | CLANG_WARN_UNREACHABLE_CODE = YES; 320 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 321 | COPY_PHASE_STRIP = NO; 322 | DEBUG_INFORMATION_FORMAT = dwarf; 323 | ENABLE_STRICT_OBJC_MSGSEND = YES; 324 | ENABLE_TESTABILITY = YES; 325 | GCC_C_LANGUAGE_STANDARD = gnu11; 326 | GCC_DYNAMIC_NO_PIC = NO; 327 | GCC_NO_COMMON_BLOCKS = YES; 328 | GCC_OPTIMIZATION_LEVEL = 0; 329 | GCC_PREPROCESSOR_DEFINITIONS = ( 330 | "DEBUG=1", 331 | "$(inherited)", 332 | ); 333 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 334 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 335 | GCC_WARN_UNDECLARED_SELECTOR = YES; 336 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 337 | GCC_WARN_UNUSED_FUNCTION = YES; 338 | GCC_WARN_UNUSED_VARIABLE = YES; 339 | IPHONEOS_DEPLOYMENT_TARGET = 16.4; 340 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 341 | MTL_FAST_MATH = YES; 342 | ONLY_ACTIVE_ARCH = YES; 343 | OTHER_SWIFT_FLAGS = "-driver-show-incremental"; 344 | SDKROOT = iphoneos; 345 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 346 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 347 | }; 348 | name = Debug; 349 | }; 350 | 90064A3C2AB1C305007E9376 /* Release */ = { 351 | isa = XCBuildConfiguration; 352 | buildSettings = { 353 | ALWAYS_SEARCH_USER_PATHS = NO; 354 | CLANG_ANALYZER_NONNULL = YES; 355 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 356 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 357 | CLANG_ENABLE_MODULES = YES; 358 | CLANG_ENABLE_OBJC_ARC = YES; 359 | CLANG_ENABLE_OBJC_WEAK = YES; 360 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 361 | CLANG_WARN_BOOL_CONVERSION = YES; 362 | CLANG_WARN_COMMA = YES; 363 | CLANG_WARN_CONSTANT_CONVERSION = YES; 364 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 365 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 366 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 367 | CLANG_WARN_EMPTY_BODY = YES; 368 | CLANG_WARN_ENUM_CONVERSION = YES; 369 | CLANG_WARN_INFINITE_RECURSION = YES; 370 | CLANG_WARN_INT_CONVERSION = YES; 371 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 372 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 373 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 374 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 375 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 376 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 377 | CLANG_WARN_STRICT_PROTOTYPES = YES; 378 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 379 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 380 | CLANG_WARN_UNREACHABLE_CODE = YES; 381 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 382 | COPY_PHASE_STRIP = NO; 383 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 384 | ENABLE_NS_ASSERTIONS = NO; 385 | ENABLE_STRICT_OBJC_MSGSEND = YES; 386 | GCC_C_LANGUAGE_STANDARD = gnu11; 387 | GCC_NO_COMMON_BLOCKS = YES; 388 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 389 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 390 | GCC_WARN_UNDECLARED_SELECTOR = YES; 391 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 392 | GCC_WARN_UNUSED_FUNCTION = YES; 393 | GCC_WARN_UNUSED_VARIABLE = YES; 394 | IPHONEOS_DEPLOYMENT_TARGET = 16.4; 395 | MTL_ENABLE_DEBUG_INFO = NO; 396 | MTL_FAST_MATH = YES; 397 | OTHER_SWIFT_FLAGS = "-driver-show-incremental"; 398 | SDKROOT = iphoneos; 399 | SWIFT_COMPILATION_MODE = wholemodule; 400 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 401 | VALIDATE_PRODUCT = YES; 402 | }; 403 | name = Release; 404 | }; 405 | 90064A3E2AB1C305007E9376 /* Debug */ = { 406 | isa = XCBuildConfiguration; 407 | buildSettings = { 408 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 409 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 410 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 411 | CODE_SIGN_STYLE = Automatic; 412 | CURRENT_PROJECT_VERSION = 1; 413 | DEVELOPMENT_ASSET_PATHS = "\"MyApp/Preview Content\""; 414 | ENABLE_PREVIEWS = YES; 415 | GENERATE_INFOPLIST_FILE = YES; 416 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; 417 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 418 | INFOPLIST_KEY_UILaunchScreen_Generation = YES; 419 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 420 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 421 | LD_RUNPATH_SEARCH_PATHS = ( 422 | "$(inherited)", 423 | "@executable_path/Frameworks", 424 | ); 425 | MARKETING_VERSION = 1.0; 426 | PRODUCT_BUNDLE_IDENTIFIER = io.github.irgaly.MyApp; 427 | PRODUCT_NAME = "$(TARGET_NAME)"; 428 | SWIFT_EMIT_LOC_STRINGS = YES; 429 | SWIFT_VERSION = 5.0; 430 | TARGETED_DEVICE_FAMILY = "1,2"; 431 | }; 432 | name = Debug; 433 | }; 434 | 90064A3F2AB1C305007E9376 /* Release */ = { 435 | isa = XCBuildConfiguration; 436 | buildSettings = { 437 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 438 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 439 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 440 | CODE_SIGN_STYLE = Automatic; 441 | CURRENT_PROJECT_VERSION = 1; 442 | DEVELOPMENT_ASSET_PATHS = "\"MyApp/Preview Content\""; 443 | ENABLE_PREVIEWS = YES; 444 | GENERATE_INFOPLIST_FILE = YES; 445 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; 446 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 447 | INFOPLIST_KEY_UILaunchScreen_Generation = YES; 448 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 449 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 450 | LD_RUNPATH_SEARCH_PATHS = ( 451 | "$(inherited)", 452 | "@executable_path/Frameworks", 453 | ); 454 | MARKETING_VERSION = 1.0; 455 | PRODUCT_BUNDLE_IDENTIFIER = io.github.irgaly.MyApp; 456 | PRODUCT_NAME = "$(TARGET_NAME)"; 457 | SWIFT_EMIT_LOC_STRINGS = YES; 458 | SWIFT_VERSION = 5.0; 459 | TARGETED_DEVICE_FAMILY = "1,2"; 460 | }; 461 | name = Release; 462 | }; 463 | 90064A542AB1C3D3007E9376 /* Debug */ = { 464 | isa = XCBuildConfiguration; 465 | buildSettings = { 466 | CLANG_ENABLE_MODULES = YES; 467 | CODE_SIGN_STYLE = Automatic; 468 | CURRENT_PROJECT_VERSION = 1; 469 | DEFINES_MODULE = YES; 470 | DYLIB_COMPATIBILITY_VERSION = 1; 471 | DYLIB_CURRENT_VERSION = 1; 472 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 473 | ENABLE_MODULE_VERIFIER = YES; 474 | GENERATE_INFOPLIST_FILE = YES; 475 | INFOPLIST_KEY_NSHumanReadableCopyright = ""; 476 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 477 | LD_RUNPATH_SEARCH_PATHS = ( 478 | "$(inherited)", 479 | "@executable_path/Frameworks", 480 | "@loader_path/Frameworks", 481 | ); 482 | MARKETING_VERSION = 1.0; 483 | MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; 484 | MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++20"; 485 | PRODUCT_BUNDLE_IDENTIFIER = io.github.irgaly.MyLibrary; 486 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 487 | SKIP_INSTALL = YES; 488 | SWIFT_EMIT_LOC_STRINGS = YES; 489 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 490 | SWIFT_VERSION = 5.0; 491 | TARGETED_DEVICE_FAMILY = "1,2"; 492 | VERSIONING_SYSTEM = "apple-generic"; 493 | VERSION_INFO_PREFIX = ""; 494 | }; 495 | name = Debug; 496 | }; 497 | 90064A552AB1C3D3007E9376 /* Release */ = { 498 | isa = XCBuildConfiguration; 499 | buildSettings = { 500 | CLANG_ENABLE_MODULES = YES; 501 | CODE_SIGN_STYLE = Automatic; 502 | CURRENT_PROJECT_VERSION = 1; 503 | DEFINES_MODULE = YES; 504 | DYLIB_COMPATIBILITY_VERSION = 1; 505 | DYLIB_CURRENT_VERSION = 1; 506 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 507 | ENABLE_MODULE_VERIFIER = YES; 508 | GENERATE_INFOPLIST_FILE = YES; 509 | INFOPLIST_KEY_NSHumanReadableCopyright = ""; 510 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 511 | LD_RUNPATH_SEARCH_PATHS = ( 512 | "$(inherited)", 513 | "@executable_path/Frameworks", 514 | "@loader_path/Frameworks", 515 | ); 516 | MARKETING_VERSION = 1.0; 517 | MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; 518 | MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++20"; 519 | PRODUCT_BUNDLE_IDENTIFIER = io.github.irgaly.MyLibrary; 520 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 521 | SKIP_INSTALL = YES; 522 | SWIFT_EMIT_LOC_STRINGS = YES; 523 | SWIFT_VERSION = 5.0; 524 | TARGETED_DEVICE_FAMILY = "1,2"; 525 | VERSIONING_SYSTEM = "apple-generic"; 526 | VERSION_INFO_PREFIX = ""; 527 | }; 528 | name = Release; 529 | }; 530 | /* End XCBuildConfiguration section */ 531 | 532 | /* Begin XCConfigurationList section */ 533 | 90064A2A2AB1C304007E9376 /* Build configuration list for PBXProject "MyApp" */ = { 534 | isa = XCConfigurationList; 535 | buildConfigurations = ( 536 | 90064A3B2AB1C305007E9376 /* Debug */, 537 | 90064A3C2AB1C305007E9376 /* Release */, 538 | ); 539 | defaultConfigurationIsVisible = 0; 540 | defaultConfigurationName = Release; 541 | }; 542 | 90064A3D2AB1C305007E9376 /* Build configuration list for PBXNativeTarget "MyApp" */ = { 543 | isa = XCConfigurationList; 544 | buildConfigurations = ( 545 | 90064A3E2AB1C305007E9376 /* Debug */, 546 | 90064A3F2AB1C305007E9376 /* Release */, 547 | ); 548 | defaultConfigurationIsVisible = 0; 549 | defaultConfigurationName = Release; 550 | }; 551 | 90064A532AB1C3D3007E9376 /* Build configuration list for PBXNativeTarget "MyLibrary" */ = { 552 | isa = XCConfigurationList; 553 | buildConfigurations = ( 554 | 90064A542AB1C3D3007E9376 /* Debug */, 555 | 90064A552AB1C3D3007E9376 /* Release */, 556 | ); 557 | defaultConfigurationIsVisible = 0; 558 | defaultConfigurationName = Release; 559 | }; 560 | /* End XCConfigurationList section */ 561 | 562 | /* Begin XCRemoteSwiftPackageReference section */ 563 | 90CBC6312AB1C6D500646C39 /* XCRemoteSwiftPackageReference "Reusable" */ = { 564 | isa = XCRemoteSwiftPackageReference; 565 | repositoryURL = "https://github.com/AliSoftware/Reusable.git"; 566 | requirement = { 567 | kind = exactVersion; 568 | version = 4.1.2; 569 | }; 570 | }; 571 | 90CBC6342AB1C6FC00646C39 /* XCRemoteSwiftPackageReference "FLEX" */ = { 572 | isa = XCRemoteSwiftPackageReference; 573 | repositoryURL = "https://github.com/FLEXTool/FLEX.git"; 574 | requirement = { 575 | kind = exactVersion; 576 | version = 5.22.10; 577 | }; 578 | }; 579 | /* End XCRemoteSwiftPackageReference section */ 580 | 581 | /* Begin XCSwiftPackageProductDependency section */ 582 | 90CBC6322AB1C6D500646C39 /* Reusable */ = { 583 | isa = XCSwiftPackageProductDependency; 584 | package = 90CBC6312AB1C6D500646C39 /* XCRemoteSwiftPackageReference "Reusable" */; 585 | productName = Reusable; 586 | }; 587 | 90CBC6352AB1C6FC00646C39 /* FLEX */ = { 588 | isa = XCSwiftPackageProductDependency; 589 | package = 90CBC6342AB1C6FC00646C39 /* XCRemoteSwiftPackageReference "FLEX" */; 590 | productName = FLEX; 591 | }; 592 | /* End XCSwiftPackageProductDependency section */ 593 | 594 | /* Begin XCVersionGroup section */ 595 | 90064A5B2AB1C460007E9376 /* Model.xcdatamodeld */ = { 596 | isa = XCVersionGroup; 597 | children = ( 598 | 90064A5C2AB1C460007E9376 /* Model.xcdatamodel */, 599 | ); 600 | currentVersion = 90064A5C2AB1C460007E9376 /* Model.xcdatamodel */; 601 | path = Model.xcdatamodeld; 602 | sourceTree = ""; 603 | versionGroupType = wrapper.xcdatamodel; 604 | }; 605 | /* End XCVersionGroup section */ 606 | }; 607 | rootObject = 90064A272AB1C304007E9376 /* Project object */; 608 | } 609 | -------------------------------------------------------------------------------- /sample/MyApp/MyApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /sample/MyApp/MyApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /sample/MyApp/MyApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "pins" : [ 3 | { 4 | "identity" : "flex", 5 | "kind" : "remoteSourceControl", 6 | "location" : "https://github.com/FLEXTool/FLEX.git", 7 | "state" : { 8 | "revision" : "e0acf59d06d498041f65bbea1e5914b6e4b39733", 9 | "version" : "5.22.10" 10 | } 11 | }, 12 | { 13 | "identity" : "reusable", 14 | "kind" : "remoteSourceControl", 15 | "location" : "https://github.com/AliSoftware/Reusable.git", 16 | "state" : { 17 | "revision" : "18674709421360e210c2ecd4e8e08b217d4ea61d", 18 | "version" : "4.1.2" 19 | } 20 | } 21 | ], 22 | "version" : 2 23 | } 24 | -------------------------------------------------------------------------------- /sample/MyApp/MyApp/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /sample/MyApp/MyApp/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "platform" : "ios", 6 | "size" : "1024x1024" 7 | } 8 | ], 9 | "info" : { 10 | "author" : "xcode", 11 | "version" : 1 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /sample/MyApp/MyApp/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /sample/MyApp/MyApp/Assets.xcassets/sample.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "sample.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /sample/MyApp/MyApp/Assets.xcassets/sample.imageset/sample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/irgaly/xcode-cache/7d303a62f4d1701699190a51e595234e3fe534b5/sample/MyApp/MyApp/Assets.xcassets/sample.imageset/sample.png -------------------------------------------------------------------------------- /sample/MyApp/MyApp/ContentView.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct ContentView: View { 4 | var body: some View { 5 | VStack { 6 | Image(systemName: "globe") 7 | .imageScale(.large) 8 | .foregroundColor(.accentColor) 9 | Text("Hello, world!") 10 | } 11 | .padding() 12 | } 13 | } 14 | 15 | struct ContentView_Previews: PreviewProvider { 16 | static var previews: some View { 17 | ContentView() 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /sample/MyApp/MyApp/Model.xcdatamodeld/Model.xcdatamodel/contents: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /sample/MyApp/MyApp/MyAppApp.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | @main 4 | struct MyAppApp: App { 5 | var body: some Scene { 6 | WindowGroup { 7 | ContentView() 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /sample/MyApp/MyApp/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /sample/MyApp/MyApp/PropertyList.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /sample/MyApp/MyApp/Storyboard.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /sample/MyApp/MyApp/View.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /sample/MyApp/MyLibrary/MyLibrary.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | -------------------------------------------------------------------------------- /sample/MyApp/Settings.bundle/Root.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | StringsTable 6 | Root 7 | PreferenceSpecifiers 8 | 9 | 10 | Type 11 | PSGroupSpecifier 12 | Title 13 | Group 14 | 15 | 16 | Type 17 | PSTextFieldSpecifier 18 | Title 19 | Name 20 | Key 21 | name_preference 22 | DefaultValue 23 | 24 | IsSecure 25 | 26 | KeyboardType 27 | Alphabet 28 | AutocapitalizationType 29 | None 30 | AutocorrectionType 31 | No 32 | 33 | 34 | Type 35 | PSToggleSwitchSpecifier 36 | Title 37 | Enabled 38 | Key 39 | enabled_preference 40 | DefaultValue 41 | 42 | 43 | 44 | Type 45 | PSSliderSpecifier 46 | Key 47 | slider_preference 48 | DefaultValue 49 | 0.5 50 | MinimumValue 51 | 0 52 | MaximumValue 53 | 1 54 | MinimumValueImage 55 | 56 | MaximumValueImage 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /sample/MyApp/Settings.bundle/en.lproj/Root.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/irgaly/xcode-cache/7d303a62f4d1701699190a51e595234e3fe534b5/sample/MyApp/Settings.bundle/en.lproj/Root.strings -------------------------------------------------------------------------------- /src/input.ts: -------------------------------------------------------------------------------- 1 | import * as core from '@actions/core' 2 | import * as glob from '@actions/glob' 3 | import { hashFiles } from '@actions/glob' 4 | import * as fs from 'fs/promises' 5 | import * as os from 'os' 6 | import * as path from 'path' 7 | 8 | class Input { 9 | constructor( 10 | public key: string, 11 | public restoreKeys: string[], 12 | public derivedDataDirectory: string | null, 13 | public sourcePackagesDirectory: string | null, 14 | public restoreMtimeTargets: string[], 15 | public swiftpmPackageResolvedFile: string[], 16 | public swiftpmCacheKey: string | null, 17 | public swiftpmCacheRestoreKeys: string[], 18 | public useDefaultMtimeTargets: boolean, 19 | public deleteUsedDerivedDataCache: boolean, 20 | public token: string, 21 | public verbose: boolean, 22 | public cacheReadOnly: boolean 23 | ) {} 24 | 25 | getDerivedDataDirectory(): string { 26 | let result = this.derivedDataDirectory 27 | if (result == null) { 28 | result = '~/Library/Developer/Xcode/DerivedData' 29 | } 30 | result = result.replace(/^~\//, `${os.homedir()}/`) 31 | return result 32 | } 33 | 34 | async getSourcePackagesDirectory(): Promise { 35 | let result = this.sourcePackagesDirectory 36 | if (result == null) { 37 | // find DerivedData/{AppName}-{ID}/SourcePackages 38 | const derivedDataDirectory = this.getDerivedDataDirectory() 39 | const globber = await glob.create(path.join(derivedDataDirectory, '*/SourcePackages')) 40 | const files = await globber.glob() 41 | if (0 < files.length) { 42 | result = files[0] 43 | } 44 | } 45 | result = result?.replace(/^~\//, `${os.homedir()}/`) ?? null 46 | return result 47 | } 48 | 49 | async getSwiftpmCacheKey(): Promise { 50 | let result = this.swiftpmCacheKey 51 | if (result == null) { 52 | let resolvedFiles = this.swiftpmPackageResolvedFile 53 | if (resolvedFiles.length <= 0) { 54 | resolvedFiles = [ 55 | '**/*.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved', 56 | '**/*.xcworkspace/xcshareddata/swiftpm/Package.resolved' 57 | ] 58 | } 59 | result = `irgaly/xcode-cache-sourcepackages-${await hashFiles(resolvedFiles.join('\n'))}` 60 | } 61 | return result 62 | } 63 | } 64 | 65 | export async function debugLocalInput(): Promise { 66 | let result = false 67 | const inputFile = process.env['INPUT'] 68 | if (inputFile) { 69 | // setup environment from file for debug 70 | const json = JSON.parse(await fs.readFile(inputFile, 'utf8')) 71 | Object.entries(json).forEach(([key, value]) => { 72 | core.info(`set debug env: ${key} => ${value}`) 73 | process.env[key] = value as string 74 | }) 75 | result = true 76 | } 77 | return result 78 | } 79 | 80 | export function getInput(): Input { 81 | return new Input( 82 | core.getInput('key'), 83 | core.getMultilineInput('restore-keys'), 84 | getInputOrNull('deriveddata-directory'), 85 | getInputOrNull('sourcepackages-directory'), 86 | core.getMultilineInput('restore-mtime-targets'), 87 | core.getMultilineInput('swiftpm-package-resolved-file'), 88 | getInputOrNull('swiftpm-cache-key'), 89 | core.getMultilineInput('swiftpm-cache-restore-keys'), 90 | core.getBooleanInput('use-default-mtime-targets'), 91 | core.getBooleanInput('delete-used-deriveddata-cache'), 92 | core.getInput('token'), 93 | core.getBooleanInput('verbose'), 94 | core.getBooleanInput('cache-read-only') 95 | ) 96 | } 97 | 98 | function getInputOrNull(name: string): string | null { 99 | let value: string | null = core.getInput(name) 100 | if (value.length <= 0) { 101 | value = null 102 | } 103 | return value 104 | } 105 | -------------------------------------------------------------------------------- /src/json.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * ```json 3 | * [ 4 | * {"path": "src/foo.swift", "time": "1609297230.485880489", "sha256": ""}, 5 | * ] 6 | * ``` 7 | */ 8 | export type MtimeJson = { 9 | path: string, 10 | time: string, 11 | sha256: string 12 | } 13 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import * as core from '@actions/core' 2 | import * as cache from '@actions/cache' 3 | import * as exec from '@actions/exec' 4 | import * as fs from 'fs/promises' 5 | import { existsSync, BigIntStats } from 'fs' 6 | import * as os from 'os' 7 | import * as path from 'path' 8 | import { getInput, debugLocalInput } from './input' 9 | import * as util from './util' 10 | import { MtimeJson } from './json' 11 | import { promisify } from 'util' 12 | const nanoutimes = require(`../lib/node-v${process.versions.modules}-darwin-${os.arch()}/nanoutimes.node`) 13 | 14 | main() 15 | 16 | async function main() { 17 | try { 18 | const debugLocal = await debugLocalInput() 19 | if (debugLocal) { 20 | util.fakeCache(cache) 21 | } 22 | const runnerOs = process.env['RUNNER_OS'] 23 | if (runnerOs != 'macOS') { 24 | throw new Error(`xcode-cache supports only macOS, current host is ${runnerOs}`) 25 | } 26 | const input = getInput() 27 | core.info('Input parameters:') 28 | Object.entries(input).forEach(([key, value]) => { 29 | core.info(` ${key} = ${value}`) 30 | }) 31 | core.info('') 32 | const derivedDataDirectory = await input.getDerivedDataDirectory() 33 | const derivedDataRestoredKey = await restoreDerivedData( 34 | derivedDataDirectory, 35 | input.key, 36 | input.restoreKeys 37 | ) 38 | const derivedDataRestored = (derivedDataRestoredKey != undefined) 39 | core.info('') 40 | const sourcePackagesDirectory = await input.getSourcePackagesDirectory() 41 | let sourcePackagesRestoredKey: string | undefined = undefined 42 | let sourcePackagesRestored = false 43 | if (sourcePackagesDirectory == null) { 44 | core.info(`There are no SourcePackages directory in DerivedData, skip restoring SourcePackages`) 45 | } else { 46 | sourcePackagesRestoredKey = await restoreSourcePackages( 47 | sourcePackagesDirectory, 48 | await input.getSwiftpmCacheKey(), 49 | input.swiftpmCacheRestoreKeys 50 | ) 51 | sourcePackagesRestored = (sourcePackagesRestoredKey != undefined) 52 | } 53 | core.info('') 54 | if (!derivedDataRestored) { 55 | core.info(`Skipped restoring mtime because of DerivedData is not restored`) 56 | } else { 57 | await restoreMtime( 58 | derivedDataDirectory, 59 | input.restoreMtimeTargets, 60 | input.verbose 61 | ) 62 | } 63 | core.info('') 64 | core.info(`set-output: restored = ${derivedDataRestored}`) 65 | core.setOutput('restored', derivedDataRestored.toString()); 66 | if (derivedDataRestored) { 67 | core.info(`set-output: restored-key = ${derivedDataRestoredKey}`) 68 | core.setOutput('restored-key', derivedDataRestoredKey); 69 | } else { 70 | core.info(`restored-key will not set`) 71 | } 72 | core.info(`set-output: swiftpm-restored = ${sourcePackagesRestored}`) 73 | core.setOutput('swiftpm-restored', sourcePackagesRestored.toString()); 74 | if (sourcePackagesRestored) { 75 | core.info(`set-output: swiftpm-restored-key = ${sourcePackagesRestoredKey}`) 76 | core.setOutput('swiftpm-restored-key', sourcePackagesRestoredKey); 77 | } else { 78 | core.info(`swiftpm-restored-key will not set`) 79 | } 80 | } catch (error) { 81 | if (error instanceof Error) { 82 | core.setFailed(error.message) 83 | } 84 | } 85 | } 86 | 87 | async function restoreDerivedData( 88 | derivedDataDirectory: string, 89 | key: string, 90 | restoreKeys: string[] 91 | ): Promise { 92 | const begin = new Date() 93 | core.info(`[${util.getHHmmss(begin)}]: Restoring DerivedData...`) 94 | core.info(`cache key:\n ${key}`) 95 | core.info(`restore keys:\n ${restoreKeys.join('\n')}`) 96 | const restoreKey = await cache.restoreCache([derivedDataDirectory], key, restoreKeys) 97 | const restored = (restoreKey != undefined) 98 | if (!restored) { 99 | core.info('DerivedData cache not found') 100 | } else { 101 | core.info(`Restored cache key:\n ${restoreKey}`) 102 | core.saveState('deriveddata-restorekey', restoreKey) 103 | core.info(`Restored to:\n ${derivedDataDirectory}`) 104 | } 105 | const end = new Date() 106 | core.info(`[${util.getHHmmss(end)}]: ${util.elapsed(begin, end)}s`) 107 | return restoreKey 108 | } 109 | 110 | async function restoreSourcePackages( 111 | sourcePackagesDirectory: string, 112 | key: string, 113 | restoreKeys: string[] 114 | ): Promise { 115 | const begin = new Date() 116 | core.info(`[${util.getHHmmss(begin)}]: Restoring SourcePackages...`) 117 | core.info(`cache key:\n ${key}`) 118 | core.info(`restore keys:\n ${restoreKeys.join('\n')}`) 119 | const restoreKey = await cache.restoreCache([sourcePackagesDirectory], key, restoreKeys) 120 | const restored = (restoreKey != undefined) 121 | if (!restored) { 122 | core.info('SourcePackages cache not found') 123 | } else { 124 | core.info(`Restored cache key:\n ${restoreKey}`) 125 | core.saveState('sourcepackages-restorekey', restoreKey) 126 | core.info(`Restored to:\n ${sourcePackagesDirectory}`) 127 | } 128 | const end = new Date() 129 | core.info(`[${util.getHHmmss(end)}]: ${util.elapsed(begin, end)}s`) 130 | return restoreKey 131 | } 132 | 133 | async function restoreMtime( 134 | derivedDataDirectory: string, 135 | restoreMtimeTargets: string[], 136 | verbose: boolean 137 | ) { 138 | const begin = new Date() 139 | core.info(`[${util.getHHmmss(begin)}]: Restoring mtime...`) 140 | let changed = 0 141 | let skipped: string[] = [] 142 | const jsonFile = path.join(derivedDataDirectory, 'xcode-cache-mtime.json') 143 | let json = null 144 | try { 145 | json = await fs.readFile(jsonFile, 'utf8') 146 | } catch (error) { 147 | core.warning(`xcode-cache-mtime.json not found: ${jsonFile}`) 148 | } 149 | if (json != null) { 150 | const files = JSON.parse(json) as MtimeJson[] 151 | core.info(`Restoring from:\n ${jsonFile}`) 152 | if (verbose) { 153 | core.startGroup('Restoring mtime') 154 | } 155 | for (const item of files) { 156 | let stat: BigIntStats | null = null 157 | try { 158 | stat = await fs.stat(item.path, {bigint: true}) 159 | } catch (error) { 160 | // file not exist 161 | // do nothing 162 | } 163 | if (stat != null) { 164 | const fileMtime = stat.mtimeNs.toString() 165 | const cacheMtime = item.time.replace('.', '') 166 | if (fileMtime == cacheMtime) { 167 | if (verbose) { 168 | skipped.push(`same mtime : ${item.path}`) 169 | } 170 | } else { 171 | let sha256 = '' 172 | if (stat.isDirectory()) { 173 | sha256 = await util.calculateDirectoryHash(item.path) 174 | } else { 175 | sha256 = await util.calculateHash(item.path) 176 | } 177 | if (sha256 != item.sha256) { 178 | if (verbose) { 179 | skipped.push(`contents changed : ${item.path}`) 180 | } 181 | } else { 182 | if (verbose) { 183 | core.info(`${util.getTimeString(stat.mtimeNs)} => ${item.time} : ${item.path}`) 184 | } 185 | const [second, nano] = item.time.split('.').map(v => Number(v)) 186 | nanoutimes.utimesSync(item.path, second, nano, second, nano) 187 | changed++ 188 | } 189 | } 190 | } 191 | } 192 | if (verbose) { 193 | core.endGroup() 194 | if (0 < skipped.length) { 195 | core.startGroup('Skipped files') 196 | skipped.forEach (v => { 197 | core.info(v) 198 | }) 199 | core.endGroup() 200 | } 201 | } 202 | core.info(`Restored ${changed} file's mtimes.`) 203 | const end = new Date() 204 | core.info(`[${util.getHHmmss(end)}]: ${util.elapsed(begin, end)}s`) 205 | } 206 | } 207 | -------------------------------------------------------------------------------- /src/post.ts: -------------------------------------------------------------------------------- 1 | import * as core from '@actions/core' 2 | import * as cache from '@actions/cache' 3 | import * as glob from '@actions/glob' 4 | import * as exec from '@actions/exec' 5 | import * as github from '@actions/github' 6 | import * as fs from 'fs/promises' 7 | import { existsSync } from 'fs' 8 | import * as os from 'os' 9 | import * as path from 'path' 10 | import { getInput, debugLocalInput } from './input' 11 | import * as util from './util' 12 | import { MtimeJson } from './json' 13 | 14 | // Prevent upload chunk error, handle it as warning 15 | // > Error: Cache upload failed because file read failed with EBADF: bad file descriptor 16 | process.on('uncaughtException', e => { 17 | core.info(`[warning] ${e.message}`); 18 | }); 19 | 20 | post() 21 | 22 | async function post() { 23 | try { 24 | const debugLocal = await debugLocalInput() 25 | if (debugLocal) { 26 | util.fakeCache(cache) 27 | util.fakeOctokit(github) 28 | } 29 | const runnerOs = process.env['RUNNER_OS'] 30 | if (runnerOs != 'macOS') { 31 | throw new Error(`xcode-cache supports only macOS, current host is ${runnerOs}`) 32 | } 33 | const input = getInput() 34 | core.info('Input parameters:') 35 | Object.entries(input).forEach(([key, value]) => { 36 | core.info(` ${key} = ${value}`) 37 | }) 38 | core.info('') 39 | if (input.cacheReadOnly) { 40 | core.info('Cache is read-only: will not save state for use in subsequent builds.') 41 | } else { 42 | const tempDirectory = path.join(process.env['RUNNER_TEMP']!, 'irgaly-xcode-cache') 43 | const derivedDataDirectory = await input.getDerivedDataDirectory() 44 | const sourcePackagesDirectory = await input.getSourcePackagesDirectory() 45 | if (!existsSync(derivedDataDirectory)) { 46 | core.warning(`DerivedData directory not found:\n ${derivedDataDirectory}`) 47 | core.warning('Skipped storing mtime') 48 | } else { 49 | const derivedDataRestoreKey = core.getState('deriveddata-restorekey') 50 | if (derivedDataRestoreKey == input.key) { 51 | core.warning(`DerivedData cache has been restored with same key: ${input.key}`) 52 | core.warning('Skipped storing mtime') 53 | } else { 54 | await storeMtime( 55 | derivedDataDirectory, 56 | sourcePackagesDirectory, 57 | input.restoreMtimeTargets, 58 | input.useDefaultMtimeTargets, 59 | input.verbose 60 | ) 61 | } 62 | } 63 | core.info('') 64 | if (sourcePackagesDirectory == null) { 65 | core.info(`There are no SourcePackages directory in DerivedData, skip restoring SourcePackages`) 66 | } else { 67 | if (!existsSync(sourcePackagesDirectory)) { 68 | core.warning(`SourcePackages directory not exists:\n ${sourcePackagesDirectory}`) 69 | core.warning('Skipped storing SourcePackages') 70 | } else { 71 | await storeSourcePackages( 72 | sourcePackagesDirectory, 73 | await input.getSwiftpmCacheKey() 74 | ) 75 | } 76 | } 77 | core.info('') 78 | if (input.deleteUsedDerivedDataCache) { 79 | await deleteUsedDerivedDataCache( 80 | input.key, 81 | input.token 82 | ) 83 | } else { 84 | core.info('Skipped deleting old DerivedData cache') 85 | } 86 | core.info('') 87 | await storeDerivedData( 88 | await input.getDerivedDataDirectory(), 89 | sourcePackagesDirectory, 90 | tempDirectory, 91 | input.key 92 | ) 93 | if (!debugLocal && existsSync(tempDirectory)) { 94 | core.info(`Clean up: removing temporary directory: ${tempDirectory}`) 95 | await fs.rm(tempDirectory, { recursive: true, force: true }) 96 | } 97 | } 98 | } catch (error) { 99 | if (error instanceof Error) { 100 | core.setFailed(error.message) 101 | } 102 | } 103 | // Workaround for node20 HTTPS + keepAlive + cache.saveCache() takes 2 mins bug 104 | // https://github.com/actions/toolkit/issues/1643 105 | // https://github.com/nodejs/node/issues/47228 106 | process.exit(0) 107 | } 108 | 109 | async function deleteUsedDerivedDataCache( 110 | key: string, 111 | token: string 112 | ) { 113 | const restoreKey = core.getState('deriveddata-restorekey') 114 | if (restoreKey == '') { 115 | core.info(`DerivedData cache has not been restored.`) 116 | core.info('Skipped deleting old DerivedData cache') 117 | } else if (restoreKey == key) { 118 | core.info(`DerivedData cache has been restored with same key:\n ${key}`) 119 | core.info('Skipped deleting old DerivedData cache') 120 | } else { 121 | const begin = new Date() 122 | core.info(`[${util.getHHmmss(begin)}]: Deleting old DerivedData cache...`) 123 | core.info(`Cache key:\n ${restoreKey}`) 124 | const octokit = github.getOctokit(token) 125 | try { 126 | const result = await octokit.request('DELETE /repos/{owner}/{repo}/actions/caches{?key,ref}', { 127 | owner: github.context.repo.owner, 128 | repo: github.context.repo.repo, 129 | key: restoreKey, 130 | ref: github.context.ref 131 | }) 132 | core.info(`DELETE cache API Result:\n${JSON.stringify(result, null, ' ')}`) 133 | } catch (error: any) { 134 | if (error.status == 404) { 135 | core.info('API returns "Cache is Not Found" response.') 136 | core.info('This occurs when Cache belongs to other branch.') 137 | core.info(`This is expected behavior and treat it as success, if this job is the first build of "${github.context.ref}" branch.`) 138 | core.info(`DELETE cache API Result:\n${JSON.stringify(error, null, ' ')}`) 139 | } else { 140 | core.error('Error when deleting old DerivedData cache:') 141 | core.error('Please be sure actions:write permission is granted for your token.') 142 | core.error('See API Docs: https://docs.github.com/en/rest/actions/cache?apiVersion=2022-11-28#delete-github-actions-caches-for-a-repository-using-a-cache-key') 143 | core.error('See GitHub Actions Permissions: https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs') 144 | core.error(`${JSON.stringify(error, null, ' ')}`) 145 | throw error 146 | } 147 | } 148 | const end = new Date() 149 | core.info(`[${util.getHHmmss(end)}]: ${util.elapsed(begin, end)}s`) 150 | } 151 | } 152 | 153 | async function storeDerivedData( 154 | derivedDataDirectory: string, 155 | sourcePackagesDirectory: string | null, 156 | tempDirectory: string, 157 | key: string 158 | ) { 159 | const restoreKey = core.getState('deriveddata-restorekey') 160 | if (restoreKey == key) { 161 | core.info(`DerivedData cache has been restored with same key:\n ${key}`) 162 | core.info('Skipped storing DerivedData') 163 | } else { 164 | const begin = new Date() 165 | core.info(`[${util.getHHmmss(begin)}]: Storing DerivedData...`) 166 | core.info(`Cache path:\n ${derivedDataDirectory}`) 167 | if (sourcePackagesDirectory != null) { 168 | if ( 169 | util.pathContains(derivedDataDirectory, sourcePackagesDirectory) && 170 | existsSync(sourcePackagesDirectory) 171 | ) { 172 | // replace SourcePackages directory by empty directory 173 | await fs.mkdir(tempDirectory, { recursive: true }) 174 | await fs.rename(sourcePackagesDirectory, path.join(tempDirectory, path.basename(sourcePackagesDirectory))) 175 | await fs.mkdir(sourcePackagesDirectory) 176 | } 177 | } 178 | await cache.saveCache([derivedDataDirectory], key) 179 | core.info(`Cached with key:\n ${key}`) 180 | if (sourcePackagesDirectory != null) { 181 | const backup = path.join(tempDirectory, path.basename(sourcePackagesDirectory)) 182 | if (existsSync(backup)) { 183 | await fs.rm(sourcePackagesDirectory, { recursive: true, force: true }) 184 | await fs.rename(backup, sourcePackagesDirectory) 185 | } 186 | } 187 | const end = new Date() 188 | core.info(`[${util.getHHmmss(end)}]: ${util.elapsed(begin, end)}s`) 189 | } 190 | } 191 | 192 | async function storeSourcePackages( 193 | sourcePackagesDirectory: string, 194 | key: string 195 | ) { 196 | const restoreKey = core.getState('sourcepackages-restorekey') 197 | if (restoreKey == key) { 198 | core.info(`SourcePackages cache has been restored with same key:\n ${key}`) 199 | core.info('Skipped storing SourcePackages') 200 | } else { 201 | const begin = new Date() 202 | core.info(`[${util.getHHmmss(begin)}]: Storing SourcePackages...`) 203 | core.info(`Cache path:\n ${sourcePackagesDirectory}`) 204 | try { 205 | await cache.saveCache([sourcePackagesDirectory], key) 206 | core.info(`Cached with key:\n ${key}`) 207 | } catch (error) { 208 | // in case cache key conflict, 209 | // this occurs when SourcePackages directory is under DerivedData and 210 | // DerivedData cache missed. 211 | // then logging warning and treat as success. 212 | core.warning(`SourcePackages cache key exists, not saved: ${error}`) 213 | } 214 | const end = new Date() 215 | core.info(`[${util.getHHmmss(end)}]: ${util.elapsed(begin, end)}s`) 216 | } 217 | } 218 | 219 | async function storeMtime( 220 | derivedDataDirectory: string, 221 | sourcePackagesDirectory: string | null, 222 | restoreMtimeTargets: string[], 223 | useDefaultMtimeTarget: boolean, 224 | verbose: boolean 225 | ) { 226 | const begin = new Date() 227 | core.info(`[${util.getHHmmss(begin)}]: Storing mtime...`) 228 | let stored = 0 229 | const jsonFile = path.join(derivedDataDirectory, 'xcode-cache-mtime.json') 230 | const json: MtimeJson[] = [] 231 | const defaultMtimeTargets = [ 232 | "**/*.swift", 233 | "**/*.xib", 234 | "**/*.storyboard", 235 | "**/*.strings", 236 | "**/*.xcstrings", 237 | "**/*.plist", 238 | "**/*.intentdefinition", 239 | "**/*.json", 240 | "**/*.xcassets", 241 | "**/*.xcassets/**/*", 242 | "**/*.bundle", 243 | "**/*.bundle/**/*", 244 | "**/*.xcdatamodel", 245 | "**/*.xcdatamodel/**/*", 246 | "**/*.framework", 247 | "**/*.framework/**/*", 248 | "**/*.xcframework", 249 | "**/*.xcframework/**/*", 250 | "**/*.m", 251 | "**/*.mm", 252 | "**/*.h", 253 | "**/*.c", 254 | "**/*.cc", 255 | "**/*.cpp", 256 | "**/*.hpp", 257 | "**/*.hxx" 258 | ] 259 | let patterns: string[] = [] 260 | if (useDefaultMtimeTarget) { 261 | patterns = [...patterns, ...defaultMtimeTargets] 262 | } 263 | const targets = restoreMtimeTargets.sort((l, r) => { 264 | let order = 0 265 | const excludeL = l.startsWith('!') 266 | const excludeR = r.startsWith('!') 267 | if (excludeL != excludeR) { 268 | if (excludeL) { 269 | order = 1 270 | } else { 271 | order = -1 272 | } 273 | } 274 | return order 275 | }) 276 | patterns = [...patterns, ...targets] 277 | patterns = [...patterns, `!${derivedDataDirectory}/**/*`] 278 | if (sourcePackagesDirectory != null) { 279 | patterns = [...patterns, `!${sourcePackagesDirectory}/**/*`] 280 | } 281 | core.info(`Storing to:\n ${jsonFile}`) 282 | if (verbose) { 283 | core.info(`Target glob patterns:`) 284 | patterns.forEach(pattern => { 285 | core.info(` ${pattern}`) 286 | }) 287 | } 288 | const cwd = process.cwd() 289 | const globber = await glob.create(patterns.join('\n'), { implicitDescendants: false }) 290 | const files = (await globber.glob()).map(filePath => { 291 | return path.relative(cwd, filePath) 292 | }) 293 | if (verbose) { 294 | core.startGroup('Storing mtime') 295 | } 296 | for(const path of files) { 297 | try { 298 | const stat = await fs.stat(path, {bigint: true}) 299 | const mtime = util.getTimeString(stat.mtimeNs) 300 | let sha256 = '' 301 | if (stat.isDirectory()) { 302 | sha256 = await util.calculateDirectoryHash(path) 303 | } else { 304 | sha256 = await util.calculateHash(path) 305 | } 306 | if (verbose) { 307 | core.info(`${mtime} : ${path}`) 308 | } 309 | json.push({ path: path, time: mtime, sha256: sha256 }) 310 | stored++ 311 | } catch (error) { 312 | core.warning(`Cannot read file stat: ${path}`) 313 | } 314 | } 315 | if (verbose) { 316 | core.endGroup() 317 | } 318 | await fs.writeFile(jsonFile, JSON.stringify(json)) 319 | core.info(`Stored ${stored} file's mtimes`) 320 | const end = new Date() 321 | core.info(`[${util.getHHmmss(end)}]: ${util.elapsed(begin, end)}s`) 322 | } 323 | -------------------------------------------------------------------------------- /src/util.ts: -------------------------------------------------------------------------------- 1 | import * as core from '@actions/core' 2 | import * as fs from 'fs/promises' 3 | import { existsSync } from 'fs' 4 | import * as path from 'path' 5 | import { createReadStream } from 'fs' 6 | import * as exec from '@actions/exec' 7 | import { ExecOptions } from '@actions/exec' 8 | import * as crypto from 'crypto' 9 | import { pipeline } from 'stream/promises' 10 | 11 | /** 12 | * Get 'HH:mm:ss' formatted string 13 | */ 14 | export function getHHmmss( 15 | date: Date 16 | ): string { 17 | const hours = ('0' + date.getHours()).slice(-2) 18 | const minutes = ('0' + date.getMinutes()).slice(-2) 19 | const seconds = ('0' + date.getSeconds()).slice(-2) 20 | return `${hours}:${minutes}:${seconds}` 21 | } 22 | 23 | /** 24 | * Get elapsed seconds as string: "0.00" 25 | */ 26 | export function elapsed( 27 | begin: Date, 28 | end: Date 29 | ): string { 30 | return ((end.getTime() - begin.getTime()) / 1000).toFixed(3) 31 | } 32 | 33 | /** 34 | * BigInt to time string "1694535491.104939637" 35 | */ 36 | export function getTimeString( 37 | value: BigInt 38 | ): string { 39 | const str = value.toString() 40 | return `${str.slice(0, str.length - 9)}.${str.slice(str.length - 9)}` 41 | } 42 | 43 | /** 44 | * Get SHA256 hash from file content 45 | */ 46 | export async function calculateHash( 47 | targetPath: string 48 | ): Promise { 49 | const hash = crypto.createHash('sha256') 50 | await pipeline(createReadStream(targetPath), hash) 51 | return hash.digest('hex') 52 | } 53 | 54 | /** 55 | * Get SHA256 hash from directory entities 56 | * 57 | * directory hash: 58 | * * children's fileName 59 | */ 60 | export async function calculateDirectoryHash( 61 | targetPath: string 62 | ): Promise { 63 | const hash = crypto.createHash('sha256') 64 | const fileNames = (await fs.readdir(targetPath)).sort() 65 | for(const fileName of fileNames) { 66 | hash.update(fileName) 67 | } 68 | return hash.digest('hex') 69 | } 70 | 71 | /** 72 | * return true if the child path is under the parent path in UNIX file system. 73 | */ 74 | export function pathContains(parent: string, child: string): boolean { 75 | return !path.relative(parent, child).startsWith("../") 76 | } 77 | 78 | export async function execute( 79 | command: string, args: string[] = [], cwd?: string 80 | ): Promise { 81 | let output = '' 82 | const options: ExecOptions = {} 83 | options.listeners = { 84 | stdout: (data: Buffer) => { 85 | output += data.toString() 86 | }, 87 | stderr: (data: Buffer) => { 88 | console.error(data) 89 | } 90 | } 91 | if (cwd) { 92 | options.cwd = cwd 93 | } 94 | await exec.exec(command, args, options) 95 | return output 96 | } 97 | 98 | export async function fakeCache( 99 | cache: any 100 | ) { 101 | Object.assign(cache, { 102 | restoreCache: async (paths: string[], primaryKey: string, restoreKeys?: string[]): Promise => { 103 | if (existsSync(paths[0])) { 104 | core.info(`Debug: restoreCache success: ${paths[0]}`) 105 | return "restore-key" 106 | } else { 107 | core.error(`Debug: restoreCache failure: ${paths[0]}`) 108 | return undefined 109 | } 110 | }, 111 | saveCache: async (paths: string[], key: string): Promise => { 112 | if (existsSync(paths[0])) { 113 | core.info(`Debug: saveCache success: ${paths[0]}`) 114 | return 0 115 | } else { 116 | core.error(`Debug: saveCache failure: ${paths[0]}`) 117 | throw new Error(`file not exist: ${paths[0]}`) 118 | } 119 | } 120 | }) 121 | } 122 | 123 | export async function fakeOctokit( 124 | github: any 125 | ) { 126 | Object.assign(github, { 127 | getOctokit: (token: string): any => { 128 | return { 129 | request: (route: string, options: any) => { 130 | core.info(`Debug: octokit.request:`) 131 | core.info(`Debug: route: ${route}`) 132 | core.info(`Debug: options: ${JSON.stringify(options)}`) 133 | } 134 | } 135 | } 136 | }) 137 | } 138 | -------------------------------------------------------------------------------- /test/input.json: -------------------------------------------------------------------------------- 1 | { 2 | "RUNNER_OS": "macOS", 3 | "RUNNER_TEMP": "./tmp", 4 | "GITHUB_REPOSITORY": "dummy_owner/dummy_repository", 5 | "STATE_deriveddata-restorekey": "dummy_restore_key", 6 | "INPUT_KEY": "xcode-deriveddata-{workflow}-{sha}", 7 | "INPUT_DERIVEDDATA-DIRECTORY": "./sample/MyApp/DerivedData", 8 | "INPUT_SOURCEPACKAGES-DIRECTORY": "./sample/MyApp/SourcePackages", 9 | "INPUT_USE-DEFAULT-MTIME-TARGETS": "true", 10 | "INPUT_DELETE-USED-DERIVEDDATA-CACHE": "false", 11 | "INPUT_TOKEN": "dummy_github_token", 12 | "INPUT_VERBOSE": "true", 13 | "INPUT_CACHE-READ-ONLY": "false" 14 | } 15 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2022", 4 | "module": "commonjs", 5 | "strict": true, 6 | "noImplicitAny": true, 7 | "esModuleInterop": true 8 | } 9 | } 10 | --------------------------------------------------------------------------------