mirror of
https://github.com/reactivecircus/android-emulator-runner.git
synced 2026-09-03 10:59:32 +00:00
Compare commits
40 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1dcd009011 | |||
| 2548f9f3fc | |||
| 595a4563df | |||
| a173d65200 | |||
| 50d5b10c01 | |||
| 62dbb605bb | |||
| c77bfe7c0b | |||
| ead704cc5a | |||
| e800ffffe6 | |||
| 8c07710601 | |||
| 3a18f50216 | |||
| 1b985f4c7a | |||
| a3dcdb348b | |||
| f0d1ed2dca | |||
| 81f860b51a | |||
| e93b947104 | |||
| 4b0628e9f8 | |||
| 77986be265 | |||
| ca77a1081f | |||
| 1fef06a960 | |||
| d8da5b6410 | |||
| a0c0e7216b | |||
| 9d5d6236f4 | |||
| 6b0df4b0ef | |||
| bc2cd2aaea | |||
| 61a61f94a9 | |||
| eaf4c246b5 | |||
| 426fbd2820 | |||
| e1bd48ca1d | |||
| 1e33853aad | |||
| c479bb6c0f | |||
| 99a4aac18b | |||
| 677db68893 | |||
| f9c2835191 | |||
| 1036f55734 | |||
| 5a481d20f1 | |||
| f72f505164 | |||
| fabc29122a | |||
| 2cfd145246 | |||
| e1bdfefaa7 |
@@ -9,5 +9,5 @@ jobs:
|
|||||||
validate-typings:
|
validate-typings:
|
||||||
runs-on: "ubuntu-latest"
|
runs-on: "ubuntu-latest"
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: krzema12/github-actions-typing@v0
|
- uses: krzema12/github-actions-typing@v0
|
||||||
|
|||||||
+37
-33
@@ -18,41 +18,36 @@ jobs:
|
|||||||
timeout-minutes: 15
|
timeout-minutes: 15
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [macos-latest, ubuntu-latest]
|
|
||||||
api-level: [16, 23, 29]
|
|
||||||
target: [default, google_apis]
|
|
||||||
arch: [x86]
|
|
||||||
exclude:
|
|
||||||
- os: ubuntu-latest
|
|
||||||
api-level: 23
|
|
||||||
- os: ubuntu-latest
|
|
||||||
api-level: 29
|
|
||||||
- target: google_apis
|
|
||||||
api-level: 16
|
|
||||||
- target: google_apis
|
|
||||||
api-level: 23
|
|
||||||
- target: google_apis
|
|
||||||
api-level: 29
|
|
||||||
include:
|
include:
|
||||||
- os: macos-latest
|
- os: ubuntu-22.04
|
||||||
|
api-level: 23
|
||||||
|
target: default
|
||||||
|
arch: x86
|
||||||
|
- os: ubuntu-24.04
|
||||||
api-level: 24
|
api-level: 24
|
||||||
target: playstore
|
target: playstore
|
||||||
arch: x86
|
arch: x86
|
||||||
- os: macos-latest
|
- os: macos-13
|
||||||
api-level: 30
|
|
||||||
target: aosp_atd
|
|
||||||
arch: x86
|
|
||||||
- os: macos-11
|
|
||||||
api-level: 31
|
api-level: 31
|
||||||
|
target: default
|
||||||
|
arch: x86_64
|
||||||
|
- os: ubuntu-24.04
|
||||||
|
api-level: 34
|
||||||
|
target: aosp_atd
|
||||||
|
arch: x86_64
|
||||||
|
- os: ubuntu-latest
|
||||||
|
api-level: 35
|
||||||
target: google_apis
|
target: google_apis
|
||||||
arch: x86_64
|
arch: x86_64
|
||||||
|
- os: ubuntu-latest
|
||||||
|
api-level: 34-ext10
|
||||||
|
target: android-automotive
|
||||||
|
arch: x86_64
|
||||||
|
system-image-api-level: 34-ext9
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: checkout
|
- name: checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: validate gradle wrapper
|
|
||||||
uses: gradle/wrapper-validation-action@v1
|
|
||||||
|
|
||||||
- name: build, test and lint
|
- name: build, test and lint
|
||||||
run: |
|
run: |
|
||||||
@@ -61,25 +56,32 @@ jobs:
|
|||||||
npm run lint
|
npm run lint
|
||||||
npm test
|
npm test
|
||||||
|
|
||||||
- uses: actions/setup-java@v3
|
- uses: actions/setup-java@v4
|
||||||
with:
|
with:
|
||||||
distribution: 'zulu'
|
distribution: 'zulu'
|
||||||
java-version: 19
|
java-version: 23
|
||||||
|
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v4
|
||||||
id: avd-cache
|
id: avd-cache
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
~/.android/avd/*
|
~/.android/avd/*
|
||||||
~/.android/adb*
|
~/.android/adb*
|
||||||
~/.android/debug.keystore
|
~/.android/debug.keystore
|
||||||
key: avd-${{ matrix.api-level }}-${{ matrix.os }}-${{ matrix.target }}
|
key: avd-${{ matrix.api-level }}-${{ matrix.os }}-${{ matrix.target }}-${{ matrix.arch }}
|
||||||
|
|
||||||
|
- uses: gradle/actions/setup-gradle@v4
|
||||||
|
|
||||||
- name: assemble tests
|
- name: assemble tests
|
||||||
uses: gradle/gradle-build-action@v2
|
working-directory: test-fixture
|
||||||
with:
|
run: ./gradlew assembleAndroidTest
|
||||||
build-root-directory: test-fixture
|
|
||||||
arguments: assembleAndroidTest
|
- name: enable KVM for linux runners
|
||||||
|
if: runner.os == 'Linux'
|
||||||
|
run: |
|
||||||
|
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
|
||||||
|
sudo udevadm control --reload-rules
|
||||||
|
sudo udevadm trigger --name-match=kvm
|
||||||
|
|
||||||
- name: run emulator to generate snapshot for caching
|
- name: run emulator to generate snapshot for caching
|
||||||
if: steps.avd-cache.outputs.cache-hit != 'true'
|
if: steps.avd-cache.outputs.cache-hit != 'true'
|
||||||
@@ -88,6 +90,7 @@ jobs:
|
|||||||
api-level: ${{ matrix.api-level }}
|
api-level: ${{ matrix.api-level }}
|
||||||
target: ${{ matrix.target }}
|
target: ${{ matrix.target }}
|
||||||
arch: ${{ matrix.arch }}
|
arch: ${{ matrix.arch }}
|
||||||
|
system-image-api-level: ${{ matrix.system-image-api-level }}
|
||||||
profile: Galaxy Nexus
|
profile: Galaxy Nexus
|
||||||
cores: 2
|
cores: 2
|
||||||
sdcard-path-or-size: 100M
|
sdcard-path-or-size: 100M
|
||||||
@@ -105,6 +108,7 @@ jobs:
|
|||||||
api-level: ${{ matrix.api-level }}
|
api-level: ${{ matrix.api-level }}
|
||||||
target: ${{ matrix.target }}
|
target: ${{ matrix.target }}
|
||||||
arch: ${{ matrix.arch }}
|
arch: ${{ matrix.arch }}
|
||||||
|
system-image-api-level: ${{ matrix.system-image-api-level }}
|
||||||
profile: Galaxy Nexus
|
profile: Galaxy Nexus
|
||||||
cores: 2
|
cores: 2
|
||||||
ram-size: 2048M
|
ram-size: 2048M
|
||||||
|
|||||||
@@ -5,18 +5,20 @@ on:
|
|||||||
os:
|
os:
|
||||||
description: 'OS'
|
description: 'OS'
|
||||||
required: true
|
required: true
|
||||||
default: 'macos-latest'
|
default: 'ubuntu-latest'
|
||||||
api-level:
|
api-level:
|
||||||
description: 'API level of the platform and system image'
|
description: 'API level of the platform and system image (if not overridden with system-image-api-level input) - e.g. 33, 35-ext15, Baklava'
|
||||||
required: true
|
required: true
|
||||||
default: '30'
|
default: '34'
|
||||||
|
system-image-api-level:
|
||||||
|
description: 'API level of the system image - e.g. 34-ext10, 35-ext15'
|
||||||
target:
|
target:
|
||||||
description: 'target of the system image - default, google_apis, google_apis_playstore, aosp_atd, google_atd, android-wear, android-wear-cn, android-tv or google-tv'
|
description: 'target of the system image - default, google_apis, google_apis_playstore, aosp_atd, google_atd, android-wear, android-wear-cn, android-tv, google-tv, android-automotive, android-automotive-playstore or android-desktop'
|
||||||
required: true
|
required: true
|
||||||
default: 'default'
|
default: 'default'
|
||||||
arch:
|
arch:
|
||||||
description: 'CPU architecture of the system image - x86, x86_64 or arm64-v8a'
|
description: 'CPU architecture of the system image - x86, x86_64 or arm64-v8a'
|
||||||
default: 'x86'
|
default: 'x86_64'
|
||||||
emulator-options:
|
emulator-options:
|
||||||
description: 'command-line options used when launching the emulator'
|
description: 'command-line options used when launching the emulator'
|
||||||
default: '-no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim'
|
default: '-no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim'
|
||||||
@@ -39,10 +41,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: checkout
|
- name: checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: validate gradle wrapper
|
|
||||||
uses: gradle/wrapper-validation-action@v1
|
|
||||||
|
|
||||||
- name: build, test and lint
|
- name: build, test and lint
|
||||||
run: |
|
run: |
|
||||||
@@ -51,14 +50,19 @@ jobs:
|
|||||||
npm run lint
|
npm run lint
|
||||||
npm test
|
npm test
|
||||||
|
|
||||||
- uses: actions/setup-java@v3
|
- uses: actions/setup-java@v4
|
||||||
with:
|
with:
|
||||||
distribution: 'zulu'
|
distribution: 'zulu'
|
||||||
java-version: 19
|
java-version: 23
|
||||||
|
|
||||||
- uses: gradle/gradle-build-action@v2
|
- uses: gradle/actions/setup-gradle@v4
|
||||||
with:
|
|
||||||
gradle-home-cache-cleanup: true
|
- name: enable KVM for linux runners
|
||||||
|
if: runner.os == 'Linux'
|
||||||
|
run: |
|
||||||
|
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
|
||||||
|
sudo udevadm control --reload-rules
|
||||||
|
sudo udevadm trigger --name-match=kvm
|
||||||
|
|
||||||
- name: run action
|
- name: run action
|
||||||
uses: ./
|
uses: ./
|
||||||
@@ -66,6 +70,7 @@ jobs:
|
|||||||
api-level: ${{ github.event.inputs.api-level }}
|
api-level: ${{ github.event.inputs.api-level }}
|
||||||
target: ${{ github.event.inputs.target }}
|
target: ${{ github.event.inputs.target }}
|
||||||
arch: ${{ github.event.inputs.arch }}
|
arch: ${{ github.event.inputs.arch }}
|
||||||
|
system-image-api-level: ${{ github.event.inputs.system-image-api-level }}
|
||||||
profile: Galaxy Nexus
|
profile: Galaxy Nexus
|
||||||
emulator-options: ${{ github.event.inputs.emulator-options }}
|
emulator-options: ${{ github.event.inputs.emulator-options }}
|
||||||
emulator-build: ${{ github.event.inputs.emulator-build }}
|
emulator-build: ${{ github.event.inputs.emulator-build }}
|
||||||
|
|||||||
@@ -1,5 +1,47 @@
|
|||||||
# Change Log
|
# Change Log
|
||||||
|
|
||||||
|
## Unreleased
|
||||||
|
|
||||||
|
No changes yet.
|
||||||
|
|
||||||
|
## v2.34.0
|
||||||
|
|
||||||
|
* Allow arbitrary value for `api-level` such as `Baklava` and `35-ext15`. - [428](https://github.com/ReactiveCircus/android-emulator-runner/pull/428)
|
||||||
|
* Add option to specify `system-image-api-level` to use a system image with a different API level than the platform. - [428](https://github.com/ReactiveCircus/android-emulator-runner/pull/428)
|
||||||
|
* Support automotive and desktop targets: `android-automotive`, `android-automotive-playstore`, `android-desktop`. - [428](https://github.com/ReactiveCircus/android-emulator-runner/pull/428)
|
||||||
|
|
||||||
|
## v2.33.0
|
||||||
|
|
||||||
|
* Fix missing AVD directory in `ubuntu-24.04` runner. - [415](https://github.com/ReactiveCircus/android-emulator-runner/pull/415)
|
||||||
|
* Update SDK build tools to `35.0.0`, update SDK command-line tools to `16.0`. - [#356](https://github.com/ReactiveCircus/android-emulator-runner/pull/356)
|
||||||
|
* Stop changing owner of the SDK directory. - [406](https://github.com/ReactiveCircus/android-emulator-runner/pull/406) [#409](https://github.com/ReactiveCircus/android-emulator-runner/pull/409)
|
||||||
|
* Upgrade to latest npm dependencies. - [#401](https://github.com/ReactiveCircus/android-emulator-runner/pull/401)
|
||||||
|
|
||||||
|
## v2.32.0
|
||||||
|
|
||||||
|
* Add `port` parameter for customizing the emulator port to use. - [#383](https://github.com/ReactiveCircus/android-emulator-runner/pull/383)
|
||||||
|
|
||||||
|
|
||||||
|
## v2.31.0
|
||||||
|
|
||||||
|
* Support setting `VanillaIceCream` as `api-level`. - [#378](https://github.com/ReactiveCircus/android-emulator-runner/pull/378)
|
||||||
|
* Install `platforms` for the specified `api-level`. - [#384](https://github.com/ReactiveCircus/android-emulator-runner/pull/384)
|
||||||
|
|
||||||
|
## v2.30.1
|
||||||
|
|
||||||
|
* Run action on Node 20. - [#371](https://github.com/ReactiveCircus/android-emulator-runner/pull/371)
|
||||||
|
|
||||||
|
## v2.30.0
|
||||||
|
|
||||||
|
* Update to Node 20. - [#369](https://github.com/ReactiveCircus/android-emulator-runner/pull/369)
|
||||||
|
|
||||||
|
## v2.29.0
|
||||||
|
|
||||||
|
* Fixed emulator download URL. - [#343](https://github.com/ReactiveCircus/android-emulator-runner/pull/343)
|
||||||
|
* Upgrade to latest npm dependencies. - [#347](https://github.com/ReactiveCircus/android-emulator-runner/pull/347) [#355](https://github.com/ReactiveCircus/android-emulator-runner/pull/355)
|
||||||
|
* Update SDK command-line tools to `11.0`. - [#356](https://github.com/ReactiveCircus/android-emulator-runner/pull/356)
|
||||||
|
* Update SDK build tools to `34.0.0`. - [#356](https://github.com/ReactiveCircus/android-emulator-runner/pull/356)
|
||||||
|
|
||||||
## v2.28.0
|
## v2.28.0
|
||||||
|
|
||||||
* Add `emulator-boot-timeout` to support configuring maximum time waiting for emulator boot. - [#326](https://github.com/ReactiveCircus/android-emulator-runner/pull/326)
|
* Add `emulator-boot-timeout` to support configuring maximum time waiting for emulator boot. - [#326](https://github.com/ReactiveCircus/android-emulator-runner/pull/326)
|
||||||
|
|||||||
@@ -4,12 +4,24 @@
|
|||||||
<a href="https://github.com/ReactiveCircus/android-emulator-runner"><img alt="GitHub Actions status" src="https://github.com/ReactiveCircus/android-emulator-runner/workflows/Main%20workflow/badge.svg"></a>
|
<a href="https://github.com/ReactiveCircus/android-emulator-runner"><img alt="GitHub Actions status" src="https://github.com/ReactiveCircus/android-emulator-runner/workflows/Main%20workflow/badge.svg"></a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
A GitHub Action for installing, configuring and running hardware-accelerated Android Emulators on macOS virtual machines.
|
A GitHub Action for installing, configuring and running hardware-accelerated Android Emulators on Linux and macOS virtual machines.
|
||||||
|
|
||||||
The old ARM-based emulators were slow and are no longer supported by Google. The modern Intel Atom (x86 and x86_64) emulators can be fast, but rely on two forms of hardware acceleration to reach their peak potential: [Graphics Acceleration](https://developer.android.com/studio/run/emulator-acceleration#accel-graphics), e.g. `emulator -gpu host` and [Virtual Machine(VM) Acceleration](https://developer.android.com/studio/run/emulator-acceleration#accel-vm), e.g. `emulator -accel on`. **Note:** GPU and VM Acceleration are two different and non-mutually exclusive forms of Hardware Acceleration.
|
The old ARM-based emulators were slow and are no longer supported by Google. The modern Intel Atom (x86 and x86_64) emulators can be fast, but rely on two forms of hardware acceleration to reach their peak potential: [Graphics Acceleration](https://developer.android.com/studio/run/emulator-acceleration#accel-graphics), e.g. `emulator -gpu host` and [Virtual Machine(VM) Acceleration](https://developer.android.com/studio/run/emulator-acceleration#accel-vm), e.g. `emulator -accel on`. **Note:** GPU and VM Acceleration are two different and non-mutually exclusive forms of Hardware Acceleration.
|
||||||
|
|
||||||
This presents a challenge when running emulators on CI especially when running emulators within a docker container, because **Nested Virtualization** must be supported by the host VM which isn't the case for most cloud-based CI providers due to infrastructural limits. If you want to learn more about Emulators on CI, here's an article [Yang](https://github.com/ychescale9) wrote: [Running Android Instrumented Tests on CI](https://dev.to/ychescale9/running-android-emulators-on-ci-from-bitrise-io-to-github-actions-3j76).
|
This presents a challenge when running emulators on CI especially when running emulators within a docker container, because **Nested Virtualization** must be supported by the host VM which isn't the case for most cloud-based CI providers due to infrastructural limits. If you want to learn more about Emulators on CI, here's an article [Yang](https://github.com/ychescale9) wrote: [Running Android Instrumented Tests on CI](https://dev.to/ychescale9/running-android-emulators-on-ci-from-bitrise-io-to-github-actions-3j76).
|
||||||
|
|
||||||
|
## Running hardware accelerated emulators on Linux runners
|
||||||
|
|
||||||
|
GitHub's [larger Linux runners support running hardware accelerated emulators](https://github.blog/changelog/2023-02-23-hardware-accelerated-android-virtualization-on-actions-windows-and-linux-larger-hosted-runners/) which is [free for public GitHub repos](https://github.blog/2024-01-17-github-hosted-runners-double-the-power-for-open-source/). It is now recommended to use the **Ubuntu** (`ubuntu-latest`) runners which are 2-3 times faster than the **macOS** ones which are also a lot more expensive. Remember to enable KVM in your workflow before running this action:
|
||||||
|
|
||||||
|
```
|
||||||
|
- name: Enable KVM group perms
|
||||||
|
run: |
|
||||||
|
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
|
||||||
|
sudo udevadm control --reload-rules
|
||||||
|
sudo udevadm trigger --name-match=kvm
|
||||||
|
```
|
||||||
|
|
||||||
## A note on VM Acceleration and why we don't need HAXM anymore
|
## A note on VM Acceleration and why we don't need HAXM anymore
|
||||||
|
|
||||||
According to [this documentation](https://developer.android.com/studio/run/emulator-acceleration#vm-mac), "on Mac OS X v10.10 Yosemite and higher, the Android Emulator uses the built-in [Hypervisor.Framework](https://developer.apple.com/documentation/hypervisor) by default, and falls back to using Intel HAXM if Hypervisor.Framework fails to initialize." This means that **HAXM is only needed to achieve VM Acceleration if this default Hypervisor is not available on macOS machines.**
|
According to [this documentation](https://developer.android.com/studio/run/emulator-acceleration#vm-mac), "on Mac OS X v10.10 Yosemite and higher, the Android Emulator uses the built-in [Hypervisor.Framework](https://developer.apple.com/documentation/hypervisor) by default, and falls back to using Intel HAXM if Hypervisor.Framework fails to initialize." This means that **HAXM is only needed to achieve VM Acceleration if this default Hypervisor is not available on macOS machines.**
|
||||||
@@ -34,10 +46,16 @@ A workflow that uses **android-emulator-runner** to run your instrumented tests
|
|||||||
```yml
|
```yml
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
runs-on: macos-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: checkout
|
- name: checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Enable KVM
|
||||||
|
run: |
|
||||||
|
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
|
||||||
|
sudo udevadm control --reload-rules
|
||||||
|
sudo udevadm trigger --name-match=kvm
|
||||||
|
|
||||||
- name: run tests
|
- name: run tests
|
||||||
uses: reactivecircus/android-emulator-runner@v2
|
uses: reactivecircus/android-emulator-runner@v2
|
||||||
@@ -51,14 +69,20 @@ We can also leverage GitHub Actions's build matrix to test across multiple confi
|
|||||||
```yml
|
```yml
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
runs-on: macos-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
api-level: [21, 23, 29]
|
api-level: [21, 23, 29]
|
||||||
target: [default, google_apis]
|
target: [default, google_apis]
|
||||||
steps:
|
steps:
|
||||||
- name: checkout
|
- name: checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Enable KVM
|
||||||
|
run: |
|
||||||
|
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
|
||||||
|
sudo udevadm control --reload-rules
|
||||||
|
sudo udevadm trigger --name-match=kvm
|
||||||
|
|
||||||
- name: run tests
|
- name: run tests
|
||||||
uses: reactivecircus/android-emulator-runner@v2
|
uses: reactivecircus/android-emulator-runner@v2
|
||||||
@@ -75,10 +99,16 @@ If you need specific versions of **NDK** and **CMake** installed:
|
|||||||
```yml
|
```yml
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
runs-on: macos-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: checkout
|
- name: checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Enable KVM
|
||||||
|
run: |
|
||||||
|
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
|
||||||
|
sudo udevadm control --reload-rules
|
||||||
|
sudo udevadm trigger --name-match=kvm
|
||||||
|
|
||||||
- name: run tests
|
- name: run tests
|
||||||
uses: reactivecircus/android-emulator-runner@v2
|
uses: reactivecircus/android-emulator-runner@v2
|
||||||
@@ -89,29 +119,60 @@ jobs:
|
|||||||
script: ./gradlew connectedCheck
|
script: ./gradlew connectedCheck
|
||||||
```
|
```
|
||||||
|
|
||||||
|
If you need a specific [SDK Extensions](https://developer.android.com/guide/sdk-extensions) for the system image but not the platform:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Enable KVM
|
||||||
|
run: |
|
||||||
|
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
|
||||||
|
sudo udevadm control --reload-rules
|
||||||
|
sudo udevadm trigger --name-match=kvm
|
||||||
|
|
||||||
|
- name: run tests
|
||||||
|
uses: reactivecircus/android-emulator-runner@v2
|
||||||
|
with:
|
||||||
|
api-level: 34
|
||||||
|
system-image-api-level: 34-ext9
|
||||||
|
target: android-automotive
|
||||||
|
script: ./gradlew connectedCheck
|
||||||
|
```
|
||||||
|
|
||||||
We can significantly reduce emulator startup time by setting up AVD snapshot caching:
|
We can significantly reduce emulator startup time by setting up AVD snapshot caching:
|
||||||
|
|
||||||
1. add a `gradle/gradle-build-action@v2` step for caching Gradle, more details see [#229](https://github.com/ReactiveCircus/android-emulator-runner/issues/229)
|
1. add a `gradle/actions/setup-gradle@v4` step for caching Gradle, more details see [#229](https://github.com/ReactiveCircus/android-emulator-runner/issues/229)
|
||||||
2. add an `actions/cache@v3` step for caching the `avd`
|
2. add an `actions/cache@v4` step for caching the `avd`
|
||||||
3. add a `reactivecircus/android-emulator-runner@v2` step to generate a clean snapshot - specify `emulator-options` without `no-snapshot`
|
3. add a `reactivecircus/android-emulator-runner@v2` step to generate a clean snapshot - specify `emulator-options` without `no-snapshot`
|
||||||
4. add another `reactivecircus/android-emulator-runner@v2` step to run your tests using existing AVD / snapshot - specify `emulator-options` with `no-snapshot-save`
|
4. add another `reactivecircus/android-emulator-runner@v2` step to run your tests using existing AVD / snapshot - specify `emulator-options` with `no-snapshot-save`
|
||||||
|
|
||||||
```yml
|
```yml
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
runs-on: macos-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
api-level: [21, 23, 29]
|
api-level: [21, 23, 29]
|
||||||
steps:
|
steps:
|
||||||
- name: checkout
|
- name: checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Enable KVM
|
||||||
|
run: |
|
||||||
|
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
|
||||||
|
sudo udevadm control --reload-rules
|
||||||
|
sudo udevadm trigger --name-match=kvm
|
||||||
|
|
||||||
- name: Gradle cache
|
- name: Gradle cache
|
||||||
uses: gradle/gradle-build-action@v2
|
uses: gradle/actions/setup-gradle@v3
|
||||||
|
|
||||||
- name: AVD cache
|
- name: AVD cache
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v4
|
||||||
id: avd-cache
|
id: avd-cache
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
@@ -143,8 +204,9 @@ jobs:
|
|||||||
|
|
||||||
| **Input** | **Required** | **Default** | **Description** |
|
| **Input** | **Required** | **Default** | **Description** |
|
||||||
|-|-|-|-|
|
|-|-|-|-|
|
||||||
| `api-level` | Required | N/A | API level of the platform system image - e.g. 23 for Android Marshmallow, 29 for Android 10. **Minimum API level supported is 15**. |
|
| `api-level` | Required | N/A | API level of the platform and system image - e.g. `23`, `33`, `35-ext15`, `Baklava`. **Minimum API level supported is 15**. |
|
||||||
| `target` | Optional | `default` | Target of the system image - `default`, `google_apis`, `playstore`, `android-wear`, `android-wear-cn`, `android-tv`, `google-tv`, `aosp_atd` or `google_atd`. Note that `aosp_atd` and `google_atd` currently require the following: `api-level: 30`, `arch: x86` or `arch: arm64-v8` and `channel: canary`. |
|
| `system-image-api-level` | Optional | same as `api-level` | API level of the system image - e.g. `34-ext10`, `35-ext15`. |
|
||||||
|
| `target` | Optional | `default` | Target of the system image - `default`, `google_apis`, `playstore`, `android-wear`, `android-wear-cn`, `android-tv`, `google-tv`, `aosp_atd`, `google_atd`, `android-automotive`, `android-automotive-playstore` or `android-desktop`. Note that `aosp_atd` and `google_atd` currently require the following: `api-level: 30`, `arch: x86` or `arch: arm64-v8` and `channel: canary`. |
|
||||||
| `arch` | Optional | `x86` | CPU architecture of the system image - `x86`, `x86_64` or `arm64-v8a`. Note that `x86_64` image is only available for API 21+. `arm64-v8a` images require Android 4.2+ and are limited to fewer API levels (e.g. 30). |
|
| `arch` | Optional | `x86` | CPU architecture of the system image - `x86`, `x86_64` or `arm64-v8a`. Note that `x86_64` image is only available for API 21+. `arm64-v8a` images require Android 4.2+ and are limited to fewer API levels (e.g. 30). |
|
||||||
| `profile` | Optional | N/A | Hardware profile used for creating the AVD - e.g. `Nexus 6`. For a list of all profiles available, run `avdmanager list device`. |
|
| `profile` | Optional | N/A | Hardware profile used for creating the AVD - e.g. `Nexus 6`. For a list of all profiles available, run `avdmanager list device`. |
|
||||||
| `cores` | Optional | 2 | Number of cores to use for the emulator (`hw.cpu.ncore` in config.ini). |
|
| `cores` | Optional | 2 | Number of cores to use for the emulator (`hw.cpu.ncore` in config.ini). |
|
||||||
@@ -155,6 +217,7 @@ jobs:
|
|||||||
| `avd-name` | Optional | `test` | Custom AVD name used for creating the Android Virtual Device. |
|
| `avd-name` | Optional | `test` | Custom AVD name used for creating the Android Virtual Device. |
|
||||||
| `force-avd-creation` | Optional | `true` | Whether to force create the AVD by overwriting an existing AVD with the same name as `avd-name` - `true` or `false`. |
|
| `force-avd-creation` | Optional | `true` | Whether to force create the AVD by overwriting an existing AVD with the same name as `avd-name` - `true` or `false`. |
|
||||||
| `emulator-boot-timeout` | Optional | `600` | Emulator boot timeout in seconds. If it takes longer to boot, the action would fail - e.g. `300` for 5 minutes. |
|
| `emulator-boot-timeout` | Optional | `600` | Emulator boot timeout in seconds. If it takes longer to boot, the action would fail - e.g. `300` for 5 minutes. |
|
||||||
|
| `emulator-port` | Optional | `5554` | Emulator port to use. Allows to run this action on multiple workers on a single machine at the same time. This input is available for the script as `EMULATOR_PORT` enviromental variable. This port is automatically used by android device related tasks in gradle |
|
||||||
| `emulator-options` | Optional | See below | Command-line options used when launching the emulator (replacing all default options) - e.g. `-no-window -no-snapshot -camera-back emulated`. |
|
| `emulator-options` | Optional | See below | Command-line options used when launching the emulator (replacing all default options) - e.g. `-no-window -no-snapshot -camera-back emulated`. |
|
||||||
| `disable-animations` | Optional | `true` | Whether to disable animations - `true` or `false`. |
|
| `disable-animations` | Optional | `true` | Whether to disable animations - `true` or `false`. |
|
||||||
| `disable-spellchecker` | Optional | `false` | Whether to disable spellchecker - `true` or `false`. |
|
| `disable-spellchecker` | Optional | `false` | Whether to disable spellchecker - `true` or `false`. |
|
||||||
@@ -170,12 +233,6 @@ jobs:
|
|||||||
|
|
||||||
Default `emulator-options`: `-no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim`.
|
Default `emulator-options`: `-no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim`.
|
||||||
|
|
||||||
## Can I use this action on Github Hosted Linux VMs?
|
|
||||||
|
|
||||||
The short answer is yes but on Github-hosted Linux runners it's expected to be a much worse experience (on some newer API levels it might not work at all) than running it on macOS, because of the current lack of hardware acceleration support. You can get it running much faster on self-hosted Linux runners but only if the underlying instances support KVM (which most don't). Things might be better on the newer Larger runners but they are still in Beta. It is possible to use this Action with hardware accelerated Linux VMs hosted by a third-party runner provider.
|
|
||||||
|
|
||||||
For a longer answer please refer to [this issue](https://github.com/ReactiveCircus/android-emulator-runner/issues/46).
|
|
||||||
|
|
||||||
## Who is using Android Emulator Runner?
|
## Who is using Android Emulator Runner?
|
||||||
|
|
||||||
These are some of the open-source projects using (or used) **Android Emulator Runner**:
|
These are some of the open-source projects using (or used) **Android Emulator Runner**:
|
||||||
@@ -210,5 +267,8 @@ These are some of the open-source projects using (or used) **Android Emulator Ru
|
|||||||
- [tinylog-org/tinylog](https://github.com/tinylog-org/tinylog/blob/v3.0/.github/workflows/build.yaml)
|
- [tinylog-org/tinylog](https://github.com/tinylog-org/tinylog/blob/v3.0/.github/workflows/build.yaml)
|
||||||
- [hzi-braunschweig/SORMAS-Project](https://github.com/hzi-braunschweig/SORMAS-Project/blob/development/.github/workflows/sormas_app_ci.yml)
|
- [hzi-braunschweig/SORMAS-Project](https://github.com/hzi-braunschweig/SORMAS-Project/blob/development/.github/workflows/sormas_app_ci.yml)
|
||||||
- [ACRA/acra](https://github.com/ACRA/acra/blob/master/.github/workflows/test.yml)
|
- [ACRA/acra](https://github.com/ACRA/acra/blob/master/.github/workflows/test.yml)
|
||||||
|
- [bitfireAT/davx5-ose](https://github.com/bitfireAT/davx5-ose/blob/dev-ose/.github/workflows/test-dev.yml)
|
||||||
|
- [robolectric/robolectric](https://github.com/robolectric/robolectric/blob/master/.github/workflows/tests.yml)
|
||||||
|
- [home-assistant/android](https://github.com/home-assistant/android/blob/master/.github/workflows/pr.yml)
|
||||||
|
|
||||||
If you are using **Android Emulator Runner** and want your project included in the list, please feel free to open a pull request.
|
If you are using **Android Emulator Runner** and want your project included in the list, please feel free to open a pull request.
|
||||||
|
|||||||
@@ -1,47 +1,5 @@
|
|||||||
import * as validator from '../src/input-validator';
|
import * as validator from '../src/input-validator';
|
||||||
|
import { MAX_PORT, MIN_PORT } from '../src/input-validator';
|
||||||
describe('api-level validator tests', () => {
|
|
||||||
it('Throws if api-level is not a number', () => {
|
|
||||||
const func = () => {
|
|
||||||
validator.checkApiLevel('api');
|
|
||||||
};
|
|
||||||
expect(func).toThrowError(`Unexpected API level: 'api'.`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Throws if api-level is not an integer', () => {
|
|
||||||
const func = () => {
|
|
||||||
validator.checkApiLevel('29.1');
|
|
||||||
};
|
|
||||||
expect(func).toThrowError(`Unexpected API level: '29.1'.`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Throws if api-level is lower than min API supported', () => {
|
|
||||||
const func = () => {
|
|
||||||
validator.checkApiLevel('14');
|
|
||||||
};
|
|
||||||
expect(func).toThrowError(`Minimum API level supported is ${validator.MIN_API_LEVEL}.`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Validates successfully with valid api-level', () => {
|
|
||||||
const func1 = () => {
|
|
||||||
validator.checkApiLevel('15');
|
|
||||||
};
|
|
||||||
expect(func1).not.toThrow();
|
|
||||||
|
|
||||||
const func2 = () => {
|
|
||||||
validator.checkApiLevel('29');
|
|
||||||
};
|
|
||||||
expect(func2).not.toThrow();
|
|
||||||
const func3 = () => {
|
|
||||||
validator.checkApiLevel('UpsideDownCake-ext5');
|
|
||||||
};
|
|
||||||
expect(func3).not.toThrow();
|
|
||||||
const func4 = () => {
|
|
||||||
validator.checkApiLevel('TiramisuPrivacySandbox');
|
|
||||||
};
|
|
||||||
expect(func4).not.toThrow();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('target validator tests', () => {
|
describe('target validator tests', () => {
|
||||||
it('Throws if target is unknown', () => {
|
it('Throws if target is unknown', () => {
|
||||||
@@ -96,6 +54,21 @@ describe('target validator tests', () => {
|
|||||||
validator.checkTarget('google-tv');
|
validator.checkTarget('google-tv');
|
||||||
};
|
};
|
||||||
expect(func9).not.toThrow();
|
expect(func9).not.toThrow();
|
||||||
|
|
||||||
|
const func10 = () => {
|
||||||
|
validator.checkTarget('android-automotive');
|
||||||
|
};
|
||||||
|
expect(func10).not.toThrow();
|
||||||
|
|
||||||
|
const func11 = () => {
|
||||||
|
validator.checkTarget('android-automotive-playstore');
|
||||||
|
};
|
||||||
|
expect(func11).not.toThrow();
|
||||||
|
|
||||||
|
const func12 = () => {
|
||||||
|
validator.checkTarget('android-desktop');
|
||||||
|
};
|
||||||
|
expect(func12).not.toThrow();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -172,6 +145,33 @@ describe('force-avd-creation validator tests', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('emulator-port validator tests', () => {
|
||||||
|
it('Validates if emulator-port is even and in range', () => {
|
||||||
|
const func = () => {
|
||||||
|
validator.checkPort(5554);
|
||||||
|
};
|
||||||
|
expect(func).not.toThrow();
|
||||||
|
});
|
||||||
|
it('Throws if emulator-port is lower than MIN_PORT', () => {
|
||||||
|
const func = () => {
|
||||||
|
validator.checkPort(MIN_PORT - 2);
|
||||||
|
};
|
||||||
|
expect(func).toThrow();
|
||||||
|
});
|
||||||
|
it('Throws if emulator-port is higher than MAX_PORT', () => {
|
||||||
|
const func = () => {
|
||||||
|
validator.checkPort(MAX_PORT + 2);
|
||||||
|
};
|
||||||
|
expect(func).toThrow();
|
||||||
|
});
|
||||||
|
it('Throws if emulator-port is odd', () => {
|
||||||
|
const func = () => {
|
||||||
|
validator.checkPort(5555);
|
||||||
|
};
|
||||||
|
expect(func).toThrow();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('disable-animations validator tests', () => {
|
describe('disable-animations validator tests', () => {
|
||||||
it('Throws if disable-animations is not a boolean', () => {
|
it('Throws if disable-animations is not a boolean', () => {
|
||||||
const func = () => {
|
const func = () => {
|
||||||
|
|||||||
+8
-1
@@ -1,6 +1,8 @@
|
|||||||
inputs:
|
inputs:
|
||||||
api-level:
|
api-level:
|
||||||
type: integer
|
type: string
|
||||||
|
system-image-api-level:
|
||||||
|
type: string
|
||||||
target:
|
target:
|
||||||
type: enum
|
type: enum
|
||||||
allowed-values:
|
allowed-values:
|
||||||
@@ -13,6 +15,9 @@ inputs:
|
|||||||
- android-wear-cn
|
- android-wear-cn
|
||||||
- android-tv
|
- android-tv
|
||||||
- google-tv
|
- google-tv
|
||||||
|
- android-automotive
|
||||||
|
- android-automotive-playstore
|
||||||
|
- android-desktop
|
||||||
arch:
|
arch:
|
||||||
type: enum
|
type: enum
|
||||||
allowed-values:
|
allowed-values:
|
||||||
@@ -37,6 +42,8 @@ inputs:
|
|||||||
type: boolean
|
type: boolean
|
||||||
emulator-boot-timeout:
|
emulator-boot-timeout:
|
||||||
type: integer
|
type: integer
|
||||||
|
emulator-port:
|
||||||
|
type: integer
|
||||||
emulator-options:
|
emulator-options:
|
||||||
type: string
|
type: string
|
||||||
disable-animations:
|
disable-animations:
|
||||||
|
|||||||
+10
-4
@@ -1,15 +1,18 @@
|
|||||||
name: 'Android Emulator Runner'
|
name: 'Android Emulator Runner'
|
||||||
description: 'Installs, configures and starts an Android Emulator directly on macOS virtual machines.'
|
description: 'Installs, configures and starts an Android Emulator directly on hardware-accelerated runners.'
|
||||||
author: 'Reactive Circus'
|
author: 'Reactive Circus'
|
||||||
branding:
|
branding:
|
||||||
icon: 'smartphone'
|
icon: 'smartphone'
|
||||||
color: 'green'
|
color: 'green'
|
||||||
inputs:
|
inputs:
|
||||||
api-level:
|
api-level:
|
||||||
description: 'API level of the platform and system image - e.g. 23 for Android Marshmallow, 29 for Android 10'
|
description: 'API level of the platform and system image - e.g. 23, 33, 35-ext15, Baklava'
|
||||||
required: true
|
required: true
|
||||||
|
system-image-api-level:
|
||||||
|
description: 'API level of the system image - e.g. 34-ext10, 35-ext15. If not set the `api-level` input will be used.'
|
||||||
|
required: false
|
||||||
target:
|
target:
|
||||||
description: 'target of the system image - default, google_apis, google_apis_playstore, aosp_atd, google_atd, android-wear, android-wear-cn, android-tv or google-tv'
|
description: 'target of the system image - default, google_apis, google_apis_playstore, aosp_atd, google_atd, android-wear, android-wear-cn, android-tv, google-tv, android-automotive, android-automotive-playstore or android-desktop'
|
||||||
default: 'default'
|
default: 'default'
|
||||||
arch:
|
arch:
|
||||||
description: 'CPU architecture of the system image - x86, x86_64 or arm64-v8a'
|
description: 'CPU architecture of the system image - x86, x86_64 or arm64-v8a'
|
||||||
@@ -36,6 +39,9 @@ inputs:
|
|||||||
emulator-boot-timeout:
|
emulator-boot-timeout:
|
||||||
description: 'Emulator boot timeout in seconds. If it takes longer to boot, the action would fail - e.g. `300` for 5 minutes'
|
description: 'Emulator boot timeout in seconds. If it takes longer to boot, the action would fail - e.g. `300` for 5 minutes'
|
||||||
default: '600'
|
default: '600'
|
||||||
|
emulator-port:
|
||||||
|
description: 'Port to run emulator on, allows to run multiple emulators on the same physical machine'
|
||||||
|
default: '5554'
|
||||||
emulator-options:
|
emulator-options:
|
||||||
description: 'command-line options used when launching the emulator - e.g. `-no-window -no-snapshot -camera-back emulated`'
|
description: 'command-line options used when launching the emulator - e.g. `-no-window -no-snapshot -camera-back emulated`'
|
||||||
default: '-no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim'
|
default: '-no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim'
|
||||||
@@ -68,5 +74,5 @@ inputs:
|
|||||||
pre-emulator-launch-script:
|
pre-emulator-launch-script:
|
||||||
description: 'custom script to run after creating the AVD and before launching the emulator - e.g. `./adjust-emulator-configs.sh`'
|
description: 'custom script to run after creating the AVD and before launching the emulator - e.g. `./adjust-emulator-configs.sh`'
|
||||||
runs:
|
runs:
|
||||||
using: 'node16'
|
using: 'node20'
|
||||||
main: 'lib/main.js'
|
main: 'lib/main.js'
|
||||||
|
|||||||
+20
-15
@@ -38,7 +38,7 @@ const fs = __importStar(require("fs"));
|
|||||||
/**
|
/**
|
||||||
* Creates and launches a new AVD instance with the specified configurations.
|
* Creates and launches a new AVD instance with the specified configurations.
|
||||||
*/
|
*/
|
||||||
function launchEmulator(apiLevel, target, arch, profile, cores, ramSize, heapSize, sdcardPathOrSize, diskSize, avdName, forceAvdCreation, emulatorBootTimeout, emulatorOptions, disableAnimations, disableSpellChecker, disableLinuxHardwareAcceleration, enableHardwareKeyboard) {
|
function launchEmulator(systemImageApiLevel, target, arch, profile, cores, ramSize, heapSize, sdcardPathOrSize, diskSize, avdName, forceAvdCreation, emulatorBootTimeout, port, emulatorOptions, disableAnimations, disableSpellChecker, disableLinuxHardwareAcceleration, enableHardwareKeyboard) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
try {
|
try {
|
||||||
console.log(`::group::Launch Emulator`);
|
console.log(`::group::Launch Emulator`);
|
||||||
@@ -48,7 +48,7 @@ function launchEmulator(apiLevel, target, arch, profile, cores, ramSize, heapSiz
|
|||||||
const profileOption = profile.trim() !== '' ? `--device '${profile}'` : '';
|
const profileOption = profile.trim() !== '' ? `--device '${profile}'` : '';
|
||||||
const sdcardPathOrSizeOption = sdcardPathOrSize.trim() !== '' ? `--sdcard '${sdcardPathOrSize}'` : '';
|
const sdcardPathOrSizeOption = sdcardPathOrSize.trim() !== '' ? `--sdcard '${sdcardPathOrSize}'` : '';
|
||||||
console.log(`Creating AVD.`);
|
console.log(`Creating AVD.`);
|
||||||
yield exec.exec(`sh -c \\"echo no | avdmanager create avd --force -n "${avdName}" --abi '${target}/${arch}' --package 'system-images;android-${apiLevel};${target};${arch}' ${profileOption} ${sdcardPathOrSizeOption}"`);
|
yield exec.exec(`sh -c \\"echo no | avdmanager create avd --force -n "${avdName}" --abi '${target}/${arch}' --package 'system-images;android-${systemImageApiLevel};${target};${arch}' ${profileOption} ${sdcardPathOrSizeOption}"`);
|
||||||
}
|
}
|
||||||
if (cores) {
|
if (cores) {
|
||||||
yield exec.exec(`sh -c \\"printf 'hw.cpu.ncore=${cores}\n' >> ${process.env.ANDROID_AVD_HOME}/"${avdName}".avd"/config.ini`);
|
yield exec.exec(`sh -c \\"printf 'hw.cpu.ncore=${cores}\n' >> ${process.env.ANDROID_AVD_HOME}/"${avdName}".avd"/config.ini`);
|
||||||
@@ -65,14 +65,14 @@ function launchEmulator(apiLevel, target, arch, profile, cores, ramSize, heapSiz
|
|||||||
if (diskSize) {
|
if (diskSize) {
|
||||||
yield exec.exec(`sh -c \\"printf 'disk.dataPartition.size=${diskSize}\n' >> ${process.env.ANDROID_AVD_HOME}/"${avdName}".avd"/config.ini`);
|
yield exec.exec(`sh -c \\"printf 'disk.dataPartition.size=${diskSize}\n' >> ${process.env.ANDROID_AVD_HOME}/"${avdName}".avd"/config.ini`);
|
||||||
}
|
}
|
||||||
//turn off hardware acceleration on Linux
|
// turn off hardware acceleration on Linux
|
||||||
if (process.platform === 'linux' && disableLinuxHardwareAcceleration) {
|
if (process.platform === 'linux' && disableLinuxHardwareAcceleration) {
|
||||||
console.log('Disabling Linux hardware acceleration.');
|
console.log('Disabling Linux hardware acceleration.');
|
||||||
emulatorOptions += ' -accel off';
|
emulatorOptions += ' -accel off';
|
||||||
}
|
}
|
||||||
// start emulator
|
// start emulator
|
||||||
console.log('Starting emulator.');
|
console.log('Starting emulator.');
|
||||||
yield exec.exec(`sh -c \\"${process.env.ANDROID_HOME}/emulator/emulator -avd "${avdName}" ${emulatorOptions} &"`, [], {
|
yield exec.exec(`sh -c \\"${process.env.ANDROID_HOME}/emulator/emulator -port ${port} -avd "${avdName}" ${emulatorOptions} &"`, [], {
|
||||||
listeners: {
|
listeners: {
|
||||||
stderr: (data) => {
|
stderr: (data) => {
|
||||||
if (data.toString().includes('invalid command-line parameter')) {
|
if (data.toString().includes('invalid command-line parameter')) {
|
||||||
@@ -82,19 +82,19 @@ function launchEmulator(apiLevel, target, arch, profile, cores, ramSize, heapSiz
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
// wait for emulator to complete booting
|
// wait for emulator to complete booting
|
||||||
yield waitForDevice(emulatorBootTimeout);
|
yield waitForDevice(port, emulatorBootTimeout);
|
||||||
yield exec.exec(`adb shell input keyevent 82`);
|
yield adb(port, `shell input keyevent 82`);
|
||||||
if (disableAnimations) {
|
if (disableAnimations) {
|
||||||
console.log('Disabling animations.');
|
console.log('Disabling animations.');
|
||||||
yield exec.exec(`adb shell settings put global window_animation_scale 0.0`);
|
yield adb(port, `shell settings put global window_animation_scale 0.0`);
|
||||||
yield exec.exec(`adb shell settings put global transition_animation_scale 0.0`);
|
yield adb(port, `shell settings put global transition_animation_scale 0.0`);
|
||||||
yield exec.exec(`adb shell settings put global animator_duration_scale 0.0`);
|
yield adb(port, `shell settings put global animator_duration_scale 0.0`);
|
||||||
}
|
}
|
||||||
if (disableSpellChecker) {
|
if (disableSpellChecker) {
|
||||||
yield exec.exec(`adb shell settings put secure spell_checker_enabled 0`);
|
yield adb(port, `shell settings put secure spell_checker_enabled 0`);
|
||||||
}
|
}
|
||||||
if (enableHardwareKeyboard) {
|
if (enableHardwareKeyboard) {
|
||||||
yield exec.exec(`adb shell settings put secure show_ime_with_hard_keyboard 0`);
|
yield adb(port, `shell settings put secure show_ime_with_hard_keyboard 0`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
@@ -106,11 +106,11 @@ exports.launchEmulator = launchEmulator;
|
|||||||
/**
|
/**
|
||||||
* Kills the running emulator on the default port.
|
* Kills the running emulator on the default port.
|
||||||
*/
|
*/
|
||||||
function killEmulator() {
|
function killEmulator(port) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
try {
|
try {
|
||||||
console.log(`::group::Terminate Emulator`);
|
console.log(`::group::Terminate Emulator`);
|
||||||
yield exec.exec(`adb -s emulator-5554 emu kill`);
|
yield adb(port, `emu kill`);
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
console.log(error instanceof Error ? error.message : error);
|
console.log(error instanceof Error ? error.message : error);
|
||||||
@@ -121,10 +121,15 @@ function killEmulator() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
exports.killEmulator = killEmulator;
|
exports.killEmulator = killEmulator;
|
||||||
|
function adb(port, command) {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
return yield exec.exec(`adb -s emulator-${port} ${command}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Wait for emulator to boot.
|
* Wait for emulator to boot.
|
||||||
*/
|
*/
|
||||||
function waitForDevice(emulatorBootTimeout) {
|
function waitForDevice(port, emulatorBootTimeout) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
let booted = false;
|
let booted = false;
|
||||||
let attempts = 0;
|
let attempts = 0;
|
||||||
@@ -133,7 +138,7 @@ function waitForDevice(emulatorBootTimeout) {
|
|||||||
while (!booted) {
|
while (!booted) {
|
||||||
try {
|
try {
|
||||||
let result = '';
|
let result = '';
|
||||||
yield exec.exec(`adb shell getprop sys.boot_completed`, [], {
|
yield exec.exec(`adb -s emulator-${port} shell getprop sys.boot_completed`, [], {
|
||||||
listeners: {
|
listeners: {
|
||||||
stdout: (data) => {
|
stdout: (data) => {
|
||||||
result += data.toString();
|
result += data.toString();
|
||||||
|
|||||||
+26
-13
@@ -1,21 +1,25 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.checkDiskSize = exports.checkEmulatorBuild = exports.checkEnableHardwareKeyboard = exports.checkDisableLinuxHardwareAcceleration = exports.checkDisableSpellchecker = exports.checkDisableAnimations = exports.checkForceAvdCreation = exports.checkChannel = exports.checkArch = exports.checkTarget = exports.checkApiLevel = exports.VALID_CHANNELS = exports.VALID_ARCHS = exports.VALID_TARGETS = exports.MIN_API_LEVEL = void 0;
|
exports.checkDiskSize = exports.checkEmulatorBuild = exports.checkEnableHardwareKeyboard = exports.checkDisableLinuxHardwareAcceleration = exports.checkDisableSpellchecker = exports.checkDisableAnimations = exports.checkPort = exports.checkForceAvdCreation = exports.checkChannel = exports.checkArch = exports.checkTarget = exports.MAX_PORT = exports.MIN_PORT = exports.VALID_CHANNELS = exports.VALID_ARCHS = exports.VALID_TARGETS = exports.MIN_API_LEVEL = void 0;
|
||||||
exports.MIN_API_LEVEL = 15;
|
exports.MIN_API_LEVEL = 15;
|
||||||
exports.VALID_TARGETS = ['default', 'google_apis', 'aosp_atd', 'google_atd', 'google_apis_playstore', 'android-wear', 'android-wear-cn', 'android-tv', 'google-tv'];
|
exports.VALID_TARGETS = [
|
||||||
|
'default',
|
||||||
|
'google_apis',
|
||||||
|
'aosp_atd',
|
||||||
|
'google_atd',
|
||||||
|
'google_apis_playstore',
|
||||||
|
'android-wear',
|
||||||
|
'android-wear-cn',
|
||||||
|
'android-tv',
|
||||||
|
'google-tv',
|
||||||
|
'android-automotive',
|
||||||
|
'android-automotive-playstore',
|
||||||
|
'android-desktop',
|
||||||
|
];
|
||||||
exports.VALID_ARCHS = ['x86', 'x86_64', 'arm64-v8a'];
|
exports.VALID_ARCHS = ['x86', 'x86_64', 'arm64-v8a'];
|
||||||
exports.VALID_CHANNELS = ['stable', 'beta', 'dev', 'canary'];
|
exports.VALID_CHANNELS = ['stable', 'beta', 'dev', 'canary'];
|
||||||
function checkApiLevel(apiLevel) {
|
exports.MIN_PORT = 5554;
|
||||||
if (apiLevel.startsWith('UpsideDownCake') || apiLevel === 'TiramisuPrivacySandbox')
|
exports.MAX_PORT = 5584;
|
||||||
return;
|
|
||||||
if (isNaN(Number(apiLevel)) || !Number.isInteger(Number(apiLevel))) {
|
|
||||||
throw new Error(`Unexpected API level: '${apiLevel}'.`);
|
|
||||||
}
|
|
||||||
if (Number(apiLevel) < exports.MIN_API_LEVEL) {
|
|
||||||
throw new Error(`Minimum API level supported is ${exports.MIN_API_LEVEL}.`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.checkApiLevel = checkApiLevel;
|
|
||||||
function checkTarget(target) {
|
function checkTarget(target) {
|
||||||
if (!exports.VALID_TARGETS.includes(target)) {
|
if (!exports.VALID_TARGETS.includes(target)) {
|
||||||
throw new Error(`Value for input.target '${target}' is unknown. Supported options: ${exports.VALID_TARGETS}.`);
|
throw new Error(`Value for input.target '${target}' is unknown. Supported options: ${exports.VALID_TARGETS}.`);
|
||||||
@@ -40,6 +44,15 @@ function checkForceAvdCreation(forceAvdCreation) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports.checkForceAvdCreation = checkForceAvdCreation;
|
exports.checkForceAvdCreation = checkForceAvdCreation;
|
||||||
|
function checkPort(port) {
|
||||||
|
if (port < exports.MIN_PORT || port > exports.MAX_PORT) {
|
||||||
|
throw new Error(`Emulator port is outside of the supported port range [${exports.MIN_PORT}, ${exports.MAX_PORT}], was ${port}`);
|
||||||
|
}
|
||||||
|
if (port % 2 == 1) {
|
||||||
|
throw new Error(`Emulator port has to be even, was ${port}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.checkPort = checkPort;
|
||||||
function checkDisableAnimations(disableAnimations) {
|
function checkDisableAnimations(disableAnimations) {
|
||||||
if (!isValidBoolean(disableAnimations)) {
|
if (!isValidBoolean(disableAnimations)) {
|
||||||
throw new Error(`Input for input.disable-animations should be either 'true' or 'false'.`);
|
throw new Error(`Input for input.disable-animations should be either 'true' or 'false'.`);
|
||||||
|
|||||||
+17
-6
@@ -42,6 +42,7 @@ const channel_id_mapper_1 = require("./channel-id-mapper");
|
|||||||
const fs_1 = require("fs");
|
const fs_1 = require("fs");
|
||||||
function run() {
|
function run() {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
let port = input_validator_1.MIN_PORT;
|
||||||
try {
|
try {
|
||||||
console.log(`::group::Configure emulator`);
|
console.log(`::group::Configure emulator`);
|
||||||
let linuxSupportKVM = false;
|
let linuxSupportKVM = false;
|
||||||
@@ -62,8 +63,12 @@ function run() {
|
|||||||
}
|
}
|
||||||
// API level of the platform and system image
|
// API level of the platform and system image
|
||||||
const apiLevel = core.getInput('api-level', { required: true });
|
const apiLevel = core.getInput('api-level', { required: true });
|
||||||
(0, input_validator_1.checkApiLevel)(apiLevel);
|
|
||||||
console.log(`API level: ${apiLevel}`);
|
console.log(`API level: ${apiLevel}`);
|
||||||
|
let systemImageApiLevel = core.getInput('system-image-api-level');
|
||||||
|
if (!systemImageApiLevel) {
|
||||||
|
systemImageApiLevel = apiLevel;
|
||||||
|
}
|
||||||
|
console.log(`System image API level: ${systemImageApiLevel}`);
|
||||||
// target of the system image
|
// target of the system image
|
||||||
const targetInput = core.getInput('target');
|
const targetInput = core.getInput('target');
|
||||||
const target = targetInput == 'playstore' ? 'google_apis_playstore' : targetInput;
|
const target = targetInput == 'playstore' ? 'google_apis_playstore' : targetInput;
|
||||||
@@ -102,6 +107,10 @@ function run() {
|
|||||||
// Emulator boot timeout seconds
|
// Emulator boot timeout seconds
|
||||||
const emulatorBootTimeout = parseInt(core.getInput('emulator-boot-timeout'), 10);
|
const emulatorBootTimeout = parseInt(core.getInput('emulator-boot-timeout'), 10);
|
||||||
console.log(`Emulator boot timeout: ${emulatorBootTimeout}`);
|
console.log(`Emulator boot timeout: ${emulatorBootTimeout}`);
|
||||||
|
// Emulator port to use
|
||||||
|
port = parseInt(core.getInput('emulator-port'), 10);
|
||||||
|
(0, input_validator_1.checkPort)(port);
|
||||||
|
console.log(`emulator port: ${port}`);
|
||||||
// emulator options
|
// emulator options
|
||||||
const emulatorOptions = core.getInput('emulator-options').trim();
|
const emulatorOptions = core.getInput('emulator-options').trim();
|
||||||
console.log(`emulator options: ${emulatorOptions}`);
|
console.log(`emulator options: ${emulatorOptions}`);
|
||||||
@@ -174,7 +183,7 @@ function run() {
|
|||||||
}));
|
}));
|
||||||
console.log(`::endgroup::`);
|
console.log(`::endgroup::`);
|
||||||
// install SDK
|
// install SDK
|
||||||
yield (0, sdk_installer_1.installAndroidSdk)(apiLevel, target, arch, channelId, emulatorBuild, ndkVersion, cmakeVersion);
|
yield (0, sdk_installer_1.installAndroidSdk)(apiLevel, systemImageApiLevel, target, arch, channelId, emulatorBuild, ndkVersion, cmakeVersion);
|
||||||
// execute pre emulator launch script if set
|
// execute pre emulator launch script if set
|
||||||
if (preEmulatorLaunchScripts !== undefined) {
|
if (preEmulatorLaunchScripts !== undefined) {
|
||||||
console.log(`::group::Run pre emulator launch script`);
|
console.log(`::group::Run pre emulator launch script`);
|
||||||
@@ -193,7 +202,7 @@ function run() {
|
|||||||
console.log(`::endgroup::`);
|
console.log(`::endgroup::`);
|
||||||
}
|
}
|
||||||
// launch an emulator
|
// launch an emulator
|
||||||
yield (0, emulator_manager_1.launchEmulator)(apiLevel, target, arch, profile, cores, ramSize, heapSize, sdcardPathOrSize, diskSize, avdName, forceAvdCreation, emulatorBootTimeout, emulatorOptions, disableAnimations, disableSpellchecker, disableLinuxHardwareAcceleration, enableHardwareKeyboard);
|
yield (0, emulator_manager_1.launchEmulator)(systemImageApiLevel, target, arch, profile, cores, ramSize, heapSize, sdcardPathOrSize, diskSize, avdName, forceAvdCreation, emulatorBootTimeout, port, emulatorOptions, disableAnimations, disableSpellchecker, disableLinuxHardwareAcceleration, enableHardwareKeyboard);
|
||||||
// execute the custom script
|
// execute the custom script
|
||||||
try {
|
try {
|
||||||
// move to custom working directory if set
|
// move to custom working directory if set
|
||||||
@@ -203,18 +212,20 @@ function run() {
|
|||||||
for (const script of scripts) {
|
for (const script of scripts) {
|
||||||
// use array form to avoid various quote escaping problems
|
// use array form to avoid various quote escaping problems
|
||||||
// caused by exec(`sh -c "${script}"`)
|
// caused by exec(`sh -c "${script}"`)
|
||||||
yield exec.exec('sh', ['-c', script]);
|
yield exec.exec('sh', ['-c', script], {
|
||||||
|
env: Object.assign(Object.assign({}, process.env), { EMULATOR_PORT: `${port}`, ANDROID_SERIAL: `emulator-${port}` }),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
core.setFailed(error instanceof Error ? error.message : error);
|
core.setFailed(error instanceof Error ? error.message : error);
|
||||||
}
|
}
|
||||||
// finally kill the emulator
|
// finally kill the emulator
|
||||||
yield (0, emulator_manager_1.killEmulator)();
|
yield (0, emulator_manager_1.killEmulator)(port);
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
// kill the emulator so the action can exit
|
// kill the emulator so the action can exit
|
||||||
yield (0, emulator_manager_1.killEmulator)();
|
yield (0, emulator_manager_1.killEmulator)(port);
|
||||||
core.setFailed(error instanceof Error ? error.message : error);
|
core.setFailed(error instanceof Error ? error.message : error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
+25
-11
@@ -38,22 +38,20 @@ const exec = __importStar(require("@actions/exec"));
|
|||||||
const io = __importStar(require("@actions/io"));
|
const io = __importStar(require("@actions/io"));
|
||||||
const tc = __importStar(require("@actions/tool-cache"));
|
const tc = __importStar(require("@actions/tool-cache"));
|
||||||
const fs = __importStar(require("fs"));
|
const fs = __importStar(require("fs"));
|
||||||
const BUILD_TOOLS_VERSION = '33.0.2';
|
const BUILD_TOOLS_VERSION = '35.0.0';
|
||||||
// SDK command-line tools 9.0
|
// SDK command-line tools 16.0
|
||||||
const CMDLINE_TOOLS_URL_MAC = 'https://dl.google.com/android/repository/commandlinetools-mac-9477386_latest.zip';
|
const CMDLINE_TOOLS_URL_MAC = 'https://dl.google.com/android/repository/commandlinetools-mac-12266719_latest.zip';
|
||||||
const CMDLINE_TOOLS_URL_LINUX = 'https://dl.google.com/android/repository/commandlinetools-linux-9477386_latest.zip';
|
const CMDLINE_TOOLS_URL_LINUX = 'https://dl.google.com/android/repository/commandlinetools-linux-12266719_latest.zip';
|
||||||
/**
|
/**
|
||||||
* Installs & updates the Android SDK for the macOS platform, including SDK platform for the chosen API level, latest build tools, platform tools, Android Emulator,
|
* Installs & updates the Android SDK for the macOS platform, including SDK platform for the chosen API level, latest build tools, platform tools, Android Emulator,
|
||||||
* and the system image for the chosen API level, CPU arch, and target.
|
* and the system image for the chosen API level, CPU arch, and target.
|
||||||
*/
|
*/
|
||||||
function installAndroidSdk(apiLevel, target, arch, channelId, emulatorBuild, ndkVersion, cmakeVersion) {
|
function installAndroidSdk(apiLevel, systemImageApiLevel, target, arch, channelId, emulatorBuild, ndkVersion, cmakeVersion) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
try {
|
try {
|
||||||
console.log(`::group::Install Android SDK`);
|
console.log(`::group::Install Android SDK`);
|
||||||
const isOnMac = process.platform === 'darwin';
|
const isOnMac = process.platform === 'darwin';
|
||||||
if (!isOnMac) {
|
const isArm = process.arch === 'arm64';
|
||||||
yield exec.exec(`sh -c \\"sudo chown $USER:$USER ${process.env.ANDROID_HOME} -R`);
|
|
||||||
}
|
|
||||||
const cmdlineToolsPath = `${process.env.ANDROID_HOME}/cmdline-tools`;
|
const cmdlineToolsPath = `${process.env.ANDROID_HOME}/cmdline-tools`;
|
||||||
if (!fs.existsSync(cmdlineToolsPath)) {
|
if (!fs.existsSync(cmdlineToolsPath)) {
|
||||||
console.log('Installing new cmdline-tools.');
|
console.log('Installing new cmdline-tools.');
|
||||||
@@ -65,23 +63,39 @@ function installAndroidSdk(apiLevel, target, arch, channelId, emulatorBuild, ndk
|
|||||||
// add paths for commandline-tools and platform-tools
|
// add paths for commandline-tools and platform-tools
|
||||||
core.addPath(`${cmdlineToolsPath}/latest:${cmdlineToolsPath}/latest/bin:${process.env.ANDROID_HOME}/platform-tools`);
|
core.addPath(`${cmdlineToolsPath}/latest:${cmdlineToolsPath}/latest/bin:${process.env.ANDROID_HOME}/platform-tools`);
|
||||||
// set standard AVD path
|
// set standard AVD path
|
||||||
|
yield io.mkdirP(`${process.env.HOME}/.android/avd`);
|
||||||
core.exportVariable('ANDROID_AVD_HOME', `${process.env.HOME}/.android/avd`);
|
core.exportVariable('ANDROID_AVD_HOME', `${process.env.HOME}/.android/avd`);
|
||||||
// accept all Android SDK licenses
|
// accept all Android SDK licenses
|
||||||
yield exec.exec(`sh -c \\"yes | sdkmanager --licenses > /dev/null"`);
|
yield exec.exec(`sh -c \\"yes | sdkmanager --licenses > /dev/null"`);
|
||||||
console.log('Installing latest build tools, platform tools, and platform.');
|
console.log('Installing latest build tools, platform tools, and platform.');
|
||||||
yield exec.exec(`sh -c \\"sdkmanager --install 'build-tools;${BUILD_TOOLS_VERSION}' platform-tools > /dev/null"`);
|
yield exec.exec(`sh -c \\"sdkmanager --install 'build-tools;${BUILD_TOOLS_VERSION}' platform-tools 'platforms;android-${apiLevel}'> /dev/null"`);
|
||||||
console.log('Installing latest emulator.');
|
console.log('Installing latest emulator.');
|
||||||
yield exec.exec(`sh -c \\"sdkmanager --install emulator --channel=${channelId} > /dev/null"`);
|
yield exec.exec(`sh -c \\"sdkmanager --install emulator --channel=${channelId} > /dev/null"`);
|
||||||
if (emulatorBuild) {
|
if (emulatorBuild) {
|
||||||
console.log(`Installing emulator build ${emulatorBuild}.`);
|
console.log(`Installing emulator build ${emulatorBuild}.`);
|
||||||
// TODO find out the correct download URLs for all build ids
|
// TODO find out the correct download URLs for all build ids
|
||||||
const downloadUrlSuffix = Number(emulatorBuild.charAt(0)) > 6 ? `_x64-${emulatorBuild}` : `-${emulatorBuild}`;
|
var downloadUrlSuffix;
|
||||||
|
const majorBuildVersion = Number(emulatorBuild);
|
||||||
|
if (majorBuildVersion >= 8000000) {
|
||||||
|
if (isArm) {
|
||||||
|
downloadUrlSuffix = `_aarch64-${emulatorBuild}`;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
downloadUrlSuffix = `_x64-${emulatorBuild}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (majorBuildVersion >= 7000000) {
|
||||||
|
downloadUrlSuffix = `_x64-${emulatorBuild}`;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
downloadUrlSuffix = `-${emulatorBuild}`;
|
||||||
|
}
|
||||||
yield exec.exec(`curl -fo emulator.zip https://dl.google.com/android/repository/emulator-${isOnMac ? 'darwin' : 'linux'}${downloadUrlSuffix}.zip`);
|
yield exec.exec(`curl -fo emulator.zip https://dl.google.com/android/repository/emulator-${isOnMac ? 'darwin' : 'linux'}${downloadUrlSuffix}.zip`);
|
||||||
yield exec.exec(`unzip -o -q emulator.zip -d ${process.env.ANDROID_HOME}`);
|
yield exec.exec(`unzip -o -q emulator.zip -d ${process.env.ANDROID_HOME}`);
|
||||||
yield io.rmRF('emulator.zip');
|
yield io.rmRF('emulator.zip');
|
||||||
}
|
}
|
||||||
console.log('Installing system images.');
|
console.log('Installing system images.');
|
||||||
yield exec.exec(`sh -c \\"sdkmanager --install 'system-images;android-${apiLevel};${target};${arch}' --channel=${channelId} > /dev/null"`);
|
yield exec.exec(`sh -c \\"sdkmanager --install 'system-images;android-${systemImageApiLevel};${target};${arch}' --channel=${channelId} > /dev/null"`);
|
||||||
if (ndkVersion) {
|
if (ndkVersion) {
|
||||||
console.log(`Installing NDK ${ndkVersion}.`);
|
console.log(`Installing NDK ${ndkVersion}.`);
|
||||||
yield exec.exec(`sh -c \\"sdkmanager --install 'ndk;${ndkVersion}' --channel=${channelId} > /dev/null"`);
|
yield exec.exec(`sh -c \\"sdkmanager --install 'ndk;${ndkVersion}' --channel=${channelId} > /dev/null"`);
|
||||||
|
|||||||
+13
-13
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "android-emulator-runner",
|
"name": "android-emulator-runner",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"node_modules/@actions/core": {
|
"node_modules/@actions/core": {
|
||||||
@@ -22,17 +22,17 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@actions/http-client": {
|
"node_modules/@actions/http-client": {
|
||||||
"version": "2.0.1",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.1.1.tgz",
|
||||||
"integrity": "sha512-PIXiMVtz6VvyaRsGY268qvj57hXQEpsYogYOu2nrQhlf+XCGmZstmuZBbAybUl1nQGnvS1k1eEsQ69ZoD7xlSw==",
|
"integrity": "sha512-qhrkRMB40bbbLo7gF+0vu+X+UawOvQQqNAA/5Unx774RS8poaOhThDOG6BGmxvAnxhQnDp2BG/ZUm65xZILTpw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"tunnel": "^0.0.6"
|
"tunnel": "^0.0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@actions/io": {
|
"node_modules/@actions/io": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/@actions/io/-/io-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/@actions/io/-/io-1.1.3.tgz",
|
||||||
"integrity": "sha512-d+RwPlMp+2qmBfeLYPLXuSRykDIFEwdTA0MMxzS9kh4kvP1ftrc/9fzy6pX6qAjthdXruHQ6/6kjT/DNo5ALuw=="
|
"integrity": "sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q=="
|
||||||
},
|
},
|
||||||
"node_modules/@actions/tool-cache": {
|
"node_modules/@actions/tool-cache": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
@@ -84,17 +84,17 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/minimist": {
|
"node_modules/minimist": {
|
||||||
"version": "1.2.7",
|
"version": "1.2.8",
|
||||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz",
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
|
||||||
"integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==",
|
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/semver": {
|
"node_modules/semver": {
|
||||||
"version": "6.3.0",
|
"version": "6.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||||
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
||||||
"bin": {
|
"bin": {
|
||||||
"semver": "bin/semver.js"
|
"semver": "bin/semver.js"
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":";;;;;;;;;;;;AAIA,MAAa,sBAAsB;IAIjC,YAAY,QAAgB,EAAE,QAAgB;QAC5C,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;QACxB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;IAC1B,CAAC;IAED,cAAc,CAAC,OAA4B;QACzC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE;YACpB,MAAM,KAAK,CAAC,4BAA4B,CAAC,CAAA;SAC1C;QACD,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,GAAG,SAAS,MAAM,CAAC,IAAI,CACrD,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,EAAE,CACpC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAA;IACxB,CAAC;IAED,iCAAiC;IACjC,uBAAuB;QACrB,OAAO,KAAK,CAAA;IACd,CAAC;IAEK,oBAAoB;;YACxB,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAA;QACpC,CAAC;KAAA;CACF;AA1BD,wDA0BC;AAED,MAAa,uBAAuB;IAGlC,YAAY,KAAa;QACvB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;IACpB,CAAC;IAED,yCAAyC;IACzC,sDAAsD;IACtD,cAAc,CAAC,OAA4B;QACzC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE;YACpB,MAAM,KAAK,CAAC,4BAA4B,CAAC,CAAA;SAC1C;QACD,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,IAAI,CAAC,KAAK,EAAE,CAAA;IAC3D,CAAC;IAED,iCAAiC;IACjC,uBAAuB;QACrB,OAAO,KAAK,CAAA;IACd,CAAC;IAEK,oBAAoB;;YACxB,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAA;QACpC,CAAC;KAAA;CACF;AAxBD,0DAwBC;AAED,MAAa,oCAAoC;IAI/C,YAAY,KAAa;QACvB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;IACpB,CAAC;IAED,yCAAyC;IACzC,sDAAsD;IACtD,cAAc,CAAC,OAA4B;QACzC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE;YACpB,MAAM,KAAK,CAAC,4BAA4B,CAAC,CAAA;SAC1C;QACD,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,GAAG,SAAS,MAAM,CAAC,IAAI,CACrD,OAAO,IAAI,CAAC,KAAK,EAAE,CACpB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAA;IACxB,CAAC;IAED,iCAAiC;IACjC,uBAAuB;QACrB,OAAO,KAAK,CAAA;IACd,CAAC;IAEK,oBAAoB;;YACxB,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAA;QACpC,CAAC;KAAA;CACF;AA3BD,oFA2BC"}
|
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":";;;;;;;;;;;;AAIA,MAAa,sBAAsB;IAIjC,YAAY,QAAgB,EAAE,QAAgB;QAC5C,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;QACxB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;IAC1B,CAAC;IAED,cAAc,CAAC,OAA4B;QACzC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE;YACpB,MAAM,KAAK,CAAC,4BAA4B,CAAC,CAAA;SAC1C;QACD,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,GAAG,SAAS,MAAM,CAAC,IAAI,CACrD,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,EAAE,CACpC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAA;IACxB,CAAC;IAED,iCAAiC;IACjC,uBAAuB;QACrB,OAAO,KAAK,CAAA;IACd,CAAC;IAEK,oBAAoB;;YACxB,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAA;QACpC,CAAC;KAAA;CACF;AA1BD,wDA0BC;AAED,MAAa,uBAAuB;IAGlC,YAAY,KAAa;QACvB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;IACpB,CAAC;IAED,yCAAyC;IACzC,sDAAsD;IACtD,cAAc,CAAC,OAA4B;QACzC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE;YACpB,MAAM,KAAK,CAAC,4BAA4B,CAAC,CAAA;SAC1C;QACD,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,IAAI,CAAC,KAAK,EAAE,CAAA;IAC3D,CAAC;IAED,iCAAiC;IACjC,uBAAuB;QACrB,OAAO,KAAK,CAAA;IACd,CAAC;IAEK,oBAAoB;;YACxB,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAA;QACpC,CAAC;KAAA;CACF;AAxBD,0DAwBC;AAED,MAAa,oCAAoC;IAK/C,YAAY,KAAa;QACvB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;IACpB,CAAC;IAED,yCAAyC;IACzC,sDAAsD;IACtD,cAAc,CAAC,OAA4B;QACzC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE;YACpB,MAAM,KAAK,CAAC,4BAA4B,CAAC,CAAA;SAC1C;QACD,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,GAAG,SAAS,MAAM,CAAC,IAAI,CACrD,OAAO,IAAI,CAAC,KAAK,EAAE,CACpB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAA;IACxB,CAAC;IAED,iCAAiC;IACjC,uBAAuB;QACrB,OAAO,KAAK,CAAA;IACd,CAAC;IAEK,oBAAoB;;YACxB,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAA;QACpC,CAAC;KAAA;CACF;AA5BD,oFA4BC"}
|
||||||
+1
@@ -51,6 +51,7 @@ export declare class HttpClientResponse {
|
|||||||
constructor(message: http.IncomingMessage);
|
constructor(message: http.IncomingMessage);
|
||||||
message: http.IncomingMessage;
|
message: http.IncomingMessage;
|
||||||
readBody(): Promise<string>;
|
readBody(): Promise<string>;
|
||||||
|
readBodyBuffer?(): Promise<Buffer>;
|
||||||
}
|
}
|
||||||
export declare function isHttps(requestUrl: string): boolean;
|
export declare function isHttps(requestUrl: string): boolean;
|
||||||
export declare class HttpClient {
|
export declare class HttpClient {
|
||||||
|
|||||||
+13
@@ -123,6 +123,19 @@ class HttpClientResponse {
|
|||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
readBodyBuffer() {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () {
|
||||||
|
const chunks = [];
|
||||||
|
this.message.on('data', (chunk) => {
|
||||||
|
chunks.push(chunk);
|
||||||
|
});
|
||||||
|
this.message.on('end', () => {
|
||||||
|
resolve(Buffer.concat(chunks));
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
exports.HttpClientResponse = HttpClientResponse;
|
exports.HttpClientResponse = HttpClientResponse;
|
||||||
function isHttps(requestUrl) {
|
function isHttps(requestUrl) {
|
||||||
|
|||||||
+1
-1
File diff suppressed because one or more lines are too long
+23
-2
@@ -15,7 +15,13 @@ function getProxyUrl(reqUrl) {
|
|||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
if (proxyVar) {
|
if (proxyVar) {
|
||||||
return new URL(proxyVar);
|
try {
|
||||||
|
return new URL(proxyVar);
|
||||||
|
}
|
||||||
|
catch (_a) {
|
||||||
|
if (!proxyVar.startsWith('http://') && !proxyVar.startsWith('https://'))
|
||||||
|
return new URL(`http://${proxyVar}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return undefined;
|
return undefined;
|
||||||
@@ -26,6 +32,10 @@ function checkBypass(reqUrl) {
|
|||||||
if (!reqUrl.hostname) {
|
if (!reqUrl.hostname) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
const reqHost = reqUrl.hostname;
|
||||||
|
if (isLoopbackAddress(reqHost)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
const noProxy = process.env['no_proxy'] || process.env['NO_PROXY'] || '';
|
const noProxy = process.env['no_proxy'] || process.env['NO_PROXY'] || '';
|
||||||
if (!noProxy) {
|
if (!noProxy) {
|
||||||
return false;
|
return false;
|
||||||
@@ -51,11 +61,22 @@ function checkBypass(reqUrl) {
|
|||||||
.split(',')
|
.split(',')
|
||||||
.map(x => x.trim().toUpperCase())
|
.map(x => x.trim().toUpperCase())
|
||||||
.filter(x => x)) {
|
.filter(x => x)) {
|
||||||
if (upperReqHosts.some(x => x === upperNoProxyItem)) {
|
if (upperNoProxyItem === '*' ||
|
||||||
|
upperReqHosts.some(x => x === upperNoProxyItem ||
|
||||||
|
x.endsWith(`.${upperNoProxyItem}`) ||
|
||||||
|
(upperNoProxyItem.startsWith('.') &&
|
||||||
|
x.endsWith(`${upperNoProxyItem}`)))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
exports.checkBypass = checkBypass;
|
exports.checkBypass = checkBypass;
|
||||||
|
function isLoopbackAddress(host) {
|
||||||
|
const hostLower = host.toLowerCase();
|
||||||
|
return (hostLower === 'localhost' ||
|
||||||
|
hostLower.startsWith('127.') ||
|
||||||
|
hostLower.startsWith('[::1]') ||
|
||||||
|
hostLower.startsWith('[0:0:0:0:0:0:0:1]'));
|
||||||
|
}
|
||||||
//# sourceMappingURL=proxy.js.map
|
//# sourceMappingURL=proxy.js.map
|
||||||
+1
-1
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"proxy.js","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":";;;AAAA,SAAgB,WAAW,CAAC,MAAW;IACrC,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,KAAK,QAAQ,CAAA;IAE7C,IAAI,WAAW,CAAC,MAAM,CAAC,EAAE;QACvB,OAAO,SAAS,CAAA;KACjB;IAED,MAAM,QAAQ,GAAG,CAAC,GAAG,EAAE;QACrB,IAAI,QAAQ,EAAE;YACZ,OAAO,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAA;SAChE;aAAM;YACL,OAAO,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;SAC9D;IACH,CAAC,CAAC,EAAE,CAAA;IAEJ,IAAI,QAAQ,EAAE;QACZ,OAAO,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAA;KACzB;SAAM;QACL,OAAO,SAAS,CAAA;KACjB;AACH,CAAC;AApBD,kCAoBC;AAED,SAAgB,WAAW,CAAC,MAAW;IACrC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE;QACpB,OAAO,KAAK,CAAA;KACb;IAED,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,CAAA;IACxE,IAAI,CAAC,OAAO,EAAE;QACZ,OAAO,KAAK,CAAA;KACb;IAED,6BAA6B;IAC7B,IAAI,OAA2B,CAAA;IAC/B,IAAI,MAAM,CAAC,IAAI,EAAE;QACf,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;KAC9B;SAAM,IAAI,MAAM,CAAC,QAAQ,KAAK,OAAO,EAAE;QACtC,OAAO,GAAG,EAAE,CAAA;KACb;SAAM,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE;QACvC,OAAO,GAAG,GAAG,CAAA;KACd;IAED,qDAAqD;IACrD,MAAM,aAAa,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAA;IACrD,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE;QAC/B,aAAa,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,IAAI,OAAO,EAAE,CAAC,CAAA;KACrD;IAED,uCAAuC;IACvC,KAAK,MAAM,gBAAgB,IAAI,OAAO;SACnC,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;SAChC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;QACjB,IAAI,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,gBAAgB,CAAC,EAAE;YACnD,OAAO,IAAI,CAAA;SACZ;KACF;IAED,OAAO,KAAK,CAAA;AACd,CAAC;AArCD,kCAqCC"}
|
{"version":3,"file":"proxy.js","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"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"}
|
||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@actions/http-client",
|
"name": "@actions/http-client",
|
||||||
"version": "2.0.1",
|
"version": "2.1.1",
|
||||||
"description": "Actions Http Client",
|
"description": "Actions Http Client",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"github",
|
"github",
|
||||||
@@ -45,4 +45,4 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"tunnel": "^0.0.6"
|
"tunnel": "^0.0.6"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+3
-1
@@ -1,7 +1,9 @@
|
|||||||
/// <reference types="node" />
|
/// <reference types="node" />
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
export declare const chmod: typeof fs.promises.chmod, copyFile: typeof fs.promises.copyFile, lstat: typeof fs.promises.lstat, mkdir: typeof fs.promises.mkdir, readdir: typeof fs.promises.readdir, readlink: typeof fs.promises.readlink, rename: typeof fs.promises.rename, rmdir: typeof fs.promises.rmdir, stat: typeof fs.promises.stat, symlink: typeof fs.promises.symlink, unlink: typeof fs.promises.unlink;
|
export declare const chmod: typeof fs.promises.chmod, copyFile: typeof fs.promises.copyFile, lstat: typeof fs.promises.lstat, mkdir: typeof fs.promises.mkdir, open: typeof fs.promises.open, readdir: typeof fs.promises.readdir, readlink: typeof fs.promises.readlink, rename: typeof fs.promises.rename, rm: typeof fs.promises.rm, rmdir: typeof fs.promises.rmdir, stat: typeof fs.promises.stat, symlink: typeof fs.promises.symlink, unlink: typeof fs.promises.unlink;
|
||||||
export declare const IS_WINDOWS: boolean;
|
export declare const IS_WINDOWS: boolean;
|
||||||
|
export declare const UV_FS_O_EXLOCK = 268435456;
|
||||||
|
export declare const READONLY: number;
|
||||||
export declare function exists(fsPath: string): Promise<boolean>;
|
export declare function exists(fsPath: string): Promise<boolean>;
|
||||||
export declare function isDirectory(fsPath: string, useStat?: boolean): Promise<boolean>;
|
export declare function isDirectory(fsPath: string, useStat?: boolean): Promise<boolean>;
|
||||||
/**
|
/**
|
||||||
|
|||||||
+8
-2
@@ -29,11 +29,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|||||||
};
|
};
|
||||||
var _a;
|
var _a;
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.getCmdPath = exports.tryGetExecutablePath = exports.isRooted = exports.isDirectory = exports.exists = exports.IS_WINDOWS = exports.unlink = exports.symlink = exports.stat = exports.rmdir = exports.rename = exports.readlink = exports.readdir = exports.mkdir = exports.lstat = exports.copyFile = exports.chmod = void 0;
|
exports.getCmdPath = exports.tryGetExecutablePath = exports.isRooted = exports.isDirectory = exports.exists = exports.READONLY = exports.UV_FS_O_EXLOCK = exports.IS_WINDOWS = exports.unlink = exports.symlink = exports.stat = exports.rmdir = exports.rm = exports.rename = exports.readlink = exports.readdir = exports.open = exports.mkdir = exports.lstat = exports.copyFile = exports.chmod = void 0;
|
||||||
const fs = __importStar(require("fs"));
|
const fs = __importStar(require("fs"));
|
||||||
const path = __importStar(require("path"));
|
const path = __importStar(require("path"));
|
||||||
_a = fs.promises, exports.chmod = _a.chmod, exports.copyFile = _a.copyFile, exports.lstat = _a.lstat, exports.mkdir = _a.mkdir, exports.readdir = _a.readdir, exports.readlink = _a.readlink, exports.rename = _a.rename, exports.rmdir = _a.rmdir, exports.stat = _a.stat, exports.symlink = _a.symlink, exports.unlink = _a.unlink;
|
_a = fs.promises
|
||||||
|
// export const {open} = 'fs'
|
||||||
|
, exports.chmod = _a.chmod, exports.copyFile = _a.copyFile, exports.lstat = _a.lstat, exports.mkdir = _a.mkdir, exports.open = _a.open, exports.readdir = _a.readdir, exports.readlink = _a.readlink, exports.rename = _a.rename, exports.rm = _a.rm, exports.rmdir = _a.rmdir, exports.stat = _a.stat, exports.symlink = _a.symlink, exports.unlink = _a.unlink;
|
||||||
|
// export const {open} = 'fs'
|
||||||
exports.IS_WINDOWS = process.platform === 'win32';
|
exports.IS_WINDOWS = process.platform === 'win32';
|
||||||
|
// See https://github.com/nodejs/node/blob/d0153aee367422d0858105abec186da4dff0a0c5/deps/uv/include/uv/win.h#L691
|
||||||
|
exports.UV_FS_O_EXLOCK = 0x10000000;
|
||||||
|
exports.READONLY = fs.constants.O_RDONLY;
|
||||||
function exists(fsPath) {
|
function exists(fsPath) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
try {
|
try {
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"io-util.js","sourceRoot":"","sources":["../src/io-util.ts"],"names":[],"mappings":"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"}
|
{"version":3,"file":"io-util.js","sourceRoot":"","sources":["../src/io-util.ts"],"names":[],"mappings":"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"}
|
||||||
+11
-53
@@ -30,12 +30,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.findInPath = exports.which = exports.mkdirP = exports.rmRF = exports.mv = exports.cp = void 0;
|
exports.findInPath = exports.which = exports.mkdirP = exports.rmRF = exports.mv = exports.cp = void 0;
|
||||||
const assert_1 = require("assert");
|
const assert_1 = require("assert");
|
||||||
const childProcess = __importStar(require("child_process"));
|
|
||||||
const path = __importStar(require("path"));
|
const path = __importStar(require("path"));
|
||||||
const util_1 = require("util");
|
|
||||||
const ioUtil = __importStar(require("./io-util"));
|
const ioUtil = __importStar(require("./io-util"));
|
||||||
const exec = util_1.promisify(childProcess.exec);
|
|
||||||
const execFile = util_1.promisify(childProcess.execFile);
|
|
||||||
/**
|
/**
|
||||||
* Copies a file or folder.
|
* Copies a file or folder.
|
||||||
* Based off of shelljs - https://github.com/shelljs/shelljs/blob/9237f66c52e5daa40458f94f9565e18e8132f5a6/src/cp.js
|
* Based off of shelljs - https://github.com/shelljs/shelljs/blob/9237f66c52e5daa40458f94f9565e18e8132f5a6/src/cp.js
|
||||||
@@ -116,61 +112,23 @@ exports.mv = mv;
|
|||||||
function rmRF(inputPath) {
|
function rmRF(inputPath) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
if (ioUtil.IS_WINDOWS) {
|
if (ioUtil.IS_WINDOWS) {
|
||||||
// Node doesn't provide a delete operation, only an unlink function. This means that if the file is being used by another
|
|
||||||
// program (e.g. antivirus), it won't be deleted. To address this, we shell out the work to rd/del.
|
|
||||||
// Check for invalid characters
|
// Check for invalid characters
|
||||||
// https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file
|
// https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file
|
||||||
if (/[*"<>|]/.test(inputPath)) {
|
if (/[*"<>|]/.test(inputPath)) {
|
||||||
throw new Error('File path must not contain `*`, `"`, `<`, `>` or `|` on Windows');
|
throw new Error('File path must not contain `*`, `"`, `<`, `>` or `|` on Windows');
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
const cmdPath = ioUtil.getCmdPath();
|
|
||||||
if (yield ioUtil.isDirectory(inputPath, true)) {
|
|
||||||
yield exec(`${cmdPath} /s /c "rd /s /q "%inputPath%""`, {
|
|
||||||
env: { inputPath }
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
yield exec(`${cmdPath} /s /c "del /f /a "%inputPath%""`, {
|
|
||||||
env: { inputPath }
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
// if you try to delete a file that doesn't exist, desired result is achieved
|
|
||||||
// other errors are valid
|
|
||||||
if (err.code !== 'ENOENT')
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
// Shelling out fails to remove a symlink folder with missing source, this unlink catches that
|
|
||||||
try {
|
|
||||||
yield ioUtil.unlink(inputPath);
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
// if you try to delete a file that doesn't exist, desired result is achieved
|
|
||||||
// other errors are valid
|
|
||||||
if (err.code !== 'ENOENT')
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
try {
|
||||||
let isDir = false;
|
// note if path does not exist, error is silent
|
||||||
try {
|
yield ioUtil.rm(inputPath, {
|
||||||
isDir = yield ioUtil.isDirectory(inputPath);
|
force: true,
|
||||||
}
|
maxRetries: 3,
|
||||||
catch (err) {
|
recursive: true,
|
||||||
// if you try to delete a file that doesn't exist, desired result is achieved
|
retryDelay: 300
|
||||||
// other errors are valid
|
});
|
||||||
if (err.code !== 'ENOENT')
|
}
|
||||||
throw err;
|
catch (err) {
|
||||||
return;
|
throw new Error(`File was unable to be removed ${err}`);
|
||||||
}
|
|
||||||
if (isDir) {
|
|
||||||
yield execFile(`rm`, [`-rf`, `${inputPath}`]);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
yield ioUtil.unlink(inputPath);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@actions/io",
|
"name": "@actions/io",
|
||||||
"version": "1.1.2",
|
"version": "1.1.3",
|
||||||
"description": "Actions io lib",
|
"description": "Actions io lib",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"github",
|
"github",
|
||||||
|
|||||||
+25
-50
@@ -1,54 +1,29 @@
|
|||||||
{
|
{
|
||||||
"root": true,
|
"root": true,
|
||||||
|
|
||||||
"extends": "@ljharb/eslint-config/node/0.4",
|
"extends": "@ljharb/eslint-config/node/0.4",
|
||||||
|
|
||||||
"rules": {
|
"rules": {
|
||||||
"array-bracket-spacing": 0,
|
"array-element-newline": 0,
|
||||||
"array-element-newline": 0,
|
"complexity": 0,
|
||||||
"brace-style": 1,
|
"func-style": [2, "declaration"],
|
||||||
"camelcase": 1,
|
"max-lines-per-function": 0,
|
||||||
"comma-dangle": 1,
|
"max-nested-callbacks": 1,
|
||||||
"comma-spacing": 1,
|
"max-statements-per-line": 1,
|
||||||
"complexity": 0,
|
"max-statements": 0,
|
||||||
"curly": 1,
|
"multiline-comment-style": 0,
|
||||||
"dot-notation": 1,
|
"no-continue": 1,
|
||||||
"eol-last": 1,
|
"no-param-reassign": 1,
|
||||||
"func-style": 1,
|
"no-restricted-syntax": 1,
|
||||||
"function-paren-newline": 1,
|
"object-curly-newline": 0,
|
||||||
"indent": [1, 4],
|
},
|
||||||
"key-spacing": 1,
|
|
||||||
"max-lines-per-function": 0,
|
"overrides": [
|
||||||
"max-nested-callbacks": 1,
|
{
|
||||||
"max-statements": 0,
|
"files": "test/**",
|
||||||
"multiline-comment-style": 1,
|
"rules": {
|
||||||
"no-array-constructor": 1,
|
"camelcase": 0,
|
||||||
"no-continue": 1,
|
},
|
||||||
"no-div-regex": 1,
|
},
|
||||||
"no-extra-parens": 1,
|
]
|
||||||
"no-mixed-operators": 1,
|
|
||||||
"no-multi-spaces": 1,
|
|
||||||
"no-multiple-empty-lines": 1,
|
|
||||||
"no-param-reassign": 1,
|
|
||||||
"no-plusplus": 1,
|
|
||||||
"no-proto": 1,
|
|
||||||
"no-redeclare": 1,
|
|
||||||
"no-restricted-syntax": 1,
|
|
||||||
"no-shadow": 1,
|
|
||||||
"no-trailing-spaces": 1,
|
|
||||||
"no-unused-vars": 1,
|
|
||||||
"no-use-before-define": 1,
|
|
||||||
"object-curly-newline": 1,
|
|
||||||
"object-curly-spacing": 1,
|
|
||||||
"operator-linebreak": 1,
|
|
||||||
"quote-props": 1,
|
|
||||||
"quotes": 1,
|
|
||||||
"semi-style": 1,
|
|
||||||
"semi": 1,
|
|
||||||
"space-before-blocks": 1,
|
|
||||||
"space-before-function-paren": 1,
|
|
||||||
"space-infix-ops": 1,
|
|
||||||
"strict": 1,
|
|
||||||
"wrap-regex": 1,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|||||||
+87
-1
@@ -5,6 +5,52 @@ All notable changes to this project will be documented in this file.
|
|||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [v1.2.8](https://github.com/minimistjs/minimist/compare/v1.2.7...v1.2.8) - 2023-02-09
|
||||||
|
|
||||||
|
### Merged
|
||||||
|
|
||||||
|
- [Fix] Fix long option followed by single dash [`#17`](https://github.com/minimistjs/minimist/pull/17)
|
||||||
|
- [Tests] Remove duplicate test [`#12`](https://github.com/minimistjs/minimist/pull/12)
|
||||||
|
- [Fix] opt.string works with multiple aliases [`#10`](https://github.com/minimistjs/minimist/pull/10)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- [Fix] Fix long option followed by single dash (#17) [`#15`](https://github.com/minimistjs/minimist/issues/15)
|
||||||
|
- [Tests] Remove duplicate test (#12) [`#8`](https://github.com/minimistjs/minimist/issues/8)
|
||||||
|
- [Fix] Fix long option followed by single dash [`#15`](https://github.com/minimistjs/minimist/issues/15)
|
||||||
|
- [Fix] opt.string works with multiple aliases (#10) [`#9`](https://github.com/minimistjs/minimist/issues/9)
|
||||||
|
- [Fix] Fix handling of short option with non-trivial equals [`#5`](https://github.com/minimistjs/minimist/issues/5)
|
||||||
|
- [Tests] Remove duplicate test [`#8`](https://github.com/minimistjs/minimist/issues/8)
|
||||||
|
- [Fix] opt.string works with multiple aliases [`#9`](https://github.com/minimistjs/minimist/issues/9)
|
||||||
|
|
||||||
|
### Commits
|
||||||
|
|
||||||
|
- Merge tag 'v0.2.3' [`a026794`](https://github.com/minimistjs/minimist/commit/a0267947c7870fc5847cf2d437fbe33f392767da)
|
||||||
|
- [eslint] fix indentation and whitespace [`5368ca4`](https://github.com/minimistjs/minimist/commit/5368ca4147e974138a54cc0dc4cea8f756546b70)
|
||||||
|
- [eslint] fix indentation and whitespace [`e5f5067`](https://github.com/minimistjs/minimist/commit/e5f5067259ceeaf0b098d14bec910f87e58708c7)
|
||||||
|
- [eslint] more cleanup [`62fde7d`](https://github.com/minimistjs/minimist/commit/62fde7d935f83417fb046741531a9e2346a36976)
|
||||||
|
- [eslint] more cleanup [`36ac5d0`](https://github.com/minimistjs/minimist/commit/36ac5d0d95e4947d074e5737d94814034ca335d1)
|
||||||
|
- [meta] add `auto-changelog` [`73923d2`](https://github.com/minimistjs/minimist/commit/73923d223553fca08b1ba77e3fbc2a492862ae4c)
|
||||||
|
- [actions] add reusable workflows [`d80727d`](https://github.com/minimistjs/minimist/commit/d80727df77bfa9e631044d7f16368d8f09242c91)
|
||||||
|
- [eslint] add eslint; rules to enable later are warnings [`48bc06a`](https://github.com/minimistjs/minimist/commit/48bc06a1b41f00e9cdf183db34f7a51ba70e98d4)
|
||||||
|
- [eslint] fix indentation [`34b0f1c`](https://github.com/minimistjs/minimist/commit/34b0f1ccaa45183c3c4f06a91f9b405180a6f982)
|
||||||
|
- [readme] rename and add badges [`5df0fe4`](https://github.com/minimistjs/minimist/commit/5df0fe49211bd09a3636f8686a7cb3012c3e98f0)
|
||||||
|
- [Dev Deps] switch from `covert` to `nyc` [`a48b128`](https://github.com/minimistjs/minimist/commit/a48b128fdb8d427dfb20a15273f83e38d97bef07)
|
||||||
|
- [Dev Deps] update `covert`, `tape`; remove unnecessary `tap` [`f0fb958`](https://github.com/minimistjs/minimist/commit/f0fb958e9a1fe980cdffc436a211b0bda58f621b)
|
||||||
|
- [meta] create FUNDING.yml; add `funding` in package.json [`3639e0c`](https://github.com/minimistjs/minimist/commit/3639e0c819359a366387e425ab6eabf4c78d3caa)
|
||||||
|
- [meta] use `npmignore` to autogenerate an npmignore file [`be2e038`](https://github.com/minimistjs/minimist/commit/be2e038c342d8333b32f0fde67a0026b79c8150e)
|
||||||
|
- Only apps should have lockfiles [`282b570`](https://github.com/minimistjs/minimist/commit/282b570e7489d01b03f2d6d3dabf79cd3e5f84cf)
|
||||||
|
- isConstructorOrProto adapted from PR [`ef9153f`](https://github.com/minimistjs/minimist/commit/ef9153fc52b6cea0744b2239921c5dcae4697f11)
|
||||||
|
- [Dev Deps] update `@ljharb/eslint-config`, `aud` [`098873c`](https://github.com/minimistjs/minimist/commit/098873c213cdb7c92e55ae1ef5aa1af3a8192a79)
|
||||||
|
- [Dev Deps] update `@ljharb/eslint-config`, `aud` [`3124ed3`](https://github.com/minimistjs/minimist/commit/3124ed3e46306301ebb3c834874ce0241555c2c4)
|
||||||
|
- [meta] add `safe-publish-latest` [`4b927de`](https://github.com/minimistjs/minimist/commit/4b927de696d561c636b4f43bf49d4597cb36d6d6)
|
||||||
|
- [Tests] add `aud` in `posttest` [`b32d9bd`](https://github.com/minimistjs/minimist/commit/b32d9bd0ab340f4e9f8c3a97ff2a4424f25fab8c)
|
||||||
|
- [meta] update repo URLs [`f9fdfc0`](https://github.com/minimistjs/minimist/commit/f9fdfc032c54884d9a9996a390c63cd0719bbe1a)
|
||||||
|
- [actions] Avoid 0.6 tests due to build failures [`ba92fe6`](https://github.com/minimistjs/minimist/commit/ba92fe6ebbdc0431cca9a2ea8f27beb492f5e4ec)
|
||||||
|
- [Dev Deps] update `tape` [`950eaa7`](https://github.com/minimistjs/minimist/commit/950eaa74f112e04d23e9c606c67472c46739b473)
|
||||||
|
- [Dev Deps] add missing `npmignore` dev dep [`3226afa`](https://github.com/minimistjs/minimist/commit/3226afaf09e9d127ca369742437fe6e88f752d6b)
|
||||||
|
- Merge tag 'v0.2.2' [`980d7ac`](https://github.com/minimistjs/minimist/commit/980d7ac61a0b4bd552711251ac107d506b23e41f)
|
||||||
|
|
||||||
## [v1.2.7](https://github.com/minimistjs/minimist/compare/v1.2.6...v1.2.7) - 2022-10-10
|
## [v1.2.7](https://github.com/minimistjs/minimist/compare/v1.2.6...v1.2.7) - 2022-10-10
|
||||||
|
|
||||||
### Commits
|
### Commits
|
||||||
@@ -109,13 +155,53 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- coverage script [`e5531ba`](https://github.com/minimistjs/minimist/commit/e5531ba0479da3b8138d3d8cac545d84ccb1c8df)
|
- coverage script [`e5531ba`](https://github.com/minimistjs/minimist/commit/e5531ba0479da3b8138d3d8cac545d84ccb1c8df)
|
||||||
- extra fn to get 100% coverage again [`a6972da`](https://github.com/minimistjs/minimist/commit/a6972da89e56bf77642f8ec05a13b6558db93498)
|
- extra fn to get 100% coverage again [`a6972da`](https://github.com/minimistjs/minimist/commit/a6972da89e56bf77642f8ec05a13b6558db93498)
|
||||||
|
|
||||||
## [v1.0.0](https://github.com/minimistjs/minimist/compare/v0.2.1...v1.0.0) - 2014-08-10
|
## [v1.0.0](https://github.com/minimistjs/minimist/compare/v0.2.3...v1.0.0) - 2014-08-10
|
||||||
|
|
||||||
### Commits
|
### Commits
|
||||||
|
|
||||||
- added stopEarly option [`471c7e4`](https://github.com/minimistjs/minimist/commit/471c7e4a7e910fc7ad8f9df850a186daf32c64e9)
|
- added stopEarly option [`471c7e4`](https://github.com/minimistjs/minimist/commit/471c7e4a7e910fc7ad8f9df850a186daf32c64e9)
|
||||||
- fix list [`fef6ae7`](https://github.com/minimistjs/minimist/commit/fef6ae79c38b9dc1c49569abb7cd04eb965eac5e)
|
- fix list [`fef6ae7`](https://github.com/minimistjs/minimist/commit/fef6ae79c38b9dc1c49569abb7cd04eb965eac5e)
|
||||||
|
|
||||||
|
## [v0.2.3](https://github.com/minimistjs/minimist/compare/v0.2.2...v0.2.3) - 2023-02-09
|
||||||
|
|
||||||
|
### Merged
|
||||||
|
|
||||||
|
- [Fix] Fix long option followed by single dash [`#17`](https://github.com/minimistjs/minimist/pull/17)
|
||||||
|
- [Tests] Remove duplicate test [`#12`](https://github.com/minimistjs/minimist/pull/12)
|
||||||
|
- [Fix] opt.string works with multiple aliases [`#10`](https://github.com/minimistjs/minimist/pull/10)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- [Fix] Fix long option followed by single dash (#17) [`#15`](https://github.com/minimistjs/minimist/issues/15)
|
||||||
|
- [Tests] Remove duplicate test (#12) [`#8`](https://github.com/minimistjs/minimist/issues/8)
|
||||||
|
- [Fix] opt.string works with multiple aliases (#10) [`#9`](https://github.com/minimistjs/minimist/issues/9)
|
||||||
|
|
||||||
|
### Commits
|
||||||
|
|
||||||
|
- [eslint] fix indentation and whitespace [`e5f5067`](https://github.com/minimistjs/minimist/commit/e5f5067259ceeaf0b098d14bec910f87e58708c7)
|
||||||
|
- [eslint] more cleanup [`36ac5d0`](https://github.com/minimistjs/minimist/commit/36ac5d0d95e4947d074e5737d94814034ca335d1)
|
||||||
|
- [eslint] fix indentation [`34b0f1c`](https://github.com/minimistjs/minimist/commit/34b0f1ccaa45183c3c4f06a91f9b405180a6f982)
|
||||||
|
- isConstructorOrProto adapted from PR [`ef9153f`](https://github.com/minimistjs/minimist/commit/ef9153fc52b6cea0744b2239921c5dcae4697f11)
|
||||||
|
- [Dev Deps] update `@ljharb/eslint-config`, `aud` [`098873c`](https://github.com/minimistjs/minimist/commit/098873c213cdb7c92e55ae1ef5aa1af3a8192a79)
|
||||||
|
- [Dev Deps] add missing `npmignore` dev dep [`3226afa`](https://github.com/minimistjs/minimist/commit/3226afaf09e9d127ca369742437fe6e88f752d6b)
|
||||||
|
|
||||||
|
## [v0.2.2](https://github.com/minimistjs/minimist/compare/v0.2.1...v0.2.2) - 2022-10-10
|
||||||
|
|
||||||
|
### Commits
|
||||||
|
|
||||||
|
- [meta] add `auto-changelog` [`73923d2`](https://github.com/minimistjs/minimist/commit/73923d223553fca08b1ba77e3fbc2a492862ae4c)
|
||||||
|
- [actions] add reusable workflows [`d80727d`](https://github.com/minimistjs/minimist/commit/d80727df77bfa9e631044d7f16368d8f09242c91)
|
||||||
|
- [eslint] add eslint; rules to enable later are warnings [`48bc06a`](https://github.com/minimistjs/minimist/commit/48bc06a1b41f00e9cdf183db34f7a51ba70e98d4)
|
||||||
|
- [readme] rename and add badges [`5df0fe4`](https://github.com/minimistjs/minimist/commit/5df0fe49211bd09a3636f8686a7cb3012c3e98f0)
|
||||||
|
- [Dev Deps] switch from `covert` to `nyc` [`a48b128`](https://github.com/minimistjs/minimist/commit/a48b128fdb8d427dfb20a15273f83e38d97bef07)
|
||||||
|
- [Dev Deps] update `covert`, `tape`; remove unnecessary `tap` [`f0fb958`](https://github.com/minimistjs/minimist/commit/f0fb958e9a1fe980cdffc436a211b0bda58f621b)
|
||||||
|
- [meta] create FUNDING.yml; add `funding` in package.json [`3639e0c`](https://github.com/minimistjs/minimist/commit/3639e0c819359a366387e425ab6eabf4c78d3caa)
|
||||||
|
- [meta] use `npmignore` to autogenerate an npmignore file [`be2e038`](https://github.com/minimistjs/minimist/commit/be2e038c342d8333b32f0fde67a0026b79c8150e)
|
||||||
|
- Only apps should have lockfiles [`282b570`](https://github.com/minimistjs/minimist/commit/282b570e7489d01b03f2d6d3dabf79cd3e5f84cf)
|
||||||
|
- [meta] add `safe-publish-latest` [`4b927de`](https://github.com/minimistjs/minimist/commit/4b927de696d561c636b4f43bf49d4597cb36d6d6)
|
||||||
|
- [Tests] add `aud` in `posttest` [`b32d9bd`](https://github.com/minimistjs/minimist/commit/b32d9bd0ab340f4e9f8c3a97ff2a4424f25fab8c)
|
||||||
|
- [meta] update repo URLs [`f9fdfc0`](https://github.com/minimistjs/minimist/commit/f9fdfc032c54884d9a9996a390c63cd0719bbe1a)
|
||||||
|
|
||||||
## [v0.2.1](https://github.com/minimistjs/minimist/compare/v0.2.0...v0.2.1) - 2020-03-12
|
## [v0.2.1](https://github.com/minimistjs/minimist/compare/v0.2.0...v0.2.1) - 2020-03-12
|
||||||
|
|
||||||
## [v0.2.0](https://github.com/minimistjs/minimist/compare/v0.1.0...v0.2.0) - 2014-06-19
|
## [v0.2.0](https://github.com/minimistjs/minimist/compare/v0.1.0...v0.2.0) - 2014-06-19
|
||||||
|
|||||||
+14
-10
@@ -26,14 +26,16 @@ $ node example/parse.js -a beep -b boop
|
|||||||
|
|
||||||
```
|
```
|
||||||
$ node example/parse.js -x 3 -y 4 -n5 -abc --beep=boop foo bar baz
|
$ node example/parse.js -x 3 -y 4 -n5 -abc --beep=boop foo bar baz
|
||||||
{ _: [ 'foo', 'bar', 'baz' ],
|
{
|
||||||
x: 3,
|
_: ['foo', 'bar', 'baz'],
|
||||||
y: 4,
|
x: 3,
|
||||||
n: 5,
|
y: 4,
|
||||||
a: true,
|
n: 5,
|
||||||
b: true,
|
a: true,
|
||||||
c: true,
|
b: true,
|
||||||
beep: 'boop' }
|
c: true,
|
||||||
|
beep: 'boop'
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
# security
|
# security
|
||||||
@@ -81,8 +83,10 @@ and `argv['--']` with everything after the `--`. Here's an example:
|
|||||||
|
|
||||||
```
|
```
|
||||||
> require('./')('one two three -- four five --six'.split(' '), { '--': true })
|
> require('./')('one two three -- four five --six'.split(' '), { '--': true })
|
||||||
{ _: [ 'one', 'two', 'three' ],
|
{
|
||||||
'--': [ 'four', 'five', '--six' ] }
|
_: ['one', 'two', 'three'],
|
||||||
|
'--': ['four', 'five', '--six']
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Note that with `opts['--']` set, parsing for arguments still stops after the
|
Note that with `opts['--']` set, parsing for arguments still stops after the
|
||||||
|
|||||||
+2
@@ -1,2 +1,4 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
var argv = require('../')(process.argv.slice(2));
|
var argv = require('../')(process.argv.slice(2));
|
||||||
console.log(argv);
|
console.log(argv);
|
||||||
|
|||||||
+249
-235
@@ -1,249 +1,263 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
function hasKey(obj, keys) {
|
||||||
|
var o = obj;
|
||||||
|
keys.slice(0, -1).forEach(function (key) {
|
||||||
|
o = o[key] || {};
|
||||||
|
});
|
||||||
|
|
||||||
|
var key = keys[keys.length - 1];
|
||||||
|
return key in o;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isNumber(x) {
|
||||||
|
if (typeof x === 'number') { return true; }
|
||||||
|
if ((/^0x[0-9a-f]+$/i).test(x)) { return true; }
|
||||||
|
return (/^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/).test(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isConstructorOrProto(obj, key) {
|
||||||
|
return (key === 'constructor' && typeof obj[key] === 'function') || key === '__proto__';
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = function (args, opts) {
|
module.exports = function (args, opts) {
|
||||||
if (!opts) opts = {};
|
if (!opts) { opts = {}; }
|
||||||
|
|
||||||
var flags = { bools : {}, strings : {}, unknownFn: null };
|
|
||||||
|
|
||||||
if (typeof opts['unknown'] === 'function') {
|
var flags = {
|
||||||
flags.unknownFn = opts['unknown'];
|
bools: {},
|
||||||
}
|
strings: {},
|
||||||
|
unknownFn: null,
|
||||||
|
};
|
||||||
|
|
||||||
if (typeof opts['boolean'] === 'boolean' && opts['boolean']) {
|
if (typeof opts.unknown === 'function') {
|
||||||
flags.allBools = true;
|
flags.unknownFn = opts.unknown;
|
||||||
} else {
|
}
|
||||||
[].concat(opts['boolean']).filter(Boolean).forEach(function (key) {
|
|
||||||
flags.bools[key] = true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
var aliases = {};
|
|
||||||
Object.keys(opts.alias || {}).forEach(function (key) {
|
|
||||||
aliases[key] = [].concat(opts.alias[key]);
|
|
||||||
aliases[key].forEach(function (x) {
|
|
||||||
aliases[x] = [key].concat(aliases[key].filter(function (y) {
|
|
||||||
return x !== y;
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
[].concat(opts.string).filter(Boolean).forEach(function (key) {
|
if (typeof opts.boolean === 'boolean' && opts.boolean) {
|
||||||
flags.strings[key] = true;
|
flags.allBools = true;
|
||||||
if (aliases[key]) {
|
} else {
|
||||||
flags.strings[aliases[key]] = true;
|
[].concat(opts.boolean).filter(Boolean).forEach(function (key) {
|
||||||
}
|
flags.bools[key] = true;
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
var defaults = opts['default'] || {};
|
var aliases = {};
|
||||||
|
|
||||||
var argv = { _ : [] };
|
|
||||||
Object.keys(flags.bools).forEach(function (key) {
|
|
||||||
setArg(key, defaults[key] === undefined ? false : defaults[key]);
|
|
||||||
});
|
|
||||||
|
|
||||||
var notFlags = [];
|
|
||||||
|
|
||||||
if (args.indexOf('--') !== -1) {
|
function aliasIsBoolean(key) {
|
||||||
notFlags = args.slice(args.indexOf('--')+1);
|
return aliases[key].some(function (x) {
|
||||||
args = args.slice(0, args.indexOf('--'));
|
return flags.bools[x];
|
||||||
}
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function argDefined(key, arg) {
|
Object.keys(opts.alias || {}).forEach(function (key) {
|
||||||
return (flags.allBools && /^--[^=]+$/.test(arg)) ||
|
aliases[key] = [].concat(opts.alias[key]);
|
||||||
flags.strings[key] || flags.bools[key] || aliases[key];
|
aliases[key].forEach(function (x) {
|
||||||
}
|
aliases[x] = [key].concat(aliases[key].filter(function (y) {
|
||||||
|
return x !== y;
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
function setArg (key, val, arg) {
|
[].concat(opts.string).filter(Boolean).forEach(function (key) {
|
||||||
if (arg && flags.unknownFn && !argDefined(key, arg)) {
|
flags.strings[key] = true;
|
||||||
if (flags.unknownFn(arg) === false) return;
|
if (aliases[key]) {
|
||||||
}
|
[].concat(aliases[key]).forEach(function (k) {
|
||||||
|
flags.strings[k] = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
var value = !flags.strings[key] && isNumber(val)
|
var defaults = opts.default || {};
|
||||||
? Number(val) : val
|
|
||||||
;
|
|
||||||
setKey(argv, key.split('.'), value);
|
|
||||||
|
|
||||||
(aliases[key] || []).forEach(function (x) {
|
|
||||||
setKey(argv, x.split('.'), value);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function setKey (obj, keys, value) {
|
var argv = { _: [] };
|
||||||
var o = obj;
|
|
||||||
for (var i = 0; i < keys.length-1; i++) {
|
|
||||||
var key = keys[i];
|
|
||||||
if (isConstructorOrProto(o, key)) return;
|
|
||||||
if (o[key] === undefined) o[key] = {};
|
|
||||||
if (o[key] === Object.prototype || o[key] === Number.prototype
|
|
||||||
|| o[key] === String.prototype) o[key] = {};
|
|
||||||
if (o[key] === Array.prototype) o[key] = [];
|
|
||||||
o = o[key];
|
|
||||||
}
|
|
||||||
|
|
||||||
var key = keys[keys.length - 1];
|
function argDefined(key, arg) {
|
||||||
if (isConstructorOrProto(o, key)) return;
|
return (flags.allBools && (/^--[^=]+$/).test(arg))
|
||||||
if (o === Object.prototype || o === Number.prototype
|
|| flags.strings[key]
|
||||||
|| o === String.prototype) o = {};
|
|| flags.bools[key]
|
||||||
if (o === Array.prototype) o = [];
|
|| aliases[key];
|
||||||
if (o[key] === undefined || flags.bools[key] || typeof o[key] === 'boolean') {
|
}
|
||||||
o[key] = value;
|
|
||||||
}
|
|
||||||
else if (Array.isArray(o[key])) {
|
|
||||||
o[key].push(value);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
o[key] = [ o[key], value ];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function aliasIsBoolean(key) {
|
|
||||||
return aliases[key].some(function (x) {
|
|
||||||
return flags.bools[x];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = 0; i < args.length; i++) {
|
function setKey(obj, keys, value) {
|
||||||
var arg = args[i];
|
var o = obj;
|
||||||
|
for (var i = 0; i < keys.length - 1; i++) {
|
||||||
if (/^--.+=/.test(arg)) {
|
var key = keys[i];
|
||||||
// Using [\s\S] instead of . because js doesn't support the
|
if (isConstructorOrProto(o, key)) { return; }
|
||||||
// 'dotall' regex modifier. See:
|
if (o[key] === undefined) { o[key] = {}; }
|
||||||
// http://stackoverflow.com/a/1068308/13216
|
if (
|
||||||
var m = arg.match(/^--([^=]+)=([\s\S]*)$/);
|
o[key] === Object.prototype
|
||||||
var key = m[1];
|
|| o[key] === Number.prototype
|
||||||
var value = m[2];
|
|| o[key] === String.prototype
|
||||||
if (flags.bools[key]) {
|
) {
|
||||||
value = value !== 'false';
|
o[key] = {};
|
||||||
}
|
}
|
||||||
setArg(key, value, arg);
|
if (o[key] === Array.prototype) { o[key] = []; }
|
||||||
}
|
o = o[key];
|
||||||
else if (/^--no-.+/.test(arg)) {
|
}
|
||||||
var key = arg.match(/^--no-(.+)/)[1];
|
|
||||||
setArg(key, false, arg);
|
|
||||||
}
|
|
||||||
else if (/^--.+/.test(arg)) {
|
|
||||||
var key = arg.match(/^--(.+)/)[1];
|
|
||||||
var next = args[i + 1];
|
|
||||||
if (next !== undefined && !/^-/.test(next)
|
|
||||||
&& !flags.bools[key]
|
|
||||||
&& !flags.allBools
|
|
||||||
&& (aliases[key] ? !aliasIsBoolean(key) : true)) {
|
|
||||||
setArg(key, next, arg);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
else if (/^(true|false)$/.test(next)) {
|
|
||||||
setArg(key, next === 'true', arg);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
setArg(key, flags.strings[key] ? '' : true, arg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (/^-[^-]+/.test(arg)) {
|
|
||||||
var letters = arg.slice(1,-1).split('');
|
|
||||||
|
|
||||||
var broken = false;
|
|
||||||
for (var j = 0; j < letters.length; j++) {
|
|
||||||
var next = arg.slice(j+2);
|
|
||||||
|
|
||||||
if (next === '-') {
|
|
||||||
setArg(letters[j], next, arg)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (/[A-Za-z]/.test(letters[j]) && /=/.test(next)) {
|
|
||||||
setArg(letters[j], next.split('=')[1], arg);
|
|
||||||
broken = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (/[A-Za-z]/.test(letters[j])
|
|
||||||
&& /-?\d+(\.\d*)?(e-?\d+)?$/.test(next)) {
|
|
||||||
setArg(letters[j], next, arg);
|
|
||||||
broken = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (letters[j+1] && letters[j+1].match(/\W/)) {
|
|
||||||
setArg(letters[j], arg.slice(j+2), arg);
|
|
||||||
broken = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
setArg(letters[j], flags.strings[letters[j]] ? '' : true, arg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var key = arg.slice(-1)[0];
|
|
||||||
if (!broken && key !== '-') {
|
|
||||||
if (args[i+1] && !/^(-|--)[^-]/.test(args[i+1])
|
|
||||||
&& !flags.bools[key]
|
|
||||||
&& (aliases[key] ? !aliasIsBoolean(key) : true)) {
|
|
||||||
setArg(key, args[i+1], arg);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
else if (args[i+1] && /^(true|false)$/.test(args[i+1])) {
|
|
||||||
setArg(key, args[i+1] === 'true', arg);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
setArg(key, flags.strings[key] ? '' : true, arg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (!flags.unknownFn || flags.unknownFn(arg) !== false) {
|
|
||||||
argv._.push(
|
|
||||||
flags.strings['_'] || !isNumber(arg) ? arg : Number(arg)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (opts.stopEarly) {
|
|
||||||
argv._.push.apply(argv._, args.slice(i + 1));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Object.keys(defaults).forEach(function (key) {
|
|
||||||
if (!hasKey(argv, key.split('.'))) {
|
|
||||||
setKey(argv, key.split('.'), defaults[key]);
|
|
||||||
|
|
||||||
(aliases[key] || []).forEach(function (x) {
|
|
||||||
setKey(argv, x.split('.'), defaults[key]);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (opts['--']) {
|
|
||||||
argv['--'] = new Array();
|
|
||||||
notFlags.forEach(function(key) {
|
|
||||||
argv['--'].push(key);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
notFlags.forEach(function(key) {
|
|
||||||
argv._.push(key);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return argv;
|
var lastKey = keys[keys.length - 1];
|
||||||
|
if (isConstructorOrProto(o, lastKey)) { return; }
|
||||||
|
if (
|
||||||
|
o === Object.prototype
|
||||||
|
|| o === Number.prototype
|
||||||
|
|| o === String.prototype
|
||||||
|
) {
|
||||||
|
o = {};
|
||||||
|
}
|
||||||
|
if (o === Array.prototype) { o = []; }
|
||||||
|
if (o[lastKey] === undefined || flags.bools[lastKey] || typeof o[lastKey] === 'boolean') {
|
||||||
|
o[lastKey] = value;
|
||||||
|
} else if (Array.isArray(o[lastKey])) {
|
||||||
|
o[lastKey].push(value);
|
||||||
|
} else {
|
||||||
|
o[lastKey] = [o[lastKey], value];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setArg(key, val, arg) {
|
||||||
|
if (arg && flags.unknownFn && !argDefined(key, arg)) {
|
||||||
|
if (flags.unknownFn(arg) === false) { return; }
|
||||||
|
}
|
||||||
|
|
||||||
|
var value = !flags.strings[key] && isNumber(val)
|
||||||
|
? Number(val)
|
||||||
|
: val;
|
||||||
|
setKey(argv, key.split('.'), value);
|
||||||
|
|
||||||
|
(aliases[key] || []).forEach(function (x) {
|
||||||
|
setKey(argv, x.split('.'), value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.keys(flags.bools).forEach(function (key) {
|
||||||
|
setArg(key, defaults[key] === undefined ? false : defaults[key]);
|
||||||
|
});
|
||||||
|
|
||||||
|
var notFlags = [];
|
||||||
|
|
||||||
|
if (args.indexOf('--') !== -1) {
|
||||||
|
notFlags = args.slice(args.indexOf('--') + 1);
|
||||||
|
args = args.slice(0, args.indexOf('--'));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < args.length; i++) {
|
||||||
|
var arg = args[i];
|
||||||
|
var key;
|
||||||
|
var next;
|
||||||
|
|
||||||
|
if ((/^--.+=/).test(arg)) {
|
||||||
|
// Using [\s\S] instead of . because js doesn't support the
|
||||||
|
// 'dotall' regex modifier. See:
|
||||||
|
// http://stackoverflow.com/a/1068308/13216
|
||||||
|
var m = arg.match(/^--([^=]+)=([\s\S]*)$/);
|
||||||
|
key = m[1];
|
||||||
|
var value = m[2];
|
||||||
|
if (flags.bools[key]) {
|
||||||
|
value = value !== 'false';
|
||||||
|
}
|
||||||
|
setArg(key, value, arg);
|
||||||
|
} else if ((/^--no-.+/).test(arg)) {
|
||||||
|
key = arg.match(/^--no-(.+)/)[1];
|
||||||
|
setArg(key, false, arg);
|
||||||
|
} else if ((/^--.+/).test(arg)) {
|
||||||
|
key = arg.match(/^--(.+)/)[1];
|
||||||
|
next = args[i + 1];
|
||||||
|
if (
|
||||||
|
next !== undefined
|
||||||
|
&& !(/^(-|--)[^-]/).test(next)
|
||||||
|
&& !flags.bools[key]
|
||||||
|
&& !flags.allBools
|
||||||
|
&& (aliases[key] ? !aliasIsBoolean(key) : true)
|
||||||
|
) {
|
||||||
|
setArg(key, next, arg);
|
||||||
|
i += 1;
|
||||||
|
} else if ((/^(true|false)$/).test(next)) {
|
||||||
|
setArg(key, next === 'true', arg);
|
||||||
|
i += 1;
|
||||||
|
} else {
|
||||||
|
setArg(key, flags.strings[key] ? '' : true, arg);
|
||||||
|
}
|
||||||
|
} else if ((/^-[^-]+/).test(arg)) {
|
||||||
|
var letters = arg.slice(1, -1).split('');
|
||||||
|
|
||||||
|
var broken = false;
|
||||||
|
for (var j = 0; j < letters.length; j++) {
|
||||||
|
next = arg.slice(j + 2);
|
||||||
|
|
||||||
|
if (next === '-') {
|
||||||
|
setArg(letters[j], next, arg);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((/[A-Za-z]/).test(letters[j]) && next[0] === '=') {
|
||||||
|
setArg(letters[j], next.slice(1), arg);
|
||||||
|
broken = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
(/[A-Za-z]/).test(letters[j])
|
||||||
|
&& (/-?\d+(\.\d*)?(e-?\d+)?$/).test(next)
|
||||||
|
) {
|
||||||
|
setArg(letters[j], next, arg);
|
||||||
|
broken = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (letters[j + 1] && letters[j + 1].match(/\W/)) {
|
||||||
|
setArg(letters[j], arg.slice(j + 2), arg);
|
||||||
|
broken = true;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
setArg(letters[j], flags.strings[letters[j]] ? '' : true, arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
key = arg.slice(-1)[0];
|
||||||
|
if (!broken && key !== '-') {
|
||||||
|
if (
|
||||||
|
args[i + 1]
|
||||||
|
&& !(/^(-|--)[^-]/).test(args[i + 1])
|
||||||
|
&& !flags.bools[key]
|
||||||
|
&& (aliases[key] ? !aliasIsBoolean(key) : true)
|
||||||
|
) {
|
||||||
|
setArg(key, args[i + 1], arg);
|
||||||
|
i += 1;
|
||||||
|
} else if (args[i + 1] && (/^(true|false)$/).test(args[i + 1])) {
|
||||||
|
setArg(key, args[i + 1] === 'true', arg);
|
||||||
|
i += 1;
|
||||||
|
} else {
|
||||||
|
setArg(key, flags.strings[key] ? '' : true, arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!flags.unknownFn || flags.unknownFn(arg) !== false) {
|
||||||
|
argv._.push(flags.strings._ || !isNumber(arg) ? arg : Number(arg));
|
||||||
|
}
|
||||||
|
if (opts.stopEarly) {
|
||||||
|
argv._.push.apply(argv._, args.slice(i + 1));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.keys(defaults).forEach(function (k) {
|
||||||
|
if (!hasKey(argv, k.split('.'))) {
|
||||||
|
setKey(argv, k.split('.'), defaults[k]);
|
||||||
|
|
||||||
|
(aliases[k] || []).forEach(function (x) {
|
||||||
|
setKey(argv, x.split('.'), defaults[k]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (opts['--']) {
|
||||||
|
argv['--'] = notFlags.slice();
|
||||||
|
} else {
|
||||||
|
notFlags.forEach(function (k) {
|
||||||
|
argv._.push(k);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return argv;
|
||||||
};
|
};
|
||||||
|
|
||||||
function hasKey (obj, keys) {
|
|
||||||
var o = obj;
|
|
||||||
keys.slice(0,-1).forEach(function (key) {
|
|
||||||
o = (o[key] || {});
|
|
||||||
});
|
|
||||||
|
|
||||||
var key = keys[keys.length - 1];
|
|
||||||
return key in o;
|
|
||||||
}
|
|
||||||
|
|
||||||
function isNumber (x) {
|
|
||||||
if (typeof x === 'number') return true;
|
|
||||||
if (/^0x[0-9a-f]+$/i.test(x)) return true;
|
|
||||||
return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function isConstructorOrProto (obj, key) {
|
|
||||||
return key === 'constructor' && typeof obj[key] === 'function' || key === '__proto__';
|
|
||||||
}
|
|
||||||
|
|||||||
+73
-73
@@ -1,75 +1,75 @@
|
|||||||
{
|
{
|
||||||
"name": "minimist",
|
"name": "minimist",
|
||||||
"version": "1.2.7",
|
"version": "1.2.8",
|
||||||
"description": "parse argument options",
|
"description": "parse argument options",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@ljharb/eslint-config": "^21.0.0",
|
"@ljharb/eslint-config": "^21.0.1",
|
||||||
"aud": "^2.0.1",
|
"aud": "^2.0.2",
|
||||||
"auto-changelog": "^2.4.0",
|
"auto-changelog": "^2.4.0",
|
||||||
"eslint": "=8.8.0",
|
"eslint": "=8.8.0",
|
||||||
"in-publish": "^2.0.1",
|
"in-publish": "^2.0.1",
|
||||||
"npmignore": "^0.3.0",
|
"npmignore": "^0.3.0",
|
||||||
"nyc": "^10.3.2",
|
"nyc": "^10.3.2",
|
||||||
"safe-publish-latest": "^2.0.0",
|
"safe-publish-latest": "^2.0.0",
|
||||||
"tape": "^5.6.1"
|
"tape": "^5.6.3"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"prepack": "npmignore --auto --commentLines=auto",
|
"prepack": "npmignore --auto --commentLines=auto",
|
||||||
"prepublishOnly": "safe-publish-latest",
|
"prepublishOnly": "safe-publish-latest",
|
||||||
"prepublish": "not-in-publish || npm run prepublishOnly",
|
"prepublish": "not-in-publish || npm run prepublishOnly",
|
||||||
"lint": "eslint --ext=js,mjs .",
|
"lint": "eslint --ext=js,mjs .",
|
||||||
"pretest": "npm run lint",
|
"pretest": "npm run lint",
|
||||||
"tests-only": "nyc tape test/*.js",
|
"tests-only": "nyc tape 'test/**/*.js'",
|
||||||
"test": "npm run tests-only",
|
"test": "npm run tests-only",
|
||||||
"posttest": "aud --production",
|
"posttest": "aud --production",
|
||||||
"version": "auto-changelog && git add CHANGELOG.md",
|
"version": "auto-changelog && git add CHANGELOG.md",
|
||||||
"postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\""
|
"postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\""
|
||||||
},
|
},
|
||||||
"testling": {
|
"testling": {
|
||||||
"files": "test/*.js",
|
"files": "test/*.js",
|
||||||
"browsers": [
|
"browsers": [
|
||||||
"ie/6..latest",
|
"ie/6..latest",
|
||||||
"ff/5",
|
"ff/5",
|
||||||
"firefox/latest",
|
"firefox/latest",
|
||||||
"chrome/10",
|
"chrome/10",
|
||||||
"chrome/latest",
|
"chrome/latest",
|
||||||
"safari/5.1",
|
"safari/5.1",
|
||||||
"safari/latest",
|
"safari/latest",
|
||||||
"opera/12"
|
"opera/12"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git://github.com/minimistjs/minimist.git"
|
"url": "git://github.com/minimistjs/minimist.git"
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/minimistjs/minimist",
|
"homepage": "https://github.com/minimistjs/minimist",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"argv",
|
"argv",
|
||||||
"getopt",
|
"getopt",
|
||||||
"parser",
|
"parser",
|
||||||
"optimist"
|
"optimist"
|
||||||
],
|
],
|
||||||
"author": {
|
"author": {
|
||||||
"name": "James Halliday",
|
"name": "James Halliday",
|
||||||
"email": "mail@substack.net",
|
"email": "mail@substack.net",
|
||||||
"url": "http://substack.net"
|
"url": "http://substack.net"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"auto-changelog": {
|
"auto-changelog": {
|
||||||
"output": "CHANGELOG.md",
|
"output": "CHANGELOG.md",
|
||||||
"template": "keepachangelog",
|
"template": "keepachangelog",
|
||||||
"unreleased": false,
|
"unreleased": false,
|
||||||
"commitLimit": false,
|
"commitLimit": false,
|
||||||
"backfillLimit": false,
|
"backfillLimit": false,
|
||||||
"hideCredit": true
|
"hideCredit": true
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"ignore": [
|
"ignore": [
|
||||||
".github/workflows"
|
".github/workflows"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+26
-24
@@ -1,32 +1,34 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
var parse = require('../');
|
var parse = require('../');
|
||||||
var test = require('tape');
|
var test = require('tape');
|
||||||
|
|
||||||
test('flag boolean true (default all --args to boolean)', function (t) {
|
test('flag boolean true (default all --args to boolean)', function (t) {
|
||||||
var argv = parse(['moo', '--honk', 'cow'], {
|
var argv = parse(['moo', '--honk', 'cow'], {
|
||||||
boolean: true
|
boolean: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
t.deepEqual(argv, {
|
t.deepEqual(argv, {
|
||||||
honk: true,
|
honk: true,
|
||||||
_: ['moo', 'cow']
|
_: ['moo', 'cow'],
|
||||||
});
|
});
|
||||||
|
|
||||||
t.deepEqual(typeof argv.honk, 'boolean');
|
t.deepEqual(typeof argv.honk, 'boolean');
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('flag boolean true only affects double hyphen arguments without equals signs', function (t) {
|
test('flag boolean true only affects double hyphen arguments without equals signs', function (t) {
|
||||||
var argv = parse(['moo', '--honk', 'cow', '-p', '55', '--tacos=good'], {
|
var argv = parse(['moo', '--honk', 'cow', '-p', '55', '--tacos=good'], {
|
||||||
boolean: true
|
boolean: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
t.deepEqual(argv, {
|
t.deepEqual(argv, {
|
||||||
honk: true,
|
honk: true,
|
||||||
tacos: 'good',
|
tacos: 'good',
|
||||||
p: 55,
|
p: 55,
|
||||||
_: ['moo', 'cow']
|
_: ['moo', 'cow'],
|
||||||
});
|
});
|
||||||
|
|
||||||
t.deepEqual(typeof argv.honk, 'boolean');
|
t.deepEqual(typeof argv.honk, 'boolean');
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|||||||
+140
-141
@@ -1,178 +1,177 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
var parse = require('../');
|
var parse = require('../');
|
||||||
var test = require('tape');
|
var test = require('tape');
|
||||||
|
|
||||||
test('flag boolean default false', function (t) {
|
test('flag boolean default false', function (t) {
|
||||||
var argv = parse(['moo'], {
|
var argv = parse(['moo'], {
|
||||||
boolean: ['t', 'verbose'],
|
boolean: ['t', 'verbose'],
|
||||||
default: { verbose: false, t: false }
|
default: { verbose: false, t: false },
|
||||||
});
|
});
|
||||||
|
|
||||||
t.deepEqual(argv, {
|
t.deepEqual(argv, {
|
||||||
verbose: false,
|
verbose: false,
|
||||||
t: false,
|
t: false,
|
||||||
_: ['moo']
|
_: ['moo'],
|
||||||
});
|
});
|
||||||
|
|
||||||
t.deepEqual(typeof argv.verbose, 'boolean');
|
t.deepEqual(typeof argv.verbose, 'boolean');
|
||||||
t.deepEqual(typeof argv.t, 'boolean');
|
t.deepEqual(typeof argv.t, 'boolean');
|
||||||
t.end();
|
t.end();
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('boolean groups', function (t) {
|
test('boolean groups', function (t) {
|
||||||
var argv = parse([ '-x', '-z', 'one', 'two', 'three' ], {
|
var argv = parse(['-x', '-z', 'one', 'two', 'three'], {
|
||||||
boolean: ['x','y','z']
|
boolean: ['x', 'y', 'z'],
|
||||||
});
|
});
|
||||||
|
|
||||||
t.deepEqual(argv, {
|
t.deepEqual(argv, {
|
||||||
x : true,
|
x: true,
|
||||||
y : false,
|
y: false,
|
||||||
z : true,
|
z: true,
|
||||||
_ : [ 'one', 'two', 'three' ]
|
_: ['one', 'two', 'three'],
|
||||||
});
|
});
|
||||||
|
|
||||||
t.deepEqual(typeof argv.x, 'boolean');
|
t.deepEqual(typeof argv.x, 'boolean');
|
||||||
t.deepEqual(typeof argv.y, 'boolean');
|
t.deepEqual(typeof argv.y, 'boolean');
|
||||||
t.deepEqual(typeof argv.z, 'boolean');
|
t.deepEqual(typeof argv.z, 'boolean');
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
test('boolean and alias with chainable api', function (t) {
|
test('boolean and alias with chainable api', function (t) {
|
||||||
var aliased = [ '-h', 'derp' ];
|
var aliased = ['-h', 'derp'];
|
||||||
var regular = [ '--herp', 'derp' ];
|
var regular = ['--herp', 'derp'];
|
||||||
var opts = {
|
var aliasedArgv = parse(aliased, {
|
||||||
herp: { alias: 'h', boolean: true }
|
boolean: 'herp',
|
||||||
};
|
alias: { h: 'herp' },
|
||||||
var aliasedArgv = parse(aliased, {
|
});
|
||||||
boolean: 'herp',
|
var propertyArgv = parse(regular, {
|
||||||
alias: { h: 'herp' }
|
boolean: 'herp',
|
||||||
});
|
alias: { h: 'herp' },
|
||||||
var propertyArgv = parse(regular, {
|
});
|
||||||
boolean: 'herp',
|
var expected = {
|
||||||
alias: { h: 'herp' }
|
herp: true,
|
||||||
});
|
h: true,
|
||||||
var expected = {
|
_: ['derp'],
|
||||||
herp: true,
|
};
|
||||||
h: true,
|
|
||||||
'_': [ 'derp' ]
|
t.same(aliasedArgv, expected);
|
||||||
};
|
t.same(propertyArgv, expected);
|
||||||
|
t.end();
|
||||||
t.same(aliasedArgv, expected);
|
|
||||||
t.same(propertyArgv, expected);
|
|
||||||
t.end();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('boolean and alias with options hash', function (t) {
|
test('boolean and alias with options hash', function (t) {
|
||||||
var aliased = [ '-h', 'derp' ];
|
var aliased = ['-h', 'derp'];
|
||||||
var regular = [ '--herp', 'derp' ];
|
var regular = ['--herp', 'derp'];
|
||||||
var opts = {
|
var opts = {
|
||||||
alias: { 'h': 'herp' },
|
alias: { h: 'herp' },
|
||||||
boolean: 'herp'
|
boolean: 'herp',
|
||||||
};
|
};
|
||||||
var aliasedArgv = parse(aliased, opts);
|
var aliasedArgv = parse(aliased, opts);
|
||||||
var propertyArgv = parse(regular, opts);
|
var propertyArgv = parse(regular, opts);
|
||||||
var expected = {
|
var expected = {
|
||||||
herp: true,
|
herp: true,
|
||||||
h: true,
|
h: true,
|
||||||
'_': [ 'derp' ]
|
_: ['derp'],
|
||||||
};
|
};
|
||||||
t.same(aliasedArgv, expected);
|
t.same(aliasedArgv, expected);
|
||||||
t.same(propertyArgv, expected);
|
t.same(propertyArgv, expected);
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('boolean and alias array with options hash', function (t) {
|
test('boolean and alias array with options hash', function (t) {
|
||||||
var aliased = [ '-h', 'derp' ];
|
var aliased = ['-h', 'derp'];
|
||||||
var regular = [ '--herp', 'derp' ];
|
var regular = ['--herp', 'derp'];
|
||||||
var alt = [ '--harp', 'derp' ];
|
var alt = ['--harp', 'derp'];
|
||||||
var opts = {
|
var opts = {
|
||||||
alias: { 'h': ['herp', 'harp'] },
|
alias: { h: ['herp', 'harp'] },
|
||||||
boolean: 'h'
|
boolean: 'h',
|
||||||
};
|
};
|
||||||
var aliasedArgv = parse(aliased, opts);
|
var aliasedArgv = parse(aliased, opts);
|
||||||
var propertyArgv = parse(regular, opts);
|
var propertyArgv = parse(regular, opts);
|
||||||
var altPropertyArgv = parse(alt, opts);
|
var altPropertyArgv = parse(alt, opts);
|
||||||
var expected = {
|
var expected = {
|
||||||
harp: true,
|
harp: true,
|
||||||
herp: true,
|
herp: true,
|
||||||
h: true,
|
h: true,
|
||||||
'_': [ 'derp' ]
|
_: ['derp'],
|
||||||
};
|
};
|
||||||
t.same(aliasedArgv, expected);
|
t.same(aliasedArgv, expected);
|
||||||
t.same(propertyArgv, expected);
|
t.same(propertyArgv, expected);
|
||||||
t.same(altPropertyArgv, expected);
|
t.same(altPropertyArgv, expected);
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('boolean and alias using explicit true', function (t) {
|
test('boolean and alias using explicit true', function (t) {
|
||||||
var aliased = [ '-h', 'true' ];
|
var aliased = ['-h', 'true'];
|
||||||
var regular = [ '--herp', 'true' ];
|
var regular = ['--herp', 'true'];
|
||||||
var opts = {
|
var opts = {
|
||||||
alias: { h: 'herp' },
|
alias: { h: 'herp' },
|
||||||
boolean: 'h'
|
boolean: 'h',
|
||||||
};
|
};
|
||||||
var aliasedArgv = parse(aliased, opts);
|
var aliasedArgv = parse(aliased, opts);
|
||||||
var propertyArgv = parse(regular, opts);
|
var propertyArgv = parse(regular, opts);
|
||||||
var expected = {
|
var expected = {
|
||||||
herp: true,
|
herp: true,
|
||||||
h: true,
|
h: true,
|
||||||
'_': [ ]
|
_: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
t.same(aliasedArgv, expected);
|
t.same(aliasedArgv, expected);
|
||||||
t.same(propertyArgv, expected);
|
t.same(propertyArgv, expected);
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
// regression, see https://github.com/substack/node-optimist/issues/71
|
// regression, see https://github.com/substack/node-optimist/issues/71
|
||||||
test('boolean and --x=true', function(t) {
|
test('boolean and --x=true', function (t) {
|
||||||
var parsed = parse(['--boool', '--other=true'], {
|
var parsed = parse(['--boool', '--other=true'], {
|
||||||
boolean: 'boool'
|
boolean: 'boool',
|
||||||
});
|
});
|
||||||
|
|
||||||
t.same(parsed.boool, true);
|
t.same(parsed.boool, true);
|
||||||
t.same(parsed.other, 'true');
|
t.same(parsed.other, 'true');
|
||||||
|
|
||||||
parsed = parse(['--boool', '--other=false'], {
|
parsed = parse(['--boool', '--other=false'], {
|
||||||
boolean: 'boool'
|
boolean: 'boool',
|
||||||
});
|
});
|
||||||
|
|
||||||
t.same(parsed.boool, true);
|
t.same(parsed.boool, true);
|
||||||
t.same(parsed.other, 'false');
|
t.same(parsed.other, 'false');
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('boolean --boool=true', function (t) {
|
test('boolean --boool=true', function (t) {
|
||||||
var parsed = parse(['--boool=true'], {
|
var parsed = parse(['--boool=true'], {
|
||||||
default: {
|
default: {
|
||||||
boool: false
|
boool: false,
|
||||||
},
|
},
|
||||||
boolean: ['boool']
|
boolean: ['boool'],
|
||||||
});
|
});
|
||||||
|
|
||||||
t.same(parsed.boool, true);
|
t.same(parsed.boool, true);
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('boolean --boool=false', function (t) {
|
test('boolean --boool=false', function (t) {
|
||||||
var parsed = parse(['--boool=false'], {
|
var parsed = parse(['--boool=false'], {
|
||||||
default: {
|
default: {
|
||||||
boool: true
|
boool: true,
|
||||||
},
|
},
|
||||||
boolean: ['boool']
|
boolean: ['boool'],
|
||||||
});
|
});
|
||||||
|
|
||||||
t.same(parsed.boool, false);
|
t.same(parsed.boool, false);
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('boolean using something similar to true', function (t) {
|
test('boolean using something similar to true', function (t) {
|
||||||
var opts = { boolean: 'h' };
|
var opts = { boolean: 'h' };
|
||||||
var result = parse(['-h', 'true.txt'], opts);
|
var result = parse(['-h', 'true.txt'], opts);
|
||||||
var expected = {
|
var expected = {
|
||||||
h: true,
|
h: true,
|
||||||
'_': ['true.txt']
|
_: ['true.txt'],
|
||||||
};
|
};
|
||||||
|
|
||||||
t.same(result, expected);
|
t.same(result, expected);
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|||||||
+33
-21
@@ -1,31 +1,43 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
var parse = require('../');
|
var parse = require('../');
|
||||||
var test = require('tape');
|
var test = require('tape');
|
||||||
|
|
||||||
test('-', function (t) {
|
test('-', function (t) {
|
||||||
t.plan(5);
|
t.plan(6);
|
||||||
t.deepEqual(parse([ '-n', '-' ]), { n: '-', _: [] });
|
t.deepEqual(parse(['-n', '-']), { n: '-', _: [] });
|
||||||
t.deepEqual(parse([ '-' ]), { _: [ '-' ] });
|
t.deepEqual(parse(['--nnn', '-']), { nnn: '-', _: [] });
|
||||||
t.deepEqual(parse([ '-f-' ]), { f: '-', _: [] });
|
t.deepEqual(parse(['-']), { _: ['-'] });
|
||||||
t.deepEqual(
|
t.deepEqual(parse(['-f-']), { f: '-', _: [] });
|
||||||
parse([ '-b', '-' ], { boolean: 'b' }),
|
t.deepEqual(
|
||||||
{ b: true, _: [ '-' ] }
|
parse(['-b', '-'], { boolean: 'b' }),
|
||||||
);
|
{ b: true, _: ['-'] }
|
||||||
t.deepEqual(
|
);
|
||||||
parse([ '-s', '-' ], { string: 's' }),
|
t.deepEqual(
|
||||||
{ s: '-', _: [] }
|
parse(['-s', '-'], { string: 's' }),
|
||||||
);
|
{ s: '-', _: [] }
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('-a -- b', function (t) {
|
test('-a -- b', function (t) {
|
||||||
t.plan(3);
|
t.plan(2);
|
||||||
t.deepEqual(parse([ '-a', '--', 'b' ]), { a: true, _: [ 'b' ] });
|
t.deepEqual(parse(['-a', '--', 'b']), { a: true, _: ['b'] });
|
||||||
t.deepEqual(parse([ '--a', '--', 'b' ]), { a: true, _: [ 'b' ] });
|
t.deepEqual(parse(['--a', '--', 'b']), { a: true, _: ['b'] });
|
||||||
t.deepEqual(parse([ '--a', '--', 'b' ]), { a: true, _: [ 'b' ] });
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('move arguments after the -- into their own `--` array', function(t) {
|
test('move arguments after the -- into their own `--` array', function (t) {
|
||||||
t.plan(1);
|
t.plan(1);
|
||||||
t.deepEqual(
|
t.deepEqual(
|
||||||
parse([ '--name', 'John', 'before', '--', 'after' ], { '--': true }),
|
parse(['--name', 'John', 'before', '--', 'after'], { '--': true }),
|
||||||
{ name: 'John', _: [ 'before' ], '--': [ 'after' ] });
|
{ name: 'John', _: ['before'], '--': ['after'] }
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('--- option value', function (t) {
|
||||||
|
// A multi-dash value is largely an edge case, but check the behaviour is as expected,
|
||||||
|
// and in particular the same for short option and long option (as made consistent in Jan 2023).
|
||||||
|
t.plan(2);
|
||||||
|
t.deepEqual(parse(['-n', '---']), { n: '---', _: [] });
|
||||||
|
t.deepEqual(parse(['--nnn', '---']), { nnn: '---', _: [] });
|
||||||
|
});
|
||||||
|
|
||||||
|
|||||||
+26
-24
@@ -1,35 +1,37 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
var test = require('tape');
|
var test = require('tape');
|
||||||
var parse = require('../');
|
var parse = require('../');
|
||||||
|
|
||||||
test('boolean default true', function (t) {
|
test('boolean default true', function (t) {
|
||||||
var argv = parse([], {
|
var argv = parse([], {
|
||||||
boolean: 'sometrue',
|
boolean: 'sometrue',
|
||||||
default: { sometrue: true }
|
default: { sometrue: true },
|
||||||
});
|
});
|
||||||
t.equal(argv.sometrue, true);
|
t.equal(argv.sometrue, true);
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('boolean default false', function (t) {
|
test('boolean default false', function (t) {
|
||||||
var argv = parse([], {
|
var argv = parse([], {
|
||||||
boolean: 'somefalse',
|
boolean: 'somefalse',
|
||||||
default: { somefalse: false }
|
default: { somefalse: false },
|
||||||
});
|
});
|
||||||
t.equal(argv.somefalse, false);
|
t.equal(argv.somefalse, false);
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('boolean default to null', function (t) {
|
test('boolean default to null', function (t) {
|
||||||
var argv = parse([], {
|
var argv = parse([], {
|
||||||
boolean: 'maybe',
|
boolean: 'maybe',
|
||||||
default: { maybe: null }
|
default: { maybe: null },
|
||||||
});
|
});
|
||||||
t.equal(argv.maybe, null);
|
t.equal(argv.maybe, null);
|
||||||
var argv = parse(['--maybe'], {
|
|
||||||
boolean: 'maybe',
|
|
||||||
default: { maybe: null }
|
|
||||||
});
|
|
||||||
t.equal(argv.maybe, true);
|
|
||||||
t.end();
|
|
||||||
|
|
||||||
})
|
var argvLong = parse(['--maybe'], {
|
||||||
|
boolean: 'maybe',
|
||||||
|
default: { maybe: null },
|
||||||
|
});
|
||||||
|
t.equal(argvLong.maybe, true);
|
||||||
|
t.end();
|
||||||
|
});
|
||||||
|
|||||||
+13
-11
@@ -1,22 +1,24 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
var parse = require('../');
|
var parse = require('../');
|
||||||
var test = require('tape');
|
var test = require('tape');
|
||||||
|
|
||||||
test('dotted alias', function (t) {
|
test('dotted alias', function (t) {
|
||||||
var argv = parse(['--a.b', '22'], {default: {'a.b': 11}, alias: {'a.b': 'aa.bb'}});
|
var argv = parse(['--a.b', '22'], { default: { 'a.b': 11 }, alias: { 'a.b': 'aa.bb' } });
|
||||||
t.equal(argv.a.b, 22);
|
t.equal(argv.a.b, 22);
|
||||||
t.equal(argv.aa.bb, 22);
|
t.equal(argv.aa.bb, 22);
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('dotted default', function (t) {
|
test('dotted default', function (t) {
|
||||||
var argv = parse('', {default: {'a.b': 11}, alias: {'a.b': 'aa.bb'}});
|
var argv = parse('', { default: { 'a.b': 11 }, alias: { 'a.b': 'aa.bb' } });
|
||||||
t.equal(argv.a.b, 11);
|
t.equal(argv.a.b, 11);
|
||||||
t.equal(argv.aa.bb, 11);
|
t.equal(argv.aa.bb, 11);
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('dotted default with no alias', function (t) {
|
test('dotted default with no alias', function (t) {
|
||||||
var argv = parse('', {default: {'a.b': 11}});
|
var argv = parse('', { default: { 'a.b': 11 } });
|
||||||
t.equal(argv.a.b, 11);
|
t.equal(argv.a.b, 11);
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|||||||
+26
-10
@@ -1,16 +1,32 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
var parse = require('../');
|
var parse = require('../');
|
||||||
var test = require('tape');
|
var test = require('tape');
|
||||||
|
|
||||||
test('short -k=v' , function (t) {
|
test('short -k=v', function (t) {
|
||||||
t.plan(1);
|
t.plan(1);
|
||||||
|
|
||||||
var argv = parse([ '-b=123' ]);
|
var argv = parse(['-b=123']);
|
||||||
t.deepEqual(argv, { b: 123, _: [] });
|
t.deepEqual(argv, { b: 123, _: [] });
|
||||||
});
|
});
|
||||||
|
|
||||||
test('multi short -k=v' , function (t) {
|
test('multi short -k=v', function (t) {
|
||||||
t.plan(1);
|
t.plan(1);
|
||||||
|
|
||||||
var argv = parse([ '-a=whatever', '-b=robots' ]);
|
var argv = parse(['-a=whatever', '-b=robots']);
|
||||||
t.deepEqual(argv, { a: 'whatever', b: 'robots', _: [] });
|
t.deepEqual(argv, { a: 'whatever', b: 'robots', _: [] });
|
||||||
|
});
|
||||||
|
|
||||||
|
test('short with embedded equals -k=a=b', function (t) {
|
||||||
|
t.plan(1);
|
||||||
|
|
||||||
|
var argv = parse(['-k=a=b']);
|
||||||
|
t.deepEqual(argv, { k: 'a=b', _: [] });
|
||||||
|
});
|
||||||
|
|
||||||
|
test('short with later equals like -ab=c', function (t) {
|
||||||
|
t.plan(1);
|
||||||
|
|
||||||
|
var argv = parse(['-ab=c']);
|
||||||
|
t.deepEqual(argv, { a: true, b: 'c', _: [] });
|
||||||
});
|
});
|
||||||
|
|||||||
+28
-26
@@ -1,31 +1,33 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
var test = require('tape');
|
var test = require('tape');
|
||||||
var parse = require('../');
|
var parse = require('../');
|
||||||
|
|
||||||
test('long opts', function (t) {
|
test('long opts', function (t) {
|
||||||
t.deepEqual(
|
t.deepEqual(
|
||||||
parse([ '--bool' ]),
|
parse(['--bool']),
|
||||||
{ bool : true, _ : [] },
|
{ bool: true, _: [] },
|
||||||
'long boolean'
|
'long boolean'
|
||||||
);
|
);
|
||||||
t.deepEqual(
|
t.deepEqual(
|
||||||
parse([ '--pow', 'xixxle' ]),
|
parse(['--pow', 'xixxle']),
|
||||||
{ pow : 'xixxle', _ : [] },
|
{ pow: 'xixxle', _: [] },
|
||||||
'long capture sp'
|
'long capture sp'
|
||||||
);
|
);
|
||||||
t.deepEqual(
|
t.deepEqual(
|
||||||
parse([ '--pow=xixxle' ]),
|
parse(['--pow=xixxle']),
|
||||||
{ pow : 'xixxle', _ : [] },
|
{ pow: 'xixxle', _: [] },
|
||||||
'long capture eq'
|
'long capture eq'
|
||||||
);
|
);
|
||||||
t.deepEqual(
|
t.deepEqual(
|
||||||
parse([ '--host', 'localhost', '--port', '555' ]),
|
parse(['--host', 'localhost', '--port', '555']),
|
||||||
{ host : 'localhost', port : 555, _ : [] },
|
{ host: 'localhost', port: 555, _: [] },
|
||||||
'long captures sp'
|
'long captures sp'
|
||||||
);
|
);
|
||||||
t.deepEqual(
|
t.deepEqual(
|
||||||
parse([ '--host=localhost', '--port=555' ]),
|
parse(['--host=localhost', '--port=555']),
|
||||||
{ host : 'localhost', port : 555, _ : [] },
|
{ host: 'localhost', port: 555, _: [] },
|
||||||
'long captures eq'
|
'long captures eq'
|
||||||
);
|
);
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|||||||
+30
-28
@@ -1,36 +1,38 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
var parse = require('../');
|
var parse = require('../');
|
||||||
var test = require('tape');
|
var test = require('tape');
|
||||||
|
|
||||||
test('nums', function (t) {
|
test('nums', function (t) {
|
||||||
var argv = parse([
|
var argv = parse([
|
||||||
'-x', '1234',
|
'-x', '1234',
|
||||||
'-y', '5.67',
|
'-y', '5.67',
|
||||||
'-z', '1e7',
|
'-z', '1e7',
|
||||||
'-w', '10f',
|
'-w', '10f',
|
||||||
'--hex', '0xdeadbeef',
|
'--hex', '0xdeadbeef',
|
||||||
'789'
|
'789',
|
||||||
]);
|
]);
|
||||||
t.deepEqual(argv, {
|
t.deepEqual(argv, {
|
||||||
x : 1234,
|
x: 1234,
|
||||||
y : 5.67,
|
y: 5.67,
|
||||||
z : 1e7,
|
z: 1e7,
|
||||||
w : '10f',
|
w: '10f',
|
||||||
hex : 0xdeadbeef,
|
hex: 0xdeadbeef,
|
||||||
_ : [ 789 ]
|
_: [789],
|
||||||
});
|
});
|
||||||
t.deepEqual(typeof argv.x, 'number');
|
t.deepEqual(typeof argv.x, 'number');
|
||||||
t.deepEqual(typeof argv.y, 'number');
|
t.deepEqual(typeof argv.y, 'number');
|
||||||
t.deepEqual(typeof argv.z, 'number');
|
t.deepEqual(typeof argv.z, 'number');
|
||||||
t.deepEqual(typeof argv.w, 'string');
|
t.deepEqual(typeof argv.w, 'string');
|
||||||
t.deepEqual(typeof argv.hex, 'number');
|
t.deepEqual(typeof argv.hex, 'number');
|
||||||
t.deepEqual(typeof argv._[0], 'number');
|
t.deepEqual(typeof argv._[0], 'number');
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('already a number', function (t) {
|
test('already a number', function (t) {
|
||||||
var argv = parse([ '-x', 1234, 789 ]);
|
var argv = parse(['-x', 1234, 789]);
|
||||||
t.deepEqual(argv, { x : 1234, _ : [ 789 ] });
|
t.deepEqual(argv, { x: 1234, _: [789] });
|
||||||
t.deepEqual(typeof argv.x, 'number');
|
t.deepEqual(typeof argv.x, 'number');
|
||||||
t.deepEqual(typeof argv._[0], 'number');
|
t.deepEqual(typeof argv._[0], 'number');
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|||||||
+165
-153
@@ -1,197 +1,209 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
var parse = require('../');
|
var parse = require('../');
|
||||||
var test = require('tape');
|
var test = require('tape');
|
||||||
|
|
||||||
test('parse args', function (t) {
|
test('parse args', function (t) {
|
||||||
t.deepEqual(
|
t.deepEqual(
|
||||||
parse([ '--no-moo' ]),
|
parse(['--no-moo']),
|
||||||
{ moo : false, _ : [] },
|
{ moo: false, _: [] },
|
||||||
'no'
|
'no'
|
||||||
);
|
);
|
||||||
t.deepEqual(
|
t.deepEqual(
|
||||||
parse([ '-v', 'a', '-v', 'b', '-v', 'c' ]),
|
parse(['-v', 'a', '-v', 'b', '-v', 'c']),
|
||||||
{ v : ['a','b','c'], _ : [] },
|
{ v: ['a', 'b', 'c'], _: [] },
|
||||||
'multi'
|
'multi'
|
||||||
);
|
);
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('comprehensive', function (t) {
|
test('comprehensive', function (t) {
|
||||||
t.deepEqual(
|
t.deepEqual(
|
||||||
parse([
|
parse([
|
||||||
'--name=meowmers', 'bare', '-cats', 'woo',
|
'--name=meowmers', 'bare', '-cats', 'woo',
|
||||||
'-h', 'awesome', '--multi=quux',
|
'-h', 'awesome', '--multi=quux',
|
||||||
'--key', 'value',
|
'--key', 'value',
|
||||||
'-b', '--bool', '--no-meep', '--multi=baz',
|
'-b', '--bool', '--no-meep', '--multi=baz',
|
||||||
'--', '--not-a-flag', 'eek'
|
'--', '--not-a-flag', 'eek',
|
||||||
]),
|
]),
|
||||||
{
|
{
|
||||||
c : true,
|
c: true,
|
||||||
a : true,
|
a: true,
|
||||||
t : true,
|
t: true,
|
||||||
s : 'woo',
|
s: 'woo',
|
||||||
h : 'awesome',
|
h: 'awesome',
|
||||||
b : true,
|
b: true,
|
||||||
bool : true,
|
bool: true,
|
||||||
key : 'value',
|
key: 'value',
|
||||||
multi : [ 'quux', 'baz' ],
|
multi: ['quux', 'baz'],
|
||||||
meep : false,
|
meep: false,
|
||||||
name : 'meowmers',
|
name: 'meowmers',
|
||||||
_ : [ 'bare', '--not-a-flag', 'eek' ]
|
_: ['bare', '--not-a-flag', 'eek'],
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('flag boolean', function (t) {
|
test('flag boolean', function (t) {
|
||||||
var argv = parse([ '-t', 'moo' ], { boolean: 't' });
|
var argv = parse(['-t', 'moo'], { boolean: 't' });
|
||||||
t.deepEqual(argv, { t : true, _ : [ 'moo' ] });
|
t.deepEqual(argv, { t: true, _: ['moo'] });
|
||||||
t.deepEqual(typeof argv.t, 'boolean');
|
t.deepEqual(typeof argv.t, 'boolean');
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('flag boolean value', function (t) {
|
test('flag boolean value', function (t) {
|
||||||
var argv = parse(['--verbose', 'false', 'moo', '-t', 'true'], {
|
var argv = parse(['--verbose', 'false', 'moo', '-t', 'true'], {
|
||||||
boolean: [ 't', 'verbose' ],
|
boolean: ['t', 'verbose'],
|
||||||
default: { verbose: true }
|
default: { verbose: true },
|
||||||
});
|
});
|
||||||
|
|
||||||
t.deepEqual(argv, {
|
t.deepEqual(argv, {
|
||||||
verbose: false,
|
verbose: false,
|
||||||
t: true,
|
t: true,
|
||||||
_: ['moo']
|
_: ['moo'],
|
||||||
});
|
});
|
||||||
|
|
||||||
t.deepEqual(typeof argv.verbose, 'boolean');
|
t.deepEqual(typeof argv.verbose, 'boolean');
|
||||||
t.deepEqual(typeof argv.t, 'boolean');
|
t.deepEqual(typeof argv.t, 'boolean');
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('newlines in params' , function (t) {
|
test('newlines in params', function (t) {
|
||||||
var args = parse([ '-s', "X\nX" ])
|
var args = parse(['-s', 'X\nX']);
|
||||||
t.deepEqual(args, { _ : [], s : "X\nX" });
|
t.deepEqual(args, { _: [], s: 'X\nX' });
|
||||||
|
|
||||||
// reproduce in bash:
|
// reproduce in bash:
|
||||||
// VALUE="new
|
// VALUE="new
|
||||||
// line"
|
// line"
|
||||||
// node program.js --s="$VALUE"
|
// node program.js --s="$VALUE"
|
||||||
args = parse([ "--s=X\nX" ])
|
args = parse(['--s=X\nX']);
|
||||||
t.deepEqual(args, { _ : [], s : "X\nX" });
|
t.deepEqual(args, { _: [], s: 'X\nX' });
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('strings' , function (t) {
|
test('strings', function (t) {
|
||||||
var s = parse([ '-s', '0001234' ], { string: 's' }).s;
|
var s = parse(['-s', '0001234'], { string: 's' }).s;
|
||||||
t.equal(s, '0001234');
|
t.equal(s, '0001234');
|
||||||
t.equal(typeof s, 'string');
|
t.equal(typeof s, 'string');
|
||||||
|
|
||||||
var x = parse([ '-x', '56' ], { string: 'x' }).x;
|
var x = parse(['-x', '56'], { string: 'x' }).x;
|
||||||
t.equal(x, '56');
|
t.equal(x, '56');
|
||||||
t.equal(typeof x, 'string');
|
t.equal(typeof x, 'string');
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('stringArgs', function (t) {
|
test('stringArgs', function (t) {
|
||||||
var s = parse([ ' ', ' ' ], { string: '_' })._;
|
var s = parse([' ', ' '], { string: '_' })._;
|
||||||
t.same(s.length, 2);
|
t.same(s.length, 2);
|
||||||
t.same(typeof s[0], 'string');
|
t.same(typeof s[0], 'string');
|
||||||
t.same(s[0], ' ');
|
t.same(s[0], ' ');
|
||||||
t.same(typeof s[1], 'string');
|
t.same(typeof s[1], 'string');
|
||||||
t.same(s[1], ' ');
|
t.same(s[1], ' ');
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('empty strings', function(t) {
|
test('empty strings', function (t) {
|
||||||
var s = parse([ '-s' ], { string: 's' }).s;
|
var s = parse(['-s'], { string: 's' }).s;
|
||||||
t.equal(s, '');
|
t.equal(s, '');
|
||||||
t.equal(typeof s, 'string');
|
t.equal(typeof s, 'string');
|
||||||
|
|
||||||
var str = parse([ '--str' ], { string: 'str' }).str;
|
var str = parse(['--str'], { string: 'str' }).str;
|
||||||
t.equal(str, '');
|
t.equal(str, '');
|
||||||
t.equal(typeof str, 'string');
|
t.equal(typeof str, 'string');
|
||||||
|
|
||||||
var letters = parse([ '-art' ], {
|
var letters = parse(['-art'], {
|
||||||
string: [ 'a', 't' ]
|
string: ['a', 't'],
|
||||||
});
|
});
|
||||||
|
|
||||||
t.equal(letters.a, '');
|
t.equal(letters.a, '');
|
||||||
t.equal(letters.r, true);
|
t.equal(letters.r, true);
|
||||||
t.equal(letters.t, '');
|
t.equal(letters.t, '');
|
||||||
|
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('string and alias', function (t) {
|
||||||
|
var x = parse(['--str', '000123'], {
|
||||||
|
string: 's',
|
||||||
|
alias: { s: 'str' },
|
||||||
|
});
|
||||||
|
|
||||||
test('string and alias', function(t) {
|
t.equal(x.str, '000123');
|
||||||
var x = parse([ '--str', '000123' ], {
|
t.equal(typeof x.str, 'string');
|
||||||
string: 's',
|
t.equal(x.s, '000123');
|
||||||
alias: { s: 'str' }
|
t.equal(typeof x.s, 'string');
|
||||||
});
|
|
||||||
|
|
||||||
t.equal(x.str, '000123');
|
var y = parse(['-s', '000123'], {
|
||||||
t.equal(typeof x.str, 'string');
|
string: 'str',
|
||||||
t.equal(x.s, '000123');
|
alias: { str: 's' },
|
||||||
t.equal(typeof x.s, 'string');
|
});
|
||||||
|
|
||||||
var y = parse([ '-s', '000123' ], {
|
t.equal(y.str, '000123');
|
||||||
string: 'str',
|
t.equal(typeof y.str, 'string');
|
||||||
alias: { str: 's' }
|
t.equal(y.s, '000123');
|
||||||
});
|
t.equal(typeof y.s, 'string');
|
||||||
|
|
||||||
t.equal(y.str, '000123');
|
var z = parse(['-s123'], {
|
||||||
t.equal(typeof y.str, 'string');
|
alias: { str: ['s', 'S'] },
|
||||||
t.equal(y.s, '000123');
|
string: ['str'],
|
||||||
t.equal(typeof y.s, 'string');
|
});
|
||||||
t.end();
|
|
||||||
|
t.deepEqual(
|
||||||
|
z,
|
||||||
|
{ _: [], s: '123', S: '123', str: '123' },
|
||||||
|
'opt.string works with multiple aliases'
|
||||||
|
);
|
||||||
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('slashBreak', function (t) {
|
test('slashBreak', function (t) {
|
||||||
t.same(
|
t.same(
|
||||||
parse([ '-I/foo/bar/baz' ]),
|
parse(['-I/foo/bar/baz']),
|
||||||
{ I : '/foo/bar/baz', _ : [] }
|
{ I: '/foo/bar/baz', _: [] }
|
||||||
);
|
);
|
||||||
t.same(
|
t.same(
|
||||||
parse([ '-xyz/foo/bar/baz' ]),
|
parse(['-xyz/foo/bar/baz']),
|
||||||
{ x : true, y : true, z : '/foo/bar/baz', _ : [] }
|
{ x: true, y: true, z: '/foo/bar/baz', _: [] }
|
||||||
);
|
);
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('alias', function (t) {
|
test('alias', function (t) {
|
||||||
var argv = parse([ '-f', '11', '--zoom', '55' ], {
|
var argv = parse(['-f', '11', '--zoom', '55'], {
|
||||||
alias: { z: 'zoom' }
|
alias: { z: 'zoom' },
|
||||||
});
|
});
|
||||||
t.equal(argv.zoom, 55);
|
t.equal(argv.zoom, 55);
|
||||||
t.equal(argv.z, argv.zoom);
|
t.equal(argv.z, argv.zoom);
|
||||||
t.equal(argv.f, 11);
|
t.equal(argv.f, 11);
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('multiAlias', function (t) {
|
test('multiAlias', function (t) {
|
||||||
var argv = parse([ '-f', '11', '--zoom', '55' ], {
|
var argv = parse(['-f', '11', '--zoom', '55'], {
|
||||||
alias: { z: [ 'zm', 'zoom' ] }
|
alias: { z: ['zm', 'zoom'] },
|
||||||
});
|
});
|
||||||
t.equal(argv.zoom, 55);
|
t.equal(argv.zoom, 55);
|
||||||
t.equal(argv.z, argv.zoom);
|
t.equal(argv.z, argv.zoom);
|
||||||
t.equal(argv.z, argv.zm);
|
t.equal(argv.z, argv.zm);
|
||||||
t.equal(argv.f, 11);
|
t.equal(argv.f, 11);
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('nested dotted objects', function (t) {
|
test('nested dotted objects', function (t) {
|
||||||
var argv = parse([
|
var argv = parse([
|
||||||
'--foo.bar', '3', '--foo.baz', '4',
|
'--foo.bar', '3', '--foo.baz', '4',
|
||||||
'--foo.quux.quibble', '5', '--foo.quux.o_O',
|
'--foo.quux.quibble', '5', '--foo.quux.o_O',
|
||||||
'--beep.boop'
|
'--beep.boop',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
t.same(argv.foo, {
|
t.same(argv.foo, {
|
||||||
bar : 3,
|
bar: 3,
|
||||||
baz : 4,
|
baz: 4,
|
||||||
quux : {
|
quux: {
|
||||||
quibble : 5,
|
quibble: 5,
|
||||||
o_O : true
|
o_O: true,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
t.same(argv.beep, { boop : true });
|
t.same(argv.beep, { boop: true });
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|||||||
+7
-5
@@ -1,9 +1,11 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
var parse = require('../');
|
var parse = require('../');
|
||||||
var test = require('tape');
|
var test = require('tape');
|
||||||
|
|
||||||
test('parse with modifier functions' , function (t) {
|
test('parse with modifier functions', function (t) {
|
||||||
t.plan(1);
|
t.plan(1);
|
||||||
|
|
||||||
var argv = parse([ '-b', '123' ], { boolean: 'b' });
|
var argv = parse(['-b', '123'], { boolean: 'b' });
|
||||||
t.deepEqual(argv, { b: true, _: [123] });
|
t.deepEqual(argv, { b: true, _: [123] });
|
||||||
});
|
});
|
||||||
|
|||||||
+41
-37
@@ -1,60 +1,64 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
/* eslint no-proto: 0 */
|
||||||
|
|
||||||
var parse = require('../');
|
var parse = require('../');
|
||||||
var test = require('tape');
|
var test = require('tape');
|
||||||
|
|
||||||
test('proto pollution', function (t) {
|
test('proto pollution', function (t) {
|
||||||
var argv = parse(['--__proto__.x','123']);
|
var argv = parse(['--__proto__.x', '123']);
|
||||||
t.equal({}.x, undefined);
|
t.equal({}.x, undefined);
|
||||||
t.equal(argv.__proto__.x, undefined);
|
t.equal(argv.__proto__.x, undefined);
|
||||||
t.equal(argv.x, undefined);
|
t.equal(argv.x, undefined);
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('proto pollution (array)', function (t) {
|
test('proto pollution (array)', function (t) {
|
||||||
var argv = parse(['--x','4','--x','5','--x.__proto__.z','789']);
|
var argv = parse(['--x', '4', '--x', '5', '--x.__proto__.z', '789']);
|
||||||
t.equal({}.z, undefined);
|
t.equal({}.z, undefined);
|
||||||
t.deepEqual(argv.x, [4,5]);
|
t.deepEqual(argv.x, [4, 5]);
|
||||||
t.equal(argv.x.z, undefined);
|
t.equal(argv.x.z, undefined);
|
||||||
t.equal(argv.x.__proto__.z, undefined);
|
t.equal(argv.x.__proto__.z, undefined);
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('proto pollution (number)', function (t) {
|
test('proto pollution (number)', function (t) {
|
||||||
var argv = parse(['--x','5','--x.__proto__.z','100']);
|
var argv = parse(['--x', '5', '--x.__proto__.z', '100']);
|
||||||
t.equal({}.z, undefined);
|
t.equal({}.z, undefined);
|
||||||
t.equal((4).z, undefined);
|
t.equal((4).z, undefined);
|
||||||
t.equal(argv.x, 5);
|
t.equal(argv.x, 5);
|
||||||
t.equal(argv.x.z, undefined);
|
t.equal(argv.x.z, undefined);
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('proto pollution (string)', function (t) {
|
test('proto pollution (string)', function (t) {
|
||||||
var argv = parse(['--x','abc','--x.__proto__.z','def']);
|
var argv = parse(['--x', 'abc', '--x.__proto__.z', 'def']);
|
||||||
t.equal({}.z, undefined);
|
t.equal({}.z, undefined);
|
||||||
t.equal('...'.z, undefined);
|
t.equal('...'.z, undefined);
|
||||||
t.equal(argv.x, 'abc');
|
t.equal(argv.x, 'abc');
|
||||||
t.equal(argv.x.z, undefined);
|
t.equal(argv.x.z, undefined);
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('proto pollution (constructor)', function (t) {
|
test('proto pollution (constructor)', function (t) {
|
||||||
var argv = parse(['--constructor.prototype.y','123']);
|
var argv = parse(['--constructor.prototype.y', '123']);
|
||||||
t.equal({}.y, undefined);
|
t.equal({}.y, undefined);
|
||||||
t.equal(argv.y, undefined);
|
t.equal(argv.y, undefined);
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('proto pollution (constructor function)', function (t) {
|
test('proto pollution (constructor function)', function (t) {
|
||||||
var argv = parse(['--_.concat.constructor.prototype.y', '123']);
|
var argv = parse(['--_.concat.constructor.prototype.y', '123']);
|
||||||
function fnToBeTested() {}
|
function fnToBeTested() {}
|
||||||
t.equal(fnToBeTested.y, undefined);
|
t.equal(fnToBeTested.y, undefined);
|
||||||
t.equal(argv.y, undefined);
|
t.equal(argv.y, undefined);
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
// powered by snyk - https://github.com/backstage/backstage/issues/10343
|
// powered by snyk - https://github.com/backstage/backstage/issues/10343
|
||||||
test('proto pollution (constructor function) snyk', function (t) {
|
test('proto pollution (constructor function) snyk', function (t) {
|
||||||
var argv = parse('--_.constructor.constructor.prototype.foo bar'.split(' '));
|
var argv = parse('--_.constructor.constructor.prototype.foo bar'.split(' '));
|
||||||
t.equal((function(){}).foo, undefined);
|
t.equal(function () {}.foo, undefined);
|
||||||
t.equal(argv.y, undefined);
|
t.equal(argv.y, undefined);
|
||||||
t.end();
|
t.end();
|
||||||
})
|
});
|
||||||
|
|||||||
+57
-55
@@ -1,67 +1,69 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
var parse = require('../');
|
var parse = require('../');
|
||||||
var test = require('tape');
|
var test = require('tape');
|
||||||
|
|
||||||
test('numeric short args', function (t) {
|
test('numeric short args', function (t) {
|
||||||
t.plan(2);
|
t.plan(2);
|
||||||
t.deepEqual(parse([ '-n123' ]), { n: 123, _: [] });
|
t.deepEqual(parse(['-n123']), { n: 123, _: [] });
|
||||||
t.deepEqual(
|
t.deepEqual(
|
||||||
parse([ '-123', '456' ]),
|
parse(['-123', '456']),
|
||||||
{ 1: true, 2: true, 3: 456, _: [] }
|
{ 1: true, 2: true, 3: 456, _: [] }
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('short', function (t) {
|
test('short', function (t) {
|
||||||
t.deepEqual(
|
t.deepEqual(
|
||||||
parse([ '-b' ]),
|
parse(['-b']),
|
||||||
{ b : true, _ : [] },
|
{ b: true, _: [] },
|
||||||
'short boolean'
|
'short boolean'
|
||||||
);
|
);
|
||||||
t.deepEqual(
|
t.deepEqual(
|
||||||
parse([ 'foo', 'bar', 'baz' ]),
|
parse(['foo', 'bar', 'baz']),
|
||||||
{ _ : [ 'foo', 'bar', 'baz' ] },
|
{ _: ['foo', 'bar', 'baz'] },
|
||||||
'bare'
|
'bare'
|
||||||
);
|
);
|
||||||
t.deepEqual(
|
t.deepEqual(
|
||||||
parse([ '-cats' ]),
|
parse(['-cats']),
|
||||||
{ c : true, a : true, t : true, s : true, _ : [] },
|
{ c: true, a: true, t: true, s: true, _: [] },
|
||||||
'group'
|
'group'
|
||||||
);
|
);
|
||||||
t.deepEqual(
|
t.deepEqual(
|
||||||
parse([ '-cats', 'meow' ]),
|
parse(['-cats', 'meow']),
|
||||||
{ c : true, a : true, t : true, s : 'meow', _ : [] },
|
{ c: true, a: true, t: true, s: 'meow', _: [] },
|
||||||
'short group next'
|
'short group next'
|
||||||
);
|
);
|
||||||
t.deepEqual(
|
t.deepEqual(
|
||||||
parse([ '-h', 'localhost' ]),
|
parse(['-h', 'localhost']),
|
||||||
{ h : 'localhost', _ : [] },
|
{ h: 'localhost', _: [] },
|
||||||
'short capture'
|
'short capture'
|
||||||
);
|
);
|
||||||
t.deepEqual(
|
t.deepEqual(
|
||||||
parse([ '-h', 'localhost', '-p', '555' ]),
|
parse(['-h', 'localhost', '-p', '555']),
|
||||||
{ h : 'localhost', p : 555, _ : [] },
|
{ h: 'localhost', p: 555, _: [] },
|
||||||
'short captures'
|
'short captures'
|
||||||
);
|
);
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('mixed short bool and capture', function (t) {
|
test('mixed short bool and capture', function (t) {
|
||||||
t.same(
|
t.same(
|
||||||
parse([ '-h', 'localhost', '-fp', '555', 'script.js' ]),
|
parse(['-h', 'localhost', '-fp', '555', 'script.js']),
|
||||||
{
|
{
|
||||||
f : true, p : 555, h : 'localhost',
|
f: true, p: 555, h: 'localhost',
|
||||||
_ : [ 'script.js' ]
|
_: ['script.js'],
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('short and long', function (t) {
|
test('short and long', function (t) {
|
||||||
t.deepEqual(
|
t.deepEqual(
|
||||||
parse([ '-h', 'localhost', '-fp', '555', 'script.js' ]),
|
parse(['-h', 'localhost', '-fp', '555', 'script.js']),
|
||||||
{
|
{
|
||||||
f : true, p : 555, h : 'localhost',
|
f: true, p: 555, h: 'localhost',
|
||||||
_ : [ 'script.js' ]
|
_: ['script.js'],
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|||||||
+10
-8
@@ -1,15 +1,17 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
var parse = require('../');
|
var parse = require('../');
|
||||||
var test = require('tape');
|
var test = require('tape');
|
||||||
|
|
||||||
test('stops parsing on the first non-option when stopEarly is set', function (t) {
|
test('stops parsing on the first non-option when stopEarly is set', function (t) {
|
||||||
var argv = parse(['--aaa', 'bbb', 'ccc', '--ddd'], {
|
var argv = parse(['--aaa', 'bbb', 'ccc', '--ddd'], {
|
||||||
stopEarly: true
|
stopEarly: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
t.deepEqual(argv, {
|
t.deepEqual(argv, {
|
||||||
aaa: 'bbb',
|
aaa: 'bbb',
|
||||||
_: ['ccc', '--ddd']
|
_: ['ccc', '--ddd'],
|
||||||
});
|
});
|
||||||
|
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|||||||
+83
-81
@@ -1,102 +1,104 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
var parse = require('../');
|
var parse = require('../');
|
||||||
var test = require('tape');
|
var test = require('tape');
|
||||||
|
|
||||||
test('boolean and alias is not unknown', function (t) {
|
test('boolean and alias is not unknown', function (t) {
|
||||||
var unknown = [];
|
var unknown = [];
|
||||||
function unknownFn(arg) {
|
function unknownFn(arg) {
|
||||||
unknown.push(arg);
|
unknown.push(arg);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
var aliased = [ '-h', 'true', '--derp', 'true' ];
|
var aliased = ['-h', 'true', '--derp', 'true'];
|
||||||
var regular = [ '--herp', 'true', '-d', 'true' ];
|
var regular = ['--herp', 'true', '-d', 'true'];
|
||||||
var opts = {
|
var opts = {
|
||||||
alias: { h: 'herp' },
|
alias: { h: 'herp' },
|
||||||
boolean: 'h',
|
boolean: 'h',
|
||||||
unknown: unknownFn
|
unknown: unknownFn,
|
||||||
};
|
};
|
||||||
var aliasedArgv = parse(aliased, opts);
|
parse(aliased, opts);
|
||||||
var propertyArgv = parse(regular, opts);
|
parse(regular, opts);
|
||||||
|
|
||||||
t.same(unknown, ['--derp', '-d']);
|
t.same(unknown, ['--derp', '-d']);
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('flag boolean true any double hyphen argument is not unknown', function (t) {
|
test('flag boolean true any double hyphen argument is not unknown', function (t) {
|
||||||
var unknown = [];
|
var unknown = [];
|
||||||
function unknownFn(arg) {
|
function unknownFn(arg) {
|
||||||
unknown.push(arg);
|
unknown.push(arg);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
var argv = parse(['--honk', '--tacos=good', 'cow', '-p', '55'], {
|
var argv = parse(['--honk', '--tacos=good', 'cow', '-p', '55'], {
|
||||||
boolean: true,
|
boolean: true,
|
||||||
unknown: unknownFn
|
unknown: unknownFn,
|
||||||
});
|
});
|
||||||
t.same(unknown, ['--tacos=good', 'cow', '-p']);
|
t.same(unknown, ['--tacos=good', 'cow', '-p']);
|
||||||
t.same(argv, {
|
t.same(argv, {
|
||||||
honk: true,
|
honk: true,
|
||||||
_: []
|
_: [],
|
||||||
});
|
});
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('string and alias is not unknown', function (t) {
|
test('string and alias is not unknown', function (t) {
|
||||||
var unknown = [];
|
var unknown = [];
|
||||||
function unknownFn(arg) {
|
function unknownFn(arg) {
|
||||||
unknown.push(arg);
|
unknown.push(arg);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
var aliased = [ '-h', 'hello', '--derp', 'goodbye' ];
|
var aliased = ['-h', 'hello', '--derp', 'goodbye'];
|
||||||
var regular = [ '--herp', 'hello', '-d', 'moon' ];
|
var regular = ['--herp', 'hello', '-d', 'moon'];
|
||||||
var opts = {
|
var opts = {
|
||||||
alias: { h: 'herp' },
|
alias: { h: 'herp' },
|
||||||
string: 'h',
|
string: 'h',
|
||||||
unknown: unknownFn
|
unknown: unknownFn,
|
||||||
};
|
};
|
||||||
var aliasedArgv = parse(aliased, opts);
|
parse(aliased, opts);
|
||||||
var propertyArgv = parse(regular, opts);
|
parse(regular, opts);
|
||||||
|
|
||||||
t.same(unknown, ['--derp', '-d']);
|
t.same(unknown, ['--derp', '-d']);
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('default and alias is not unknown', function (t) {
|
test('default and alias is not unknown', function (t) {
|
||||||
var unknown = [];
|
var unknown = [];
|
||||||
function unknownFn(arg) {
|
function unknownFn(arg) {
|
||||||
unknown.push(arg);
|
unknown.push(arg);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
var aliased = [ '-h', 'hello' ];
|
var aliased = ['-h', 'hello'];
|
||||||
var regular = [ '--herp', 'hello' ];
|
var regular = ['--herp', 'hello'];
|
||||||
var opts = {
|
var opts = {
|
||||||
default: { 'h': 'bar' },
|
default: { h: 'bar' },
|
||||||
alias: { 'h': 'herp' },
|
alias: { h: 'herp' },
|
||||||
unknown: unknownFn
|
unknown: unknownFn,
|
||||||
};
|
};
|
||||||
var aliasedArgv = parse(aliased, opts);
|
parse(aliased, opts);
|
||||||
var propertyArgv = parse(regular, opts);
|
parse(regular, opts);
|
||||||
|
|
||||||
t.same(unknown, []);
|
t.same(unknown, []);
|
||||||
t.end();
|
t.end();
|
||||||
unknownFn(); // exercise fn for 100% coverage
|
unknownFn(); // exercise fn for 100% coverage
|
||||||
});
|
});
|
||||||
|
|
||||||
test('value following -- is not unknown', function (t) {
|
test('value following -- is not unknown', function (t) {
|
||||||
var unknown = [];
|
var unknown = [];
|
||||||
function unknownFn(arg) {
|
function unknownFn(arg) {
|
||||||
unknown.push(arg);
|
unknown.push(arg);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
var aliased = [ '--bad', '--', 'good', 'arg' ];
|
var aliased = ['--bad', '--', 'good', 'arg'];
|
||||||
var opts = {
|
var opts = {
|
||||||
'--': true,
|
'--': true,
|
||||||
unknown: unknownFn
|
unknown: unknownFn,
|
||||||
};
|
};
|
||||||
var argv = parse(aliased, opts);
|
var argv = parse(aliased, opts);
|
||||||
|
|
||||||
t.same(unknown, ['--bad']);
|
t.same(unknown, ['--bad']);
|
||||||
t.same(argv, {
|
t.same(argv, {
|
||||||
'--': ['good', 'arg'],
|
'--': ['good', 'arg'],
|
||||||
'_': []
|
_: [],
|
||||||
})
|
});
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|||||||
+6
-4
@@ -1,8 +1,10 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
var parse = require('../');
|
var parse = require('../');
|
||||||
var test = require('tape');
|
var test = require('tape');
|
||||||
|
|
||||||
test('whitespace should be whitespace' , function (t) {
|
test('whitespace should be whitespace', function (t) {
|
||||||
t.plan(1);
|
t.plan(1);
|
||||||
var x = parse([ '-x', '\t' ]).x;
|
var x = parse(['-x', '\t']).x;
|
||||||
t.equal(x, '\t');
|
t.equal(x, '\t');
|
||||||
});
|
});
|
||||||
|
|||||||
-70
@@ -1,70 +0,0 @@
|
|||||||
# changes log
|
|
||||||
|
|
||||||
## 6.2.0
|
|
||||||
|
|
||||||
* Coerce numbers to strings when passed to semver.coerce()
|
|
||||||
* Add `rtl` option to coerce from right to left
|
|
||||||
|
|
||||||
## 6.1.3
|
|
||||||
|
|
||||||
* Handle X-ranges properly in includePrerelease mode
|
|
||||||
|
|
||||||
## 6.1.2
|
|
||||||
|
|
||||||
* Do not throw when testing invalid version strings
|
|
||||||
|
|
||||||
## 6.1.1
|
|
||||||
|
|
||||||
* Add options support for semver.coerce()
|
|
||||||
* Handle undefined version passed to Range.test
|
|
||||||
|
|
||||||
## 6.1.0
|
|
||||||
|
|
||||||
* Add semver.compareBuild function
|
|
||||||
* Support `*` in semver.intersects
|
|
||||||
|
|
||||||
## 6.0
|
|
||||||
|
|
||||||
* Fix `intersects` logic.
|
|
||||||
|
|
||||||
This is technically a bug fix, but since it is also a change to behavior
|
|
||||||
that may require users updating their code, it is marked as a major
|
|
||||||
version increment.
|
|
||||||
|
|
||||||
## 5.7
|
|
||||||
|
|
||||||
* Add `minVersion` method
|
|
||||||
|
|
||||||
## 5.6
|
|
||||||
|
|
||||||
* Move boolean `loose` param to an options object, with
|
|
||||||
backwards-compatibility protection.
|
|
||||||
* Add ability to opt out of special prerelease version handling with
|
|
||||||
the `includePrerelease` option flag.
|
|
||||||
|
|
||||||
## 5.5
|
|
||||||
|
|
||||||
* Add version coercion capabilities
|
|
||||||
|
|
||||||
## 5.4
|
|
||||||
|
|
||||||
* Add intersection checking
|
|
||||||
|
|
||||||
## 5.3
|
|
||||||
|
|
||||||
* Add `minSatisfying` method
|
|
||||||
|
|
||||||
## 5.2
|
|
||||||
|
|
||||||
* Add `prerelease(v)` that returns prerelease components
|
|
||||||
|
|
||||||
## 5.1
|
|
||||||
|
|
||||||
* Add Backus-Naur for ranges
|
|
||||||
* Remove excessively cute inspection methods
|
|
||||||
|
|
||||||
## 5.0
|
|
||||||
|
|
||||||
* Remove AMD/Browserified build artifacts
|
|
||||||
* Fix ltr and gtr when using the `*` range
|
|
||||||
* Fix for range `*` with a prerelease identifier
|
|
||||||
+27
-55
@@ -1,66 +1,38 @@
|
|||||||
{
|
{
|
||||||
"_args": [
|
"name": "semver",
|
||||||
[
|
"version": "6.3.1",
|
||||||
"semver@6.3.0",
|
"description": "The semantic version parser used by npm.",
|
||||||
"/Users/Yang/Desktop/Projects/android-emulator-runner"
|
"main": "semver.js",
|
||||||
]
|
"scripts": {
|
||||||
],
|
"test": "tap test/ --100 --timeout=30",
|
||||||
"_from": "semver@6.3.0",
|
"lint": "echo linting disabled",
|
||||||
"_id": "semver@6.3.0",
|
"postlint": "template-oss-check",
|
||||||
"_inBundle": false,
|
"template-oss-apply": "template-oss-apply --force",
|
||||||
"_integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
"lintfix": "npm run lint -- --fix",
|
||||||
"_location": "/semver",
|
"snap": "tap test/ --100 --timeout=30",
|
||||||
"_phantomChildren": {},
|
"posttest": "npm run lint"
|
||||||
"_requested": {
|
},
|
||||||
"type": "version",
|
"devDependencies": {
|
||||||
"registry": true,
|
"@npmcli/template-oss": "4.17.0",
|
||||||
"raw": "semver@6.3.0",
|
"tap": "^12.7.0"
|
||||||
"name": "semver",
|
},
|
||||||
"escapedName": "semver",
|
"license": "ISC",
|
||||||
"rawSpec": "6.3.0",
|
"repository": {
|
||||||
"saveSpec": null,
|
"type": "git",
|
||||||
"fetchSpec": "6.3.0"
|
"url": "https://github.com/npm/node-semver.git"
|
||||||
},
|
},
|
||||||
"_requiredBy": [
|
|
||||||
"/@actions/tool-cache",
|
|
||||||
"/@typescript-eslint/typescript-estree",
|
|
||||||
"/eslint",
|
|
||||||
"/istanbul-lib-instrument"
|
|
||||||
],
|
|
||||||
"_resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
|
||||||
"_spec": "6.3.0",
|
|
||||||
"_where": "/Users/Yang/Desktop/Projects/android-emulator-runner",
|
|
||||||
"bin": {
|
"bin": {
|
||||||
"semver": "./bin/semver.js"
|
"semver": "./bin/semver.js"
|
||||||
},
|
},
|
||||||
"bugs": {
|
|
||||||
"url": "https://github.com/npm/node-semver/issues"
|
|
||||||
},
|
|
||||||
"description": "The semantic version parser used by npm.",
|
|
||||||
"devDependencies": {
|
|
||||||
"tap": "^14.3.1"
|
|
||||||
},
|
|
||||||
"files": [
|
"files": [
|
||||||
"bin",
|
"bin",
|
||||||
"range.bnf",
|
"range.bnf",
|
||||||
"semver.js"
|
"semver.js"
|
||||||
],
|
],
|
||||||
"homepage": "https://github.com/npm/node-semver#readme",
|
"author": "GitHub Inc.",
|
||||||
"license": "ISC",
|
"templateOSS": {
|
||||||
"main": "semver.js",
|
"//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
|
||||||
"name": "semver",
|
"content": "./scripts/template-oss",
|
||||||
"repository": {
|
"version": "4.17.0"
|
||||||
"type": "git",
|
}
|
||||||
"url": "git+https://github.com/npm/node-semver.git"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"postpublish": "git push origin --follow-tags",
|
|
||||||
"postversion": "npm publish",
|
|
||||||
"preversion": "npm test",
|
|
||||||
"test": "tap"
|
|
||||||
},
|
|
||||||
"tap": {
|
|
||||||
"check-coverage": true
|
|
||||||
},
|
|
||||||
"version": "6.3.0"
|
|
||||||
}
|
}
|
||||||
|
|||||||
+71
-24
@@ -26,8 +26,11 @@ var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER ||
|
|||||||
// Max safe segment length for coercion.
|
// Max safe segment length for coercion.
|
||||||
var MAX_SAFE_COMPONENT_LENGTH = 16
|
var MAX_SAFE_COMPONENT_LENGTH = 16
|
||||||
|
|
||||||
|
var MAX_SAFE_BUILD_LENGTH = MAX_LENGTH - 6
|
||||||
|
|
||||||
// The actual regexps go on exports.re
|
// The actual regexps go on exports.re
|
||||||
var re = exports.re = []
|
var re = exports.re = []
|
||||||
|
var safeRe = exports.safeRe = []
|
||||||
var src = exports.src = []
|
var src = exports.src = []
|
||||||
var t = exports.tokens = {}
|
var t = exports.tokens = {}
|
||||||
var R = 0
|
var R = 0
|
||||||
@@ -36,6 +39,31 @@ function tok (n) {
|
|||||||
t[n] = R++
|
t[n] = R++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var LETTERDASHNUMBER = '[a-zA-Z0-9-]'
|
||||||
|
|
||||||
|
// Replace some greedy regex tokens to prevent regex dos issues. These regex are
|
||||||
|
// used internally via the safeRe object since all inputs in this library get
|
||||||
|
// normalized first to trim and collapse all extra whitespace. The original
|
||||||
|
// regexes are exported for userland consumption and lower level usage. A
|
||||||
|
// future breaking change could export the safer regex only with a note that
|
||||||
|
// all input should have extra whitespace removed.
|
||||||
|
var safeRegexReplacements = [
|
||||||
|
['\\s', 1],
|
||||||
|
['\\d', MAX_LENGTH],
|
||||||
|
[LETTERDASHNUMBER, MAX_SAFE_BUILD_LENGTH],
|
||||||
|
]
|
||||||
|
|
||||||
|
function makeSafeRe (value) {
|
||||||
|
for (var i = 0; i < safeRegexReplacements.length; i++) {
|
||||||
|
var token = safeRegexReplacements[i][0]
|
||||||
|
var max = safeRegexReplacements[i][1]
|
||||||
|
value = value
|
||||||
|
.split(token + '*').join(token + '{0,' + max + '}')
|
||||||
|
.split(token + '+').join(token + '{1,' + max + '}')
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
// The following Regular Expressions can be used for tokenizing,
|
// The following Regular Expressions can be used for tokenizing,
|
||||||
// validating, and parsing SemVer version strings.
|
// validating, and parsing SemVer version strings.
|
||||||
|
|
||||||
@@ -45,14 +73,14 @@ function tok (n) {
|
|||||||
tok('NUMERICIDENTIFIER')
|
tok('NUMERICIDENTIFIER')
|
||||||
src[t.NUMERICIDENTIFIER] = '0|[1-9]\\d*'
|
src[t.NUMERICIDENTIFIER] = '0|[1-9]\\d*'
|
||||||
tok('NUMERICIDENTIFIERLOOSE')
|
tok('NUMERICIDENTIFIERLOOSE')
|
||||||
src[t.NUMERICIDENTIFIERLOOSE] = '[0-9]+'
|
src[t.NUMERICIDENTIFIERLOOSE] = '\\d+'
|
||||||
|
|
||||||
// ## Non-numeric Identifier
|
// ## Non-numeric Identifier
|
||||||
// Zero or more digits, followed by a letter or hyphen, and then zero or
|
// Zero or more digits, followed by a letter or hyphen, and then zero or
|
||||||
// more letters, digits, or hyphens.
|
// more letters, digits, or hyphens.
|
||||||
|
|
||||||
tok('NONNUMERICIDENTIFIER')
|
tok('NONNUMERICIDENTIFIER')
|
||||||
src[t.NONNUMERICIDENTIFIER] = '\\d*[a-zA-Z-][a-zA-Z0-9-]*'
|
src[t.NONNUMERICIDENTIFIER] = '\\d*[a-zA-Z-]' + LETTERDASHNUMBER + '*'
|
||||||
|
|
||||||
// ## Main Version
|
// ## Main Version
|
||||||
// Three dot-separated numeric identifiers.
|
// Three dot-separated numeric identifiers.
|
||||||
@@ -94,7 +122,7 @@ src[t.PRERELEASELOOSE] = '(?:-?(' + src[t.PRERELEASEIDENTIFIERLOOSE] +
|
|||||||
// Any combination of digits, letters, or hyphens.
|
// Any combination of digits, letters, or hyphens.
|
||||||
|
|
||||||
tok('BUILDIDENTIFIER')
|
tok('BUILDIDENTIFIER')
|
||||||
src[t.BUILDIDENTIFIER] = '[0-9A-Za-z-]+'
|
src[t.BUILDIDENTIFIER] = LETTERDASHNUMBER + '+'
|
||||||
|
|
||||||
// ## Build Metadata
|
// ## Build Metadata
|
||||||
// Plus sign, followed by one or more period-separated build metadata
|
// Plus sign, followed by one or more period-separated build metadata
|
||||||
@@ -174,6 +202,7 @@ src[t.COERCE] = '(^|[^\\d])' +
|
|||||||
'(?:$|[^\\d])'
|
'(?:$|[^\\d])'
|
||||||
tok('COERCERTL')
|
tok('COERCERTL')
|
||||||
re[t.COERCERTL] = new RegExp(src[t.COERCE], 'g')
|
re[t.COERCERTL] = new RegExp(src[t.COERCE], 'g')
|
||||||
|
safeRe[t.COERCERTL] = new RegExp(makeSafeRe(src[t.COERCE]), 'g')
|
||||||
|
|
||||||
// Tilde ranges.
|
// Tilde ranges.
|
||||||
// Meaning is "reasonably at or greater than"
|
// Meaning is "reasonably at or greater than"
|
||||||
@@ -183,6 +212,7 @@ src[t.LONETILDE] = '(?:~>?)'
|
|||||||
tok('TILDETRIM')
|
tok('TILDETRIM')
|
||||||
src[t.TILDETRIM] = '(\\s*)' + src[t.LONETILDE] + '\\s+'
|
src[t.TILDETRIM] = '(\\s*)' + src[t.LONETILDE] + '\\s+'
|
||||||
re[t.TILDETRIM] = new RegExp(src[t.TILDETRIM], 'g')
|
re[t.TILDETRIM] = new RegExp(src[t.TILDETRIM], 'g')
|
||||||
|
safeRe[t.TILDETRIM] = new RegExp(makeSafeRe(src[t.TILDETRIM]), 'g')
|
||||||
var tildeTrimReplace = '$1~'
|
var tildeTrimReplace = '$1~'
|
||||||
|
|
||||||
tok('TILDE')
|
tok('TILDE')
|
||||||
@@ -198,6 +228,7 @@ src[t.LONECARET] = '(?:\\^)'
|
|||||||
tok('CARETTRIM')
|
tok('CARETTRIM')
|
||||||
src[t.CARETTRIM] = '(\\s*)' + src[t.LONECARET] + '\\s+'
|
src[t.CARETTRIM] = '(\\s*)' + src[t.LONECARET] + '\\s+'
|
||||||
re[t.CARETTRIM] = new RegExp(src[t.CARETTRIM], 'g')
|
re[t.CARETTRIM] = new RegExp(src[t.CARETTRIM], 'g')
|
||||||
|
safeRe[t.CARETTRIM] = new RegExp(makeSafeRe(src[t.CARETTRIM]), 'g')
|
||||||
var caretTrimReplace = '$1^'
|
var caretTrimReplace = '$1^'
|
||||||
|
|
||||||
tok('CARET')
|
tok('CARET')
|
||||||
@@ -219,6 +250,7 @@ src[t.COMPARATORTRIM] = '(\\s*)' + src[t.GTLT] +
|
|||||||
|
|
||||||
// this one has to use the /g flag
|
// this one has to use the /g flag
|
||||||
re[t.COMPARATORTRIM] = new RegExp(src[t.COMPARATORTRIM], 'g')
|
re[t.COMPARATORTRIM] = new RegExp(src[t.COMPARATORTRIM], 'g')
|
||||||
|
safeRe[t.COMPARATORTRIM] = new RegExp(makeSafeRe(src[t.COMPARATORTRIM]), 'g')
|
||||||
var comparatorTrimReplace = '$1$2$3'
|
var comparatorTrimReplace = '$1$2$3'
|
||||||
|
|
||||||
// Something like `1.2.3 - 1.2.4`
|
// Something like `1.2.3 - 1.2.4`
|
||||||
@@ -247,6 +279,14 @@ for (var i = 0; i < R; i++) {
|
|||||||
debug(i, src[i])
|
debug(i, src[i])
|
||||||
if (!re[i]) {
|
if (!re[i]) {
|
||||||
re[i] = new RegExp(src[i])
|
re[i] = new RegExp(src[i])
|
||||||
|
|
||||||
|
// Replace all greedy whitespace to prevent regex dos issues. These regex are
|
||||||
|
// used internally via the safeRe object since all inputs in this library get
|
||||||
|
// normalized first to trim and collapse all extra whitespace. The original
|
||||||
|
// regexes are exported for userland consumption and lower level usage. A
|
||||||
|
// future breaking change could export the safer regex only with a note that
|
||||||
|
// all input should have extra whitespace removed.
|
||||||
|
safeRe[i] = new RegExp(makeSafeRe(src[i]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,7 +311,7 @@ function parse (version, options) {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
var r = options.loose ? re[t.LOOSE] : re[t.FULL]
|
var r = options.loose ? safeRe[t.LOOSE] : safeRe[t.FULL]
|
||||||
if (!r.test(version)) {
|
if (!r.test(version)) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@@ -326,7 +366,7 @@ function SemVer (version, options) {
|
|||||||
this.options = options
|
this.options = options
|
||||||
this.loose = !!options.loose
|
this.loose = !!options.loose
|
||||||
|
|
||||||
var m = version.trim().match(options.loose ? re[t.LOOSE] : re[t.FULL])
|
var m = version.trim().match(options.loose ? safeRe[t.LOOSE] : safeRe[t.FULL])
|
||||||
|
|
||||||
if (!m) {
|
if (!m) {
|
||||||
throw new TypeError('Invalid Version: ' + version)
|
throw new TypeError('Invalid Version: ' + version)
|
||||||
@@ -771,6 +811,7 @@ function Comparator (comp, options) {
|
|||||||
return new Comparator(comp, options)
|
return new Comparator(comp, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
comp = comp.trim().split(/\s+/).join(' ')
|
||||||
debug('comparator', comp, options)
|
debug('comparator', comp, options)
|
||||||
this.options = options
|
this.options = options
|
||||||
this.loose = !!options.loose
|
this.loose = !!options.loose
|
||||||
@@ -787,7 +828,7 @@ function Comparator (comp, options) {
|
|||||||
|
|
||||||
var ANY = {}
|
var ANY = {}
|
||||||
Comparator.prototype.parse = function (comp) {
|
Comparator.prototype.parse = function (comp) {
|
||||||
var r = this.options.loose ? re[t.COMPARATORLOOSE] : re[t.COMPARATOR]
|
var r = this.options.loose ? safeRe[t.COMPARATORLOOSE] : safeRe[t.COMPARATOR]
|
||||||
var m = comp.match(r)
|
var m = comp.match(r)
|
||||||
|
|
||||||
if (!m) {
|
if (!m) {
|
||||||
@@ -911,9 +952,16 @@ function Range (range, options) {
|
|||||||
this.loose = !!options.loose
|
this.loose = !!options.loose
|
||||||
this.includePrerelease = !!options.includePrerelease
|
this.includePrerelease = !!options.includePrerelease
|
||||||
|
|
||||||
// First, split based on boolean or ||
|
// First reduce all whitespace as much as possible so we do not have to rely
|
||||||
|
// on potentially slow regexes like \s*. This is then stored and used for
|
||||||
|
// future error messages as well.
|
||||||
this.raw = range
|
this.raw = range
|
||||||
this.set = range.split(/\s*\|\|\s*/).map(function (range) {
|
.trim()
|
||||||
|
.split(/\s+/)
|
||||||
|
.join(' ')
|
||||||
|
|
||||||
|
// First, split based on boolean or ||
|
||||||
|
this.set = this.raw.split('||').map(function (range) {
|
||||||
return this.parseRange(range.trim())
|
return this.parseRange(range.trim())
|
||||||
}, this).filter(function (c) {
|
}, this).filter(function (c) {
|
||||||
// throw out any that are not relevant for whatever reason
|
// throw out any that are not relevant for whatever reason
|
||||||
@@ -921,7 +969,7 @@ function Range (range, options) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if (!this.set.length) {
|
if (!this.set.length) {
|
||||||
throw new TypeError('Invalid SemVer Range: ' + range)
|
throw new TypeError('Invalid SemVer Range: ' + this.raw)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.format()
|
this.format()
|
||||||
@@ -940,20 +988,19 @@ Range.prototype.toString = function () {
|
|||||||
|
|
||||||
Range.prototype.parseRange = function (range) {
|
Range.prototype.parseRange = function (range) {
|
||||||
var loose = this.options.loose
|
var loose = this.options.loose
|
||||||
range = range.trim()
|
|
||||||
// `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4`
|
// `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4`
|
||||||
var hr = loose ? re[t.HYPHENRANGELOOSE] : re[t.HYPHENRANGE]
|
var hr = loose ? safeRe[t.HYPHENRANGELOOSE] : safeRe[t.HYPHENRANGE]
|
||||||
range = range.replace(hr, hyphenReplace)
|
range = range.replace(hr, hyphenReplace)
|
||||||
debug('hyphen replace', range)
|
debug('hyphen replace', range)
|
||||||
// `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5`
|
// `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5`
|
||||||
range = range.replace(re[t.COMPARATORTRIM], comparatorTrimReplace)
|
range = range.replace(safeRe[t.COMPARATORTRIM], comparatorTrimReplace)
|
||||||
debug('comparator trim', range, re[t.COMPARATORTRIM])
|
debug('comparator trim', range, safeRe[t.COMPARATORTRIM])
|
||||||
|
|
||||||
// `~ 1.2.3` => `~1.2.3`
|
// `~ 1.2.3` => `~1.2.3`
|
||||||
range = range.replace(re[t.TILDETRIM], tildeTrimReplace)
|
range = range.replace(safeRe[t.TILDETRIM], tildeTrimReplace)
|
||||||
|
|
||||||
// `^ 1.2.3` => `^1.2.3`
|
// `^ 1.2.3` => `^1.2.3`
|
||||||
range = range.replace(re[t.CARETTRIM], caretTrimReplace)
|
range = range.replace(safeRe[t.CARETTRIM], caretTrimReplace)
|
||||||
|
|
||||||
// normalize spaces
|
// normalize spaces
|
||||||
range = range.split(/\s+/).join(' ')
|
range = range.split(/\s+/).join(' ')
|
||||||
@@ -961,7 +1008,7 @@ Range.prototype.parseRange = function (range) {
|
|||||||
// At this point, the range is completely trimmed and
|
// At this point, the range is completely trimmed and
|
||||||
// ready to be split into comparators.
|
// ready to be split into comparators.
|
||||||
|
|
||||||
var compRe = loose ? re[t.COMPARATORLOOSE] : re[t.COMPARATOR]
|
var compRe = loose ? safeRe[t.COMPARATORLOOSE] : safeRe[t.COMPARATOR]
|
||||||
var set = range.split(' ').map(function (comp) {
|
var set = range.split(' ').map(function (comp) {
|
||||||
return parseComparator(comp, this.options)
|
return parseComparator(comp, this.options)
|
||||||
}, this).join(' ').split(/\s+/)
|
}, this).join(' ').split(/\s+/)
|
||||||
@@ -1061,7 +1108,7 @@ function replaceTildes (comp, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function replaceTilde (comp, options) {
|
function replaceTilde (comp, options) {
|
||||||
var r = options.loose ? re[t.TILDELOOSE] : re[t.TILDE]
|
var r = options.loose ? safeRe[t.TILDELOOSE] : safeRe[t.TILDE]
|
||||||
return comp.replace(r, function (_, M, m, p, pr) {
|
return comp.replace(r, function (_, M, m, p, pr) {
|
||||||
debug('tilde', comp, _, M, m, p, pr)
|
debug('tilde', comp, _, M, m, p, pr)
|
||||||
var ret
|
var ret
|
||||||
@@ -1102,7 +1149,7 @@ function replaceCarets (comp, options) {
|
|||||||
|
|
||||||
function replaceCaret (comp, options) {
|
function replaceCaret (comp, options) {
|
||||||
debug('caret', comp, options)
|
debug('caret', comp, options)
|
||||||
var r = options.loose ? re[t.CARETLOOSE] : re[t.CARET]
|
var r = options.loose ? safeRe[t.CARETLOOSE] : safeRe[t.CARET]
|
||||||
return comp.replace(r, function (_, M, m, p, pr) {
|
return comp.replace(r, function (_, M, m, p, pr) {
|
||||||
debug('caret', comp, _, M, m, p, pr)
|
debug('caret', comp, _, M, m, p, pr)
|
||||||
var ret
|
var ret
|
||||||
@@ -1161,7 +1208,7 @@ function replaceXRanges (comp, options) {
|
|||||||
|
|
||||||
function replaceXRange (comp, options) {
|
function replaceXRange (comp, options) {
|
||||||
comp = comp.trim()
|
comp = comp.trim()
|
||||||
var r = options.loose ? re[t.XRANGELOOSE] : re[t.XRANGE]
|
var r = options.loose ? safeRe[t.XRANGELOOSE] : safeRe[t.XRANGE]
|
||||||
return comp.replace(r, function (ret, gtlt, M, m, p, pr) {
|
return comp.replace(r, function (ret, gtlt, M, m, p, pr) {
|
||||||
debug('xRange', comp, ret, gtlt, M, m, p, pr)
|
debug('xRange', comp, ret, gtlt, M, m, p, pr)
|
||||||
var xM = isX(M)
|
var xM = isX(M)
|
||||||
@@ -1236,7 +1283,7 @@ function replaceXRange (comp, options) {
|
|||||||
function replaceStars (comp, options) {
|
function replaceStars (comp, options) {
|
||||||
debug('replaceStars', comp, options)
|
debug('replaceStars', comp, options)
|
||||||
// Looseness is ignored here. star is always as loose as it gets!
|
// Looseness is ignored here. star is always as loose as it gets!
|
||||||
return comp.trim().replace(re[t.STAR], '')
|
return comp.trim().replace(safeRe[t.STAR], '')
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function is passed to string.replace(re[t.HYPHENRANGE])
|
// This function is passed to string.replace(re[t.HYPHENRANGE])
|
||||||
@@ -1562,7 +1609,7 @@ function coerce (version, options) {
|
|||||||
|
|
||||||
var match = null
|
var match = null
|
||||||
if (!options.rtl) {
|
if (!options.rtl) {
|
||||||
match = version.match(re[t.COERCE])
|
match = version.match(safeRe[t.COERCE])
|
||||||
} else {
|
} else {
|
||||||
// Find the right-most coercible string that does not share
|
// Find the right-most coercible string that does not share
|
||||||
// a terminus with a more left-ward coercible string.
|
// a terminus with a more left-ward coercible string.
|
||||||
@@ -1573,17 +1620,17 @@ function coerce (version, options) {
|
|||||||
// Stop when we get a match that ends at the string end, since no
|
// Stop when we get a match that ends at the string end, since no
|
||||||
// coercible string can be more right-ward without the same terminus.
|
// coercible string can be more right-ward without the same terminus.
|
||||||
var next
|
var next
|
||||||
while ((next = re[t.COERCERTL].exec(version)) &&
|
while ((next = safeRe[t.COERCERTL].exec(version)) &&
|
||||||
(!match || match.index + match[0].length !== version.length)
|
(!match || match.index + match[0].length !== version.length)
|
||||||
) {
|
) {
|
||||||
if (!match ||
|
if (!match ||
|
||||||
next.index + next[0].length !== match.index + match[0].length) {
|
next.index + next[0].length !== match.index + match[0].length) {
|
||||||
match = next
|
match = next
|
||||||
}
|
}
|
||||||
re[t.COERCERTL].lastIndex = next.index + next[1].length + next[2].length
|
safeRe[t.COERCERTL].lastIndex = next.index + next[1].length + next[2].length
|
||||||
}
|
}
|
||||||
// leave it in a clean state
|
// leave it in a clean state
|
||||||
re[t.COERCERTL].lastIndex = -1
|
safeRe[t.COERCERTL].lastIndex = -1
|
||||||
}
|
}
|
||||||
|
|
||||||
if (match === null) {
|
if (match === null) {
|
||||||
|
|||||||
Generated
+2956
-1870
File diff suppressed because it is too large
Load Diff
+5
-2
@@ -2,7 +2,7 @@
|
|||||||
"name": "android-emulator-runner",
|
"name": "android-emulator-runner",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"description": "A GitHub Action for installing, configuring and running Android Emulators on macOS virtual machines.",
|
"description": "A GitHub Action for installing, configuring and running Android Emulators on hardware-accelerated runners.",
|
||||||
"main": "lib/main.js",
|
"main": "lib/main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc",
|
"build": "tsc",
|
||||||
@@ -18,6 +18,9 @@
|
|||||||
"node",
|
"node",
|
||||||
"setup"
|
"setup"
|
||||||
],
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20"
|
||||||
|
},
|
||||||
"author": "Reactive Circus",
|
"author": "Reactive Circus",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -29,7 +32,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "^29.2.0",
|
"@types/jest": "^29.2.0",
|
||||||
"@types/node": "^16.18.2",
|
"@types/node": "^20.11.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.41.0",
|
"@typescript-eslint/eslint-plugin": "^5.41.0",
|
||||||
"@typescript-eslint/parser": "^5.41.0",
|
"@typescript-eslint/parser": "^5.41.0",
|
||||||
"eslint": "^8.26.0",
|
"eslint": "^8.26.0",
|
||||||
|
|||||||
+20
-15
@@ -5,7 +5,7 @@ import * as fs from 'fs';
|
|||||||
* Creates and launches a new AVD instance with the specified configurations.
|
* Creates and launches a new AVD instance with the specified configurations.
|
||||||
*/
|
*/
|
||||||
export async function launchEmulator(
|
export async function launchEmulator(
|
||||||
apiLevel: string,
|
systemImageApiLevel: string,
|
||||||
target: string,
|
target: string,
|
||||||
arch: string,
|
arch: string,
|
||||||
profile: string,
|
profile: string,
|
||||||
@@ -17,6 +17,7 @@ export async function launchEmulator(
|
|||||||
avdName: string,
|
avdName: string,
|
||||||
forceAvdCreation: boolean,
|
forceAvdCreation: boolean,
|
||||||
emulatorBootTimeout: number,
|
emulatorBootTimeout: number,
|
||||||
|
port: number,
|
||||||
emulatorOptions: string,
|
emulatorOptions: string,
|
||||||
disableAnimations: boolean,
|
disableAnimations: boolean,
|
||||||
disableSpellChecker: boolean,
|
disableSpellChecker: boolean,
|
||||||
@@ -32,7 +33,7 @@ export async function launchEmulator(
|
|||||||
const sdcardPathOrSizeOption = sdcardPathOrSize.trim() !== '' ? `--sdcard '${sdcardPathOrSize}'` : '';
|
const sdcardPathOrSizeOption = sdcardPathOrSize.trim() !== '' ? `--sdcard '${sdcardPathOrSize}'` : '';
|
||||||
console.log(`Creating AVD.`);
|
console.log(`Creating AVD.`);
|
||||||
await exec.exec(
|
await exec.exec(
|
||||||
`sh -c \\"echo no | avdmanager create avd --force -n "${avdName}" --abi '${target}/${arch}' --package 'system-images;android-${apiLevel};${target};${arch}' ${profileOption} ${sdcardPathOrSizeOption}"`
|
`sh -c \\"echo no | avdmanager create avd --force -n "${avdName}" --abi '${target}/${arch}' --package 'system-images;android-${systemImageApiLevel};${target};${arch}' ${profileOption} ${sdcardPathOrSizeOption}"`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,7 +57,7 @@ export async function launchEmulator(
|
|||||||
await exec.exec(`sh -c \\"printf 'disk.dataPartition.size=${diskSize}\n' >> ${process.env.ANDROID_AVD_HOME}/"${avdName}".avd"/config.ini`);
|
await exec.exec(`sh -c \\"printf 'disk.dataPartition.size=${diskSize}\n' >> ${process.env.ANDROID_AVD_HOME}/"${avdName}".avd"/config.ini`);
|
||||||
}
|
}
|
||||||
|
|
||||||
//turn off hardware acceleration on Linux
|
// turn off hardware acceleration on Linux
|
||||||
if (process.platform === 'linux' && disableLinuxHardwareAcceleration) {
|
if (process.platform === 'linux' && disableLinuxHardwareAcceleration) {
|
||||||
console.log('Disabling Linux hardware acceleration.');
|
console.log('Disabling Linux hardware acceleration.');
|
||||||
emulatorOptions += ' -accel off';
|
emulatorOptions += ' -accel off';
|
||||||
@@ -65,7 +66,7 @@ export async function launchEmulator(
|
|||||||
// start emulator
|
// start emulator
|
||||||
console.log('Starting emulator.');
|
console.log('Starting emulator.');
|
||||||
|
|
||||||
await exec.exec(`sh -c \\"${process.env.ANDROID_HOME}/emulator/emulator -avd "${avdName}" ${emulatorOptions} &"`, [], {
|
await exec.exec(`sh -c \\"${process.env.ANDROID_HOME}/emulator/emulator -port ${port} -avd "${avdName}" ${emulatorOptions} &"`, [], {
|
||||||
listeners: {
|
listeners: {
|
||||||
stderr: (data: Buffer) => {
|
stderr: (data: Buffer) => {
|
||||||
if (data.toString().includes('invalid command-line parameter')) {
|
if (data.toString().includes('invalid command-line parameter')) {
|
||||||
@@ -76,20 +77,20 @@ export async function launchEmulator(
|
|||||||
});
|
});
|
||||||
|
|
||||||
// wait for emulator to complete booting
|
// wait for emulator to complete booting
|
||||||
await waitForDevice(emulatorBootTimeout);
|
await waitForDevice(port, emulatorBootTimeout);
|
||||||
await exec.exec(`adb shell input keyevent 82`);
|
await adb(port, `shell input keyevent 82`);
|
||||||
|
|
||||||
if (disableAnimations) {
|
if (disableAnimations) {
|
||||||
console.log('Disabling animations.');
|
console.log('Disabling animations.');
|
||||||
await exec.exec(`adb shell settings put global window_animation_scale 0.0`);
|
await adb(port, `shell settings put global window_animation_scale 0.0`);
|
||||||
await exec.exec(`adb shell settings put global transition_animation_scale 0.0`);
|
await adb(port, `shell settings put global transition_animation_scale 0.0`);
|
||||||
await exec.exec(`adb shell settings put global animator_duration_scale 0.0`);
|
await adb(port, `shell settings put global animator_duration_scale 0.0`);
|
||||||
}
|
}
|
||||||
if (disableSpellChecker) {
|
if (disableSpellChecker) {
|
||||||
await exec.exec(`adb shell settings put secure spell_checker_enabled 0`);
|
await adb(port, `shell settings put secure spell_checker_enabled 0`);
|
||||||
}
|
}
|
||||||
if (enableHardwareKeyboard) {
|
if (enableHardwareKeyboard) {
|
||||||
await exec.exec(`adb shell settings put secure show_ime_with_hard_keyboard 0`);
|
await adb(port, `shell settings put secure show_ime_with_hard_keyboard 0`);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
console.log(`::endgroup::`);
|
console.log(`::endgroup::`);
|
||||||
@@ -99,10 +100,10 @@ export async function launchEmulator(
|
|||||||
/**
|
/**
|
||||||
* Kills the running emulator on the default port.
|
* Kills the running emulator on the default port.
|
||||||
*/
|
*/
|
||||||
export async function killEmulator(): Promise<void> {
|
export async function killEmulator(port: number): Promise<void> {
|
||||||
try {
|
try {
|
||||||
console.log(`::group::Terminate Emulator`);
|
console.log(`::group::Terminate Emulator`);
|
||||||
await exec.exec(`adb -s emulator-5554 emu kill`);
|
await adb(port, `emu kill`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error instanceof Error ? error.message : error);
|
console.log(error instanceof Error ? error.message : error);
|
||||||
} finally {
|
} finally {
|
||||||
@@ -110,10 +111,14 @@ export async function killEmulator(): Promise<void> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function adb(port: number, command: string): Promise<number> {
|
||||||
|
return await exec.exec(`adb -s emulator-${port} ${command}`);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wait for emulator to boot.
|
* Wait for emulator to boot.
|
||||||
*/
|
*/
|
||||||
async function waitForDevice(emulatorBootTimeout: number): Promise<void> {
|
async function waitForDevice(port: number, emulatorBootTimeout: number): Promise<void> {
|
||||||
let booted = false;
|
let booted = false;
|
||||||
let attempts = 0;
|
let attempts = 0;
|
||||||
const retryInterval = 2; // retry every 2 seconds
|
const retryInterval = 2; // retry every 2 seconds
|
||||||
@@ -121,7 +126,7 @@ async function waitForDevice(emulatorBootTimeout: number): Promise<void> {
|
|||||||
while (!booted) {
|
while (!booted) {
|
||||||
try {
|
try {
|
||||||
let result = '';
|
let result = '';
|
||||||
await exec.exec(`adb shell getprop sys.boot_completed`, [], {
|
await exec.exec(`adb -s emulator-${port} shell getprop sys.boot_completed`, [], {
|
||||||
listeners: {
|
listeners: {
|
||||||
stdout: (data: Buffer) => {
|
stdout: (data: Buffer) => {
|
||||||
result += data.toString();
|
result += data.toString();
|
||||||
|
|||||||
+25
-11
@@ -1,17 +1,22 @@
|
|||||||
export const MIN_API_LEVEL = 15;
|
export const MIN_API_LEVEL = 15;
|
||||||
export const VALID_TARGETS: Array<string> = ['default', 'google_apis', 'aosp_atd', 'google_atd', 'google_apis_playstore', 'android-wear', 'android-wear-cn', 'android-tv', 'google-tv'];
|
export const VALID_TARGETS: Array<string> = [
|
||||||
|
'default',
|
||||||
|
'google_apis',
|
||||||
|
'aosp_atd',
|
||||||
|
'google_atd',
|
||||||
|
'google_apis_playstore',
|
||||||
|
'android-wear',
|
||||||
|
'android-wear-cn',
|
||||||
|
'android-tv',
|
||||||
|
'google-tv',
|
||||||
|
'android-automotive',
|
||||||
|
'android-automotive-playstore',
|
||||||
|
'android-desktop',
|
||||||
|
];
|
||||||
export const VALID_ARCHS: Array<string> = ['x86', 'x86_64', 'arm64-v8a'];
|
export const VALID_ARCHS: Array<string> = ['x86', 'x86_64', 'arm64-v8a'];
|
||||||
export const VALID_CHANNELS: Array<string> = ['stable', 'beta', 'dev', 'canary'];
|
export const VALID_CHANNELS: Array<string> = ['stable', 'beta', 'dev', 'canary'];
|
||||||
|
export const MIN_PORT = 5554;
|
||||||
export function checkApiLevel(apiLevel: string): void {
|
export const MAX_PORT = 5584;
|
||||||
if (apiLevel.startsWith('UpsideDownCake') || apiLevel === 'TiramisuPrivacySandbox') return;
|
|
||||||
if (isNaN(Number(apiLevel)) || !Number.isInteger(Number(apiLevel))) {
|
|
||||||
throw new Error(`Unexpected API level: '${apiLevel}'.`);
|
|
||||||
}
|
|
||||||
if (Number(apiLevel) < MIN_API_LEVEL) {
|
|
||||||
throw new Error(`Minimum API level supported is ${MIN_API_LEVEL}.`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function checkTarget(target: string): void {
|
export function checkTarget(target: string): void {
|
||||||
if (!VALID_TARGETS.includes(target)) {
|
if (!VALID_TARGETS.includes(target)) {
|
||||||
@@ -37,6 +42,15 @@ export function checkForceAvdCreation(forceAvdCreation: string): void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function checkPort(port: number): void {
|
||||||
|
if (port < MIN_PORT || port > MAX_PORT) {
|
||||||
|
throw new Error(`Emulator port is outside of the supported port range [${MIN_PORT}, ${MAX_PORT}], was ${port}`);
|
||||||
|
}
|
||||||
|
if (port % 2 == 1) {
|
||||||
|
throw new Error(`Emulator port has to be even, was ${port}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function checkDisableAnimations(disableAnimations: string): void {
|
export function checkDisableAnimations(disableAnimations: string): void {
|
||||||
if (!isValidBoolean(disableAnimations)) {
|
if (!isValidBoolean(disableAnimations)) {
|
||||||
throw new Error(`Input for input.disable-animations should be either 'true' or 'false'.`);
|
throw new Error(`Input for input.disable-animations should be either 'true' or 'false'.`);
|
||||||
|
|||||||
+22
-7
@@ -1,7 +1,6 @@
|
|||||||
import * as core from '@actions/core';
|
import * as core from '@actions/core';
|
||||||
import { installAndroidSdk } from './sdk-installer';
|
import { installAndroidSdk } from './sdk-installer';
|
||||||
import {
|
import {
|
||||||
checkApiLevel,
|
|
||||||
checkTarget,
|
checkTarget,
|
||||||
checkArch,
|
checkArch,
|
||||||
checkDisableAnimations,
|
checkDisableAnimations,
|
||||||
@@ -12,6 +11,8 @@ import {
|
|||||||
checkChannel,
|
checkChannel,
|
||||||
checkEnableHardwareKeyboard,
|
checkEnableHardwareKeyboard,
|
||||||
checkDiskSize,
|
checkDiskSize,
|
||||||
|
checkPort,
|
||||||
|
MIN_PORT,
|
||||||
} from './input-validator';
|
} from './input-validator';
|
||||||
import { launchEmulator, killEmulator } from './emulator-manager';
|
import { launchEmulator, killEmulator } from './emulator-manager';
|
||||||
import * as exec from '@actions/exec';
|
import * as exec from '@actions/exec';
|
||||||
@@ -20,6 +21,7 @@ import { getChannelId } from './channel-id-mapper';
|
|||||||
import { accessSync, constants } from 'fs';
|
import { accessSync, constants } from 'fs';
|
||||||
|
|
||||||
async function run() {
|
async function run() {
|
||||||
|
let port: number = MIN_PORT;
|
||||||
try {
|
try {
|
||||||
console.log(`::group::Configure emulator`);
|
console.log(`::group::Configure emulator`);
|
||||||
let linuxSupportKVM = false;
|
let linuxSupportKVM = false;
|
||||||
@@ -41,9 +43,14 @@ async function run() {
|
|||||||
|
|
||||||
// API level of the platform and system image
|
// API level of the platform and system image
|
||||||
const apiLevel = core.getInput('api-level', { required: true });
|
const apiLevel = core.getInput('api-level', { required: true });
|
||||||
checkApiLevel(apiLevel);
|
|
||||||
console.log(`API level: ${apiLevel}`);
|
console.log(`API level: ${apiLevel}`);
|
||||||
|
|
||||||
|
let systemImageApiLevel = core.getInput('system-image-api-level');
|
||||||
|
if (!systemImageApiLevel) {
|
||||||
|
systemImageApiLevel = apiLevel;
|
||||||
|
}
|
||||||
|
console.log(`System image API level: ${systemImageApiLevel}`);
|
||||||
|
|
||||||
// target of the system image
|
// target of the system image
|
||||||
const targetInput = core.getInput('target');
|
const targetInput = core.getInput('target');
|
||||||
const target = targetInput == 'playstore' ? 'google_apis_playstore' : targetInput;
|
const target = targetInput == 'playstore' ? 'google_apis_playstore' : targetInput;
|
||||||
@@ -93,6 +100,11 @@ async function run() {
|
|||||||
const emulatorBootTimeout = parseInt(core.getInput('emulator-boot-timeout'), 10);
|
const emulatorBootTimeout = parseInt(core.getInput('emulator-boot-timeout'), 10);
|
||||||
console.log(`Emulator boot timeout: ${emulatorBootTimeout}`);
|
console.log(`Emulator boot timeout: ${emulatorBootTimeout}`);
|
||||||
|
|
||||||
|
// Emulator port to use
|
||||||
|
port = parseInt(core.getInput('emulator-port'), 10);
|
||||||
|
checkPort(port);
|
||||||
|
console.log(`emulator port: ${port}`);
|
||||||
|
|
||||||
// emulator options
|
// emulator options
|
||||||
const emulatorOptions = core.getInput('emulator-options').trim();
|
const emulatorOptions = core.getInput('emulator-options').trim();
|
||||||
console.log(`emulator options: ${emulatorOptions}`);
|
console.log(`emulator options: ${emulatorOptions}`);
|
||||||
@@ -177,7 +189,7 @@ async function run() {
|
|||||||
console.log(`::endgroup::`);
|
console.log(`::endgroup::`);
|
||||||
|
|
||||||
// install SDK
|
// install SDK
|
||||||
await installAndroidSdk(apiLevel, target, arch, channelId, emulatorBuild, ndkVersion, cmakeVersion);
|
await installAndroidSdk(apiLevel, systemImageApiLevel, target, arch, channelId, emulatorBuild, ndkVersion, cmakeVersion);
|
||||||
|
|
||||||
// execute pre emulator launch script if set
|
// execute pre emulator launch script if set
|
||||||
if (preEmulatorLaunchScripts !== undefined) {
|
if (preEmulatorLaunchScripts !== undefined) {
|
||||||
@@ -198,7 +210,7 @@ async function run() {
|
|||||||
|
|
||||||
// launch an emulator
|
// launch an emulator
|
||||||
await launchEmulator(
|
await launchEmulator(
|
||||||
apiLevel,
|
systemImageApiLevel,
|
||||||
target,
|
target,
|
||||||
arch,
|
arch,
|
||||||
profile,
|
profile,
|
||||||
@@ -210,6 +222,7 @@ async function run() {
|
|||||||
avdName,
|
avdName,
|
||||||
forceAvdCreation,
|
forceAvdCreation,
|
||||||
emulatorBootTimeout,
|
emulatorBootTimeout,
|
||||||
|
port,
|
||||||
emulatorOptions,
|
emulatorOptions,
|
||||||
disableAnimations,
|
disableAnimations,
|
||||||
disableSpellchecker,
|
disableSpellchecker,
|
||||||
@@ -226,17 +239,19 @@ async function run() {
|
|||||||
for (const script of scripts) {
|
for (const script of scripts) {
|
||||||
// use array form to avoid various quote escaping problems
|
// use array form to avoid various quote escaping problems
|
||||||
// caused by exec(`sh -c "${script}"`)
|
// caused by exec(`sh -c "${script}"`)
|
||||||
await exec.exec('sh', ['-c', script]);
|
await exec.exec('sh', ['-c', script], {
|
||||||
|
env: { ...process.env, EMULATOR_PORT: `${port}`, ANDROID_SERIAL: `emulator-${port}` },
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
core.setFailed(error instanceof Error ? error.message : (error as string));
|
core.setFailed(error instanceof Error ? error.message : (error as string));
|
||||||
}
|
}
|
||||||
|
|
||||||
// finally kill the emulator
|
// finally kill the emulator
|
||||||
await killEmulator();
|
await killEmulator(port);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// kill the emulator so the action can exit
|
// kill the emulator so the action can exit
|
||||||
await killEmulator();
|
await killEmulator(port);
|
||||||
core.setFailed(error instanceof Error ? error.message : (error as string));
|
core.setFailed(error instanceof Error ? error.message : (error as string));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+31
-12
@@ -4,23 +4,29 @@ import * as io from '@actions/io';
|
|||||||
import * as tc from '@actions/tool-cache';
|
import * as tc from '@actions/tool-cache';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
|
|
||||||
const BUILD_TOOLS_VERSION = '33.0.2';
|
const BUILD_TOOLS_VERSION = '35.0.0';
|
||||||
// SDK command-line tools 9.0
|
// SDK command-line tools 16.0
|
||||||
const CMDLINE_TOOLS_URL_MAC = 'https://dl.google.com/android/repository/commandlinetools-mac-9477386_latest.zip';
|
const CMDLINE_TOOLS_URL_MAC = 'https://dl.google.com/android/repository/commandlinetools-mac-12266719_latest.zip';
|
||||||
const CMDLINE_TOOLS_URL_LINUX = 'https://dl.google.com/android/repository/commandlinetools-linux-9477386_latest.zip';
|
const CMDLINE_TOOLS_URL_LINUX = 'https://dl.google.com/android/repository/commandlinetools-linux-12266719_latest.zip';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Installs & updates the Android SDK for the macOS platform, including SDK platform for the chosen API level, latest build tools, platform tools, Android Emulator,
|
* Installs & updates the Android SDK for the macOS platform, including SDK platform for the chosen API level, latest build tools, platform tools, Android Emulator,
|
||||||
* and the system image for the chosen API level, CPU arch, and target.
|
* and the system image for the chosen API level, CPU arch, and target.
|
||||||
*/
|
*/
|
||||||
export async function installAndroidSdk(apiLevel: string, target: string, arch: string, channelId: number, emulatorBuild?: string, ndkVersion?: string, cmakeVersion?: string): Promise<void> {
|
export async function installAndroidSdk(
|
||||||
|
apiLevel: string,
|
||||||
|
systemImageApiLevel: String,
|
||||||
|
target: string,
|
||||||
|
arch: string,
|
||||||
|
channelId: number,
|
||||||
|
emulatorBuild?: string,
|
||||||
|
ndkVersion?: string,
|
||||||
|
cmakeVersion?: string
|
||||||
|
): Promise<void> {
|
||||||
try {
|
try {
|
||||||
console.log(`::group::Install Android SDK`);
|
console.log(`::group::Install Android SDK`);
|
||||||
const isOnMac = process.platform === 'darwin';
|
const isOnMac = process.platform === 'darwin';
|
||||||
|
const isArm = process.arch === 'arm64';
|
||||||
if (!isOnMac) {
|
|
||||||
await exec.exec(`sh -c \\"sudo chown $USER:$USER ${process.env.ANDROID_HOME} -R`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const cmdlineToolsPath = `${process.env.ANDROID_HOME}/cmdline-tools`;
|
const cmdlineToolsPath = `${process.env.ANDROID_HOME}/cmdline-tools`;
|
||||||
if (!fs.existsSync(cmdlineToolsPath)) {
|
if (!fs.existsSync(cmdlineToolsPath)) {
|
||||||
@@ -35,6 +41,7 @@ export async function installAndroidSdk(apiLevel: string, target: string, arch:
|
|||||||
core.addPath(`${cmdlineToolsPath}/latest:${cmdlineToolsPath}/latest/bin:${process.env.ANDROID_HOME}/platform-tools`);
|
core.addPath(`${cmdlineToolsPath}/latest:${cmdlineToolsPath}/latest/bin:${process.env.ANDROID_HOME}/platform-tools`);
|
||||||
|
|
||||||
// set standard AVD path
|
// set standard AVD path
|
||||||
|
await io.mkdirP(`${process.env.HOME}/.android/avd`);
|
||||||
core.exportVariable('ANDROID_AVD_HOME', `${process.env.HOME}/.android/avd`);
|
core.exportVariable('ANDROID_AVD_HOME', `${process.env.HOME}/.android/avd`);
|
||||||
|
|
||||||
// accept all Android SDK licenses
|
// accept all Android SDK licenses
|
||||||
@@ -42,7 +49,7 @@ export async function installAndroidSdk(apiLevel: string, target: string, arch:
|
|||||||
|
|
||||||
console.log('Installing latest build tools, platform tools, and platform.');
|
console.log('Installing latest build tools, platform tools, and platform.');
|
||||||
|
|
||||||
await exec.exec(`sh -c \\"sdkmanager --install 'build-tools;${BUILD_TOOLS_VERSION}' platform-tools > /dev/null"`);
|
await exec.exec(`sh -c \\"sdkmanager --install 'build-tools;${BUILD_TOOLS_VERSION}' platform-tools 'platforms;android-${apiLevel}'> /dev/null"`);
|
||||||
|
|
||||||
console.log('Installing latest emulator.');
|
console.log('Installing latest emulator.');
|
||||||
await exec.exec(`sh -c \\"sdkmanager --install emulator --channel=${channelId} > /dev/null"`);
|
await exec.exec(`sh -c \\"sdkmanager --install emulator --channel=${channelId} > /dev/null"`);
|
||||||
@@ -50,13 +57,25 @@ export async function installAndroidSdk(apiLevel: string, target: string, arch:
|
|||||||
if (emulatorBuild) {
|
if (emulatorBuild) {
|
||||||
console.log(`Installing emulator build ${emulatorBuild}.`);
|
console.log(`Installing emulator build ${emulatorBuild}.`);
|
||||||
// TODO find out the correct download URLs for all build ids
|
// TODO find out the correct download URLs for all build ids
|
||||||
const downloadUrlSuffix = Number(emulatorBuild.charAt(0)) > 6 ? `_x64-${emulatorBuild}` : `-${emulatorBuild}`;
|
var downloadUrlSuffix: string;
|
||||||
|
const majorBuildVersion = Number(emulatorBuild);
|
||||||
|
if (majorBuildVersion >= 8000000) {
|
||||||
|
if (isArm) {
|
||||||
|
downloadUrlSuffix = `_aarch64-${emulatorBuild}`;
|
||||||
|
} else {
|
||||||
|
downloadUrlSuffix = `_x64-${emulatorBuild}`;
|
||||||
|
}
|
||||||
|
} else if (majorBuildVersion >= 7000000) {
|
||||||
|
downloadUrlSuffix = `_x64-${emulatorBuild}`;
|
||||||
|
} else {
|
||||||
|
downloadUrlSuffix = `-${emulatorBuild}`;
|
||||||
|
}
|
||||||
await exec.exec(`curl -fo emulator.zip https://dl.google.com/android/repository/emulator-${isOnMac ? 'darwin' : 'linux'}${downloadUrlSuffix}.zip`);
|
await exec.exec(`curl -fo emulator.zip https://dl.google.com/android/repository/emulator-${isOnMac ? 'darwin' : 'linux'}${downloadUrlSuffix}.zip`);
|
||||||
await exec.exec(`unzip -o -q emulator.zip -d ${process.env.ANDROID_HOME}`);
|
await exec.exec(`unzip -o -q emulator.zip -d ${process.env.ANDROID_HOME}`);
|
||||||
await io.rmRF('emulator.zip');
|
await io.rmRF('emulator.zip');
|
||||||
}
|
}
|
||||||
console.log('Installing system images.');
|
console.log('Installing system images.');
|
||||||
await exec.exec(`sh -c \\"sdkmanager --install 'system-images;android-${apiLevel};${target};${arch}' --channel=${channelId} > /dev/null"`);
|
await exec.exec(`sh -c \\"sdkmanager --install 'system-images;android-${systemImageApiLevel};${target};${arch}' --channel=${channelId} > /dev/null"`);
|
||||||
|
|
||||||
if (ndkVersion) {
|
if (ndkVersion) {
|
||||||
console.log(`Installing NDK ${ndkVersion}.`);
|
console.log(`Installing NDK ${ndkVersion}.`);
|
||||||
|
|||||||
@@ -2,13 +2,15 @@ apply plugin: 'com.android.application'
|
|||||||
apply plugin: 'kotlin-android'
|
apply plugin: 'kotlin-android'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 33
|
namespace = "com.example.testapp"
|
||||||
buildToolsVersion "33.0.2"
|
|
||||||
|
compileSdkVersion 35
|
||||||
|
buildToolsVersion "35.0.0"
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "com.example.testapp"
|
applicationId "com.example.testapp"
|
||||||
minSdkVersion 15
|
minSdkVersion 21
|
||||||
targetSdkVersion 33
|
targetSdkVersion 35
|
||||||
versionCode 1
|
versionCode 1
|
||||||
versionName "1.0"
|
versionName "1.0"
|
||||||
|
|
||||||
@@ -28,8 +30,7 @@ tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
implementation 'androidx.appcompat:appcompat:1.7.0'
|
||||||
implementation 'androidx.appcompat:appcompat:1.6.1'
|
androidTestImplementation 'androidx.test.ext:junit:1.2.1'
|
||||||
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'
|
||||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
package="com.example.testapp">
|
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ buildscript {
|
|||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:7.4.2'
|
classpath 'com.android.tools.build:gradle:8.7.0'
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.10"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:2.0.20"
|
||||||
|
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
// in the individual module build.gradle files
|
// in the individual module build.gradle files
|
||||||
|
|||||||
@@ -2,9 +2,6 @@ org.gradle.parallel=true
|
|||||||
org.gradle.configureondemand=true
|
org.gradle.configureondemand=true
|
||||||
org.gradle.caching=true
|
org.gradle.caching=true
|
||||||
|
|
||||||
# Enable parallel tasks execution for Kotlin Gradle plugin
|
|
||||||
kotlin.parallel.tasks.in.project=true
|
|
||||||
|
|
||||||
# Kotlin code style
|
# Kotlin code style
|
||||||
kotlin.code.style=official
|
kotlin.code.style=official
|
||||||
|
|
||||||
|
|||||||
BIN
Binary file not shown.
+2
-1
@@ -1,6 +1,7 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
|
||||||
networkTimeout=10000
|
networkTimeout=10000
|
||||||
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|||||||
Vendored
+17
-12
@@ -83,10 +83,8 @@ done
|
|||||||
# This is normally unused
|
# This is normally unused
|
||||||
# shellcheck disable=SC2034
|
# shellcheck disable=SC2034
|
||||||
APP_BASE_NAME=${0##*/}
|
APP_BASE_NAME=${0##*/}
|
||||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||||
|
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
|
||||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
|
||||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
|
||||||
|
|
||||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
MAX_FD=maximum
|
MAX_FD=maximum
|
||||||
@@ -133,10 +131,13 @@ location of your Java installation."
|
|||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
JAVACMD=java
|
JAVACMD=java
|
||||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
if ! command -v java >/dev/null 2>&1
|
||||||
|
then
|
||||||
|
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
Please set the JAVA_HOME variable in your environment to match the
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
location of your Java installation."
|
location of your Java installation."
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Increase the maximum file descriptors if we can.
|
# Increase the maximum file descriptors if we can.
|
||||||
@@ -144,7 +145,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
|||||||
case $MAX_FD in #(
|
case $MAX_FD in #(
|
||||||
max*)
|
max*)
|
||||||
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||||
# shellcheck disable=SC3045
|
# shellcheck disable=SC2039,SC3045
|
||||||
MAX_FD=$( ulimit -H -n ) ||
|
MAX_FD=$( ulimit -H -n ) ||
|
||||||
warn "Could not query maximum file descriptor limit"
|
warn "Could not query maximum file descriptor limit"
|
||||||
esac
|
esac
|
||||||
@@ -152,7 +153,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
|||||||
'' | soft) :;; #(
|
'' | soft) :;; #(
|
||||||
*)
|
*)
|
||||||
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||||
# shellcheck disable=SC3045
|
# shellcheck disable=SC2039,SC3045
|
||||||
ulimit -n "$MAX_FD" ||
|
ulimit -n "$MAX_FD" ||
|
||||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||||
esac
|
esac
|
||||||
@@ -197,11 +198,15 @@ if "$cygwin" || "$msys" ; then
|
|||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Collect all arguments for the java command;
|
|
||||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
# shell script including quotes and variable substitutions, so put them in
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
# double quotes to make sure that they get re-expanded; and
|
|
||||||
# * put everything else in single quotes, so that it's not re-expanded.
|
# Collect all arguments for the java command:
|
||||||
|
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||||
|
# and any embedded shellness will be escaped.
|
||||||
|
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
||||||
|
# treated as '${Hostname}' itself on the command line.
|
||||||
|
|
||||||
set -- \
|
set -- \
|
||||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||||
|
|||||||
Reference in New Issue
Block a user