├── sonar-project.properties ├── .babelrc ├── .github ├── dependabot.yml ├── graalvm.json ├── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md └── workflows │ └── ci.yaml ├── .gitignore ├── src ├── setup-graalvm.js ├── installer.test.js └── installer.js ├── action.yaml ├── LICENSE ├── .eslintrc ├── package.json ├── README.md └── dist └── index.js /sonar-project.properties: -------------------------------------------------------------------------------- 1 | sonar.organization = ayltai 2 | sonar.projectKey = ayltai_setup-graalvm 3 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "@babel/preset-env" 4 | ], 5 | "plugins" : [ 6 | "@babel/plugin-transform-runtime" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: github-actions 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | timezone: Asia/Manila 8 | open-pull-requests-limit: 99 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # macOS 2 | .DS_Store 3 | 4 | # Windows 5 | $RECYCLE.BIN/ 6 | Thumbs.db 7 | [Dd]esktop.ini 8 | *.lnk 9 | 10 | # JetBrains 11 | .idea/ 12 | *.iml 13 | 14 | # Node.js 15 | !node_modules/ 16 | 17 | # Coverage 18 | coverage/ 19 | 20 | # Generated 21 | cache/ 22 | temp/ 23 | *.log* 24 | -------------------------------------------------------------------------------- /.github/graalvm.json: -------------------------------------------------------------------------------- 1 | { 2 | "problemMatcher" : [ 3 | { 4 | "owner" : "graalvm", 5 | "pattern" : [ 6 | { 7 | "regexp" : "^Exception in thread \"(.*)\" (.*): (.*)$", 8 | "code" : 2, 9 | "message" : 3 10 | } 11 | ] 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /src/setup-graalvm.js: -------------------------------------------------------------------------------- 1 | import { getInput, setFailed, } from '@actions/core'; 2 | import { join, } from 'path'; 3 | 4 | import { getGraalVM, getNativeImage, } from './installer'; 5 | 6 | const run = async () => { 7 | try { 8 | await getGraalVM(getInput('java-version', { 9 | required : true, 10 | }), getInput('graalvm-version', { 11 | required : true, 12 | })); 13 | 14 | if (getInput('native-image')) await getNativeImage(); 15 | 16 | console.log(`##[add-matcher]${join(join(__dirname, '..', '.github'), 'graalvm.json')}`); 17 | } catch (error) { 18 | setFailed(error); 19 | } 20 | }; 21 | 22 | run(); 23 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: 'enhancement' 6 | assignees: 'ayltai' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /action.yaml: -------------------------------------------------------------------------------- 1 | name: Setup GraalVM action 2 | description: Set up a specific version of GraalVM and add the command line tools to PATH 3 | author: Alan Tai 4 | branding: 5 | icon: box 6 | color: orange 7 | inputs: 8 | java-version: 9 | description: The JDK version to be installed with GraalVM. E.g. 8, 11. See https://github.com/graalvm/graalvm-ce-builds/releases 10 | graalvm-version: 11 | description: The version of GraalVM to make available on PATH. E.g. 20.1.0, 19.3.2. See https://github.com/graalvm/graalvm-ce-builds/releases 12 | required: true 13 | native-image: 14 | description: Install GraalVM Native Image 15 | required: false 16 | default: false 17 | runs: 18 | using: node12 19 | main: dist/index.js 20 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: 'bug' 6 | assignees: 'ayltai' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '...' 17 | 3. Scroll down to '...' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. macOS] 28 | - Version [e.g. 10.15.5] 29 | 30 | **Additional context** 31 | Add any other context about the problem here. 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020-2021 Alan Tai 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: [push] 3 | jobs: 4 | checkstyle: 5 | runs-on: ubuntu-20.04 6 | steps: 7 | - name: Git checkout 8 | uses: actions/checkout@v3 9 | - name: Set up Node.js 10 | uses: actions/setup-node@v3 11 | with: 12 | node-version: 12 13 | - name: Install dependencies 14 | run: npm i 15 | - name: Run ESLint 16 | run: npm run check 17 | test-linux: 18 | runs-on: ubuntu-20.04 19 | steps: 20 | - name: Git checkout 21 | uses: actions/checkout@v3 22 | - name: Set up Node.js 23 | uses: actions/setup-node@v3 24 | with: 25 | node-version: 12 26 | - name: Install dependencies 27 | run: npm i 28 | - name: Run tests 29 | run: npm test 30 | - name: Upload coverage report to Codecov 31 | run: npm run codecov 32 | env: 33 | CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} 34 | - name: Run SonarCloud scanner 35 | uses: sonarsource/sonarcloud-github-action@master 36 | env: 37 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 38 | SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} 39 | test-macOS: 40 | runs-on: macos-latest 41 | steps: 42 | - name: Git checkout 43 | uses: actions/checkout@v3 44 | - name: Set up Node.js 45 | uses: actions/setup-node@v3 46 | with: 47 | node-version: 12 48 | - name: Install dependencies 49 | run: npm i 50 | - name: Run tests 51 | run: npm test 52 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends" : [ 3 | "eslint:recommended", 4 | "plugin:import/errors", 5 | "plugin:import/warnings" 6 | ], 7 | "env" : { 8 | "es6" : true, 9 | "node" : true 10 | }, 11 | "globals" : { 12 | "Atomics" : "readonly", 13 | "SharedArrayBuffer" : "readonly" 14 | }, 15 | "parser" : "babel-eslint", 16 | "parserOptions" : { 17 | "ecmaVersion" : 2019, 18 | "sourceType" : "module" 19 | }, 20 | "plugins" : [ 21 | "async-await", 22 | "es6-recommended", 23 | "import", 24 | "node", 25 | "standard" 26 | ], 27 | "rules" : { 28 | "array-bracket-spacing" : [ 29 | "error", 30 | "always" 31 | ], 32 | "comma-dangle" : [ 33 | "error", 34 | { 35 | "arrays" : "always", 36 | "exports" : "always", 37 | "functions" : "never", 38 | "imports" : "always", 39 | "objects" : "always" 40 | } 41 | ], 42 | "indent" : [ 43 | "error", 44 | 4, 45 | { 46 | "SwitchCase" : 1 47 | } 48 | ], 49 | "key-spacing" : "off", 50 | "linebreak-style" : [ 51 | "error", 52 | "unix" 53 | ], 54 | "no-multi-spaces" : "off", 55 | "no-undef" : "off", 56 | "quotes" : [ 57 | "error", 58 | "single" 59 | ], 60 | "semi" : [ 61 | "error", 62 | "always" 63 | ] 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "setup-graalvm", 3 | "version": "1.0.0", 4 | "description": "Setup GraalVM action", 5 | "author": "Alan Tai", 6 | "repository": { 7 | "type": "git", 8 | "url": "git+https://github.com/ayltai/setup-graalvm" 9 | }, 10 | "bugs": { 11 | "url": "https://github.com/ayltai/setup-graalvm/issues" 12 | }, 13 | "license": "MIT", 14 | "keywords": [ 15 | "github", 16 | "actions", 17 | "setup", 18 | "graal", 19 | "graalvm" 20 | ], 21 | "main": "dist/index.js", 22 | "scripts": { 23 | "build": "ncc build src/setup-graalvm.js", 24 | "check": "eslint src/*.js", 25 | "codecov": "codecov", 26 | "test": "jest --testTimeout=8400000 --coverage src/*.test.js" 27 | }, 28 | "devDependencies": { 29 | "@babel/plugin-transform-runtime": "^7.14.2", 30 | "@babel/preset-env": "^7.14.2", 31 | "@zeit/ncc": "^0.22.3", 32 | "babel-core": "^6.26.3", 33 | "babel-eslint": "^10.1.0", 34 | "babel-jest": "^26.6.3", 35 | "codecov": "^3.8.2", 36 | "eslint": "^7.26.0", 37 | "eslint-plugin-async-await": "^0.0.0", 38 | "eslint-plugin-es6-recommended": "^0.1.2", 39 | "eslint-plugin-import": "^2.22.1", 40 | "eslint-plugin-node": "^11.1.0", 41 | "eslint-plugin-standard": "^5.0.0", 42 | "jest": "^26.6.3" 43 | }, 44 | "dependencies": { 45 | "@actions/core": "^1.7.0", 46 | "@actions/exec": "^1.0.4", 47 | "@actions/io": "^1.1.2", 48 | "@actions/tool-cache": "^1.6.1" 49 | }, 50 | "jest": { 51 | "transform": { 52 | "^.+\\.js?$": "babel-jest" 53 | }, 54 | "testEnvironment": "node" 55 | }, 56 | "engines": { 57 | "node": ">=12" 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/installer.test.js: -------------------------------------------------------------------------------- 1 | import { rmRF, } from '@actions/io'; 2 | import { join, } from 'path'; 3 | import { arch, } from 'os'; 4 | 5 | import { getGraalVM, } from './installer'; 6 | 7 | const CACHE_DIR = join(__dirname, '..', 'cache'); 8 | const TEMP_DIR = join(__dirname, '..', 'temp'); 9 | 10 | process.env['RUNNER_TOOL_CACHE'] = CACHE_DIR; 11 | process.env['RUNNER_TEMP'] = TEMP_DIR; 12 | 13 | const safeDelete = async (dir) => { 14 | try { 15 | await rmRF(dir); 16 | } catch { 17 | console.error(`Failed to delete directory ${dir}`); 18 | } 19 | }; 20 | 21 | describe('installer', () => { 22 | afterAll(async () => { 23 | await safeDelete(CACHE_DIR); 24 | await safeDelete(TEMP_DIR); 25 | }); 26 | 27 | it('Installs GraalVM', async () => { 28 | const javaVersion = 11; 29 | const graalvmVersion = '20.1.0'; 30 | const options = { 31 | tempDir : TEMP_DIR, 32 | jvmDir : join(TEMP_DIR, 'Library', 'Java', 'JavaVirtualMachines'), 33 | javaHome : 'TEST_JAVA_HOME', 34 | }; 35 | 36 | const toolPath = await getGraalVM(javaVersion, graalvmVersion, options); 37 | 38 | if (process.platform === 'darwin') { 39 | expect(toolPath).toBe(join(CACHE_DIR, 'GraalVM', `java${javaVersion}-darwin-amd64-${graalvmVersion}`, arch())); 40 | expect(process.env[ options.javaHome ]).toBe(join(toolPath, '/Contents/Home')); 41 | } else if (process.platform === 'win32') { 42 | expect(toolPath).toBe(join(CACHE_DIR, 'GraalVM', `java${javaVersion}-windows-amd64-${graalvmVersion}`, arch())); 43 | expect(process.env[options.javaHome]).toBe(toolPath); 44 | } else if (process.arch === 'arm64') { 45 | expect(toolPath).toBe(join(CACHE_DIR, 'GraalVM', `java${javaVersion}-linux-aarch64-${graalvmVersion}`, arch())); 46 | expect(process.env[options.javaHome]).toBe(toolPath); 47 | } else { 48 | expect(toolPath).toBe(join(CACHE_DIR, 'GraalVM', `java${javaVersion}-linux-amd64-${graalvmVersion}`, arch())); 49 | expect(process.env[options.javaHome]).toBe(toolPath); 50 | } 51 | }); 52 | }); 53 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GraalVM GitHub action 2 | 3 | [![GitHub workflow status](https://img.shields.io/github/workflow/status/ayltai/setup-graalvm/CI?style=flat)](https://github.com/ayltai/setup-graalvm/actions) 4 | [![Code Quality](https://img.shields.io/codacy/grade/d7d26464c65348068815d36757c3c0aa.svg?style=flat)](https://app.codacy.com/app/AlanTai/setup-graalvm/dashboard) 5 | [![Sonar Quality Gate](https://img.shields.io/sonar/quality_gate/ayltai_setup-graalvm?server=https%3A%2F%2Fsonarcloud.io)](https://sonarcloud.io/dashboard?id=ayltai_setup-graalvm) 6 | [![Sonar Violations (short format)](https://img.shields.io/sonar/violations/ayltai_setup-graalvm?format=short&server=https%3A%2F%2Fsonarcloud.io)](https://sonarcloud.io/dashboard?id=ayltai_setup-graalvm) 7 | [![Code Coverage](https://img.shields.io/codecov/c/github/ayltai/setup-graalvm.svg?style=flat)](https://codecov.io/gh/ayltai/setup-graalvm) 8 | [![Sonar Coverage](https://img.shields.io/sonar/coverage/ayltai_setup-graalvm?server=https%3A%2F%2Fsonarcloud.io)](https://sonarcloud.io/dashboard?id=ayltai_setup-graalvm) 9 | [![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=ayltai_setup-graalvm&metric=sqale_rating)](https://sonarcloud.io/dashboard?id=ayltai_setup-graalvm) 10 | [![Reliability Rating](https://sonarcloud.io/api/project_badges/measure?project=ayltai_setup-graalvm&metric=reliability_rating)](https://sonarcloud.io/dashboard?id=ayltai_setup-graalvm) 11 | [![Sonar Tech Debt](https://img.shields.io/sonar/tech_debt/ayltai_setup-graalvm?server=https%3A%2F%2Fsonarcloud.io)](https://sonarcloud.io/dashboard?id=ayltai_setup-graalvm) 12 | [![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=ayltai_setup-graalvm&metric=security_rating)](https://sonarcloud.io/dashboard?id=ayltai_setup-graalvm) 13 | [![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=ayltai_setup-graalvm&metric=vulnerabilities)](https://sonarcloud.io/dashboard?id=ayltai_setup-graalvm) 14 | ![Maintenance](https://img.shields.io/maintenance/yes/2021) 15 | [![Release](https://img.shields.io/github/release/ayltai/setup-graalvm.svg?style=flat)](https://github.com/ayltai/setup-graalvm/releases) 16 | [![License](https://img.shields.io/github/license/ayltai/setup-graalvm.svg?style=flat)](https://github.com/ayltai/setup-graalvm/blob/master/LICENSE) 17 | 18 | This action sets up a GraalVM environment for use in [GitHub](https://github.com) [Actions](https://github.com/features/actions) by: 19 | * downloading and caching a requested version of [GraalVM](https://www.graalvm.org) and adding to `PATH` 20 | * optionally downloading [GraalVM Native Image](https://www.graalvm.org/getting-started/#native-images) 21 | * registering problem matchers for error output 22 | 23 | [![Buy me a coffee](https://img.shields.io/static/v1?label=Buy%20me%20a&message=coffee&color=important&style=flat&logo=buy-me-a-coffee&logoColor=white)](https://buymeacoff.ee/ayltai) 24 | 25 | ## Usage 26 | See [action.yaml](action.yaml) 27 | 28 | ### Basic 29 | ```yaml 30 | steps: 31 | - uses: actions/checkout@v2 32 | - uses: ayltai/setup-graalvm@v1 33 | with: 34 | java-version: 11 35 | graalvm-version: 21.1.0 36 | native-image: true 37 | - run: java -version 38 | ``` 39 | 40 | ## Configuration 41 | | Property | Required | Default | Description | 42 | |-------------------|----------|---------|-------------| 43 | | `java-version` | Yes | | A major Java version. Only `8`, `11` and `16` (targeting GraalVM v21.1.0) are supported. | 44 | | `graalvm-version` | Yes | | A GraalVM release. Supported values are `21.2.0`, `21.1.0`, `21.0.0.2`, `21.0.0`, `20.3.2`, `20.3.1.2`, `20.3.1`, `20.3.0`, `20.2.0`, `20.1.0`, `20.0.1`, `20.0.0`, `19.3.2`, `19.3.1`, `19.3.0.2` and `19.3.0`. See [GraalVM releases](https://github.com/graalvm/graalvm-ce-builds/releases) | 45 | | `native-image` | No | `false` | `true` to download GraalVM `native-image`. | 46 | 47 | ## Spring Boot applications 48 | If you are building Spring Boot applications with GraalVM or GraalVM native image, you may consider using [Spring GraalVM Native Gradle plugin](https://plugins.gradle.org/plugin/com.github.ayltai.spring-graalvm-native-plugin). 49 | 50 | ## License 51 | [MIT](https://github.com/ayltai/setup-graalvm/blob/master/LICENSE) 52 | 53 | ## References 54 | * [GraalVM](https://www.graalvm.org) 55 | * [GraalVM Native Image](https://www.graalvm.org/getting-started/#native-images) 56 | -------------------------------------------------------------------------------- /src/installer.js: -------------------------------------------------------------------------------- 1 | import { addPath, debug, exportVariable, info, } from '@actions/core'; 2 | import { exec, } from '@actions/exec'; 3 | import { mkdirP, rmRF, } from '@actions/io'; 4 | import { cacheDir, downloadTool, extractTar, extractZip, find, } from '@actions/tool-cache'; 5 | import { readdirSync, statSync, } from 'fs'; 6 | import { join, normalize, } from 'path'; 7 | 8 | const IS_WINDOWS = process.platform === 'win32'; 9 | const PLATFORM = IS_WINDOWS ? 'windows' : process.platform === 'darwin' ? 'darwin' : 'linux'; 10 | const ARCH = process.arch === 'arm64' ? 'aarch64' : 'amd64' ; 11 | const TOOL_NAME = 'GraalVM'; 12 | 13 | const OPTIONS = { 14 | tempDir : process.env['RUNNER_TEMP'] || join(IS_WINDOWS ? process.env['USERPROFILE'] || 'C:\\' : PLATFORM === 'darwin' ? '/Users' : '/home', 'actions', 'temp'), 15 | jvmDir : '/Library/Java/JavaVirtualMachines', 16 | binDir : 'bin', 17 | appDir : '/Contents/Home', 18 | javaHome : 'JAVA_HOME', 19 | graalHome : 'GRAALVM_HOME', 20 | }; 21 | 22 | export const getGraalVM = async (javaVersion, graalvmVersion, options = {}) => { 23 | options = { 24 | ...OPTIONS, 25 | ...options, 26 | }; 27 | 28 | const version = getVersion(javaVersion, graalvmVersion); 29 | const tempDir = join(options.tempDir, 'temp_' + Math.floor(Math.random() * 2000000000)); 30 | 31 | let toolPath = find(TOOL_NAME, version); 32 | if (toolPath) { 33 | debug(`${TOOL_NAME} found in cache ${toolPath}`); 34 | } else { 35 | const compressedFileExtension = IS_WINDOWS ? '.zip' : '.tar.gz'; 36 | const downloadUrl = `https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-${graalvmVersion}/graalvm-ce-${version}${compressedFileExtension}`; 37 | 38 | info(`Downloading ${TOOL_NAME} from ${downloadUrl}`); 39 | 40 | const graalvmFile = await downloadTool(downloadUrl); 41 | const graalvmDir = await decompressDownload(graalvmFile, compressedFileExtension, tempDir); 42 | 43 | debug(`${TOOL_NAME} extracted to ${graalvmDir}`); 44 | 45 | toolPath = await cacheDir(graalvmDir, TOOL_NAME, version); 46 | } 47 | 48 | if (PLATFORM === 'darwin') { 49 | await rmRF(tempDir); 50 | 51 | exportVariable(options.javaHome, join(toolPath, options.appDir)); 52 | exportVariable(options.graalHome, join(toolPath, options.appDir)); 53 | addPath(join(toolPath, options.appDir, options.binDir)); 54 | } else { 55 | exportVariable(options.javaHome, toolPath); 56 | exportVariable(options.graalHome, toolPath); 57 | addPath(join(toolPath, options.binDir)); 58 | } 59 | 60 | return toolPath; 61 | }; 62 | 63 | export const getNativeImage = async () => { 64 | await exec('gu install native-image'); 65 | }; 66 | 67 | const getVersion = (javaVersion, graalvmVersion) => { 68 | return `java${javaVersion}-${PLATFORM}-${ARCH}-${graalvmVersion}`; 69 | }; 70 | 71 | const decompressDownload = async (compressedFile, compressedFileExtension, destinationDir) => { 72 | await mkdirP(destinationDir); 73 | 74 | const graalvmFile = normalize(compressedFile); 75 | const stats = statSync(graalvmFile); 76 | 77 | if (stats) { 78 | if (stats.isFile()) { 79 | await extractFiles(graalvmFile, compressedFileExtension, destinationDir); 80 | 81 | return join(destinationDir, readdirSync(destinationDir)[0]); 82 | } else { 83 | throw new Error(`Failed to extract ${graalvmFile} which is not a file`); 84 | } 85 | } else { 86 | throw new Error(`${graalvmFile} does not exist`); 87 | } 88 | }; 89 | 90 | const extractFiles = async (compressedFile, compressedFileExtension, destinationDir) => { 91 | const stats = statSync(compressedFile); 92 | if (stats) { 93 | if (stats.isFile()) { 94 | if ('.tar' === compressedFileExtension || '.tar.gz' === compressedFileExtension) { 95 | await extractTar(compressedFile, destinationDir); 96 | } else if ('.zip' === compressedFileExtension) { 97 | await extractZip(compressedFile, destinationDir); 98 | } else { 99 | throw new Error(`Failed to extract ${compressedFile} which is in an unrecognized compression format`); 100 | } 101 | } else { 102 | throw new Error(`Failed to extract ${compressedFile} which is not a file`); 103 | } 104 | } else { 105 | throw new Error(`${compressedFile} does not exist`); 106 | } 107 | }; 108 | -------------------------------------------------------------------------------- /dist/index.js: -------------------------------------------------------------------------------- 1 | module.exports = 2 | /******/ (function(modules, runtime) { // webpackBootstrap 3 | /******/ "use strict"; 4 | /******/ // The module cache 5 | /******/ var installedModules = {}; 6 | /******/ 7 | /******/ // The require function 8 | /******/ function __webpack_require__(moduleId) { 9 | /******/ 10 | /******/ // Check if module is in cache 11 | /******/ if(installedModules[moduleId]) { 12 | /******/ return installedModules[moduleId].exports; 13 | /******/ } 14 | /******/ // Create a new module (and put it into the cache) 15 | /******/ var module = installedModules[moduleId] = { 16 | /******/ i: moduleId, 17 | /******/ l: false, 18 | /******/ exports: {} 19 | /******/ }; 20 | /******/ 21 | /******/ // Execute the module function 22 | /******/ var threw = true; 23 | /******/ try { 24 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 25 | /******/ threw = false; 26 | /******/ } finally { 27 | /******/ if(threw) delete installedModules[moduleId]; 28 | /******/ } 29 | /******/ 30 | /******/ // Flag the module as loaded 31 | /******/ module.l = true; 32 | /******/ 33 | /******/ // Return the exports of the module 34 | /******/ return module.exports; 35 | /******/ } 36 | /******/ 37 | /******/ 38 | /******/ __webpack_require__.ab = __dirname + "/"; 39 | /******/ 40 | /******/ // the startup function 41 | /******/ function startup() { 42 | /******/ // Load entry module and return exports 43 | /******/ return __webpack_require__(966); 44 | /******/ }; 45 | /******/ // initialize runtime 46 | /******/ runtime(__webpack_require__); 47 | /******/ 48 | /******/ // run startup 49 | /******/ return startup(); 50 | /******/ }) 51 | /************************************************************************/ 52 | /******/ ({ 53 | 54 | /***/ 1: 55 | /***/ (function(__unusedmodule, exports, __webpack_require__) { 56 | 57 | "use strict"; 58 | 59 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 60 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 61 | return new (P || (P = Promise))(function (resolve, reject) { 62 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 63 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 64 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 65 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 66 | }); 67 | }; 68 | var __importStar = (this && this.__importStar) || function (mod) { 69 | if (mod && mod.__esModule) return mod; 70 | var result = {}; 71 | if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; 72 | result["default"] = mod; 73 | return result; 74 | }; 75 | Object.defineProperty(exports, "__esModule", { value: true }); 76 | const childProcess = __importStar(__webpack_require__(129)); 77 | const path = __importStar(__webpack_require__(622)); 78 | const util_1 = __webpack_require__(669); 79 | const ioUtil = __importStar(__webpack_require__(672)); 80 | const exec = util_1.promisify(childProcess.exec); 81 | /** 82 | * Copies a file or folder. 83 | * Based off of shelljs - https://github.com/shelljs/shelljs/blob/9237f66c52e5daa40458f94f9565e18e8132f5a6/src/cp.js 84 | * 85 | * @param source source path 86 | * @param dest destination path 87 | * @param options optional. See CopyOptions. 88 | */ 89 | function cp(source, dest, options = {}) { 90 | return __awaiter(this, void 0, void 0, function* () { 91 | const { force, recursive } = readCopyOptions(options); 92 | const destStat = (yield ioUtil.exists(dest)) ? yield ioUtil.stat(dest) : null; 93 | // Dest is an existing file, but not forcing 94 | if (destStat && destStat.isFile() && !force) { 95 | return; 96 | } 97 | // If dest is an existing directory, should copy inside. 98 | const newDest = destStat && destStat.isDirectory() 99 | ? path.join(dest, path.basename(source)) 100 | : dest; 101 | if (!(yield ioUtil.exists(source))) { 102 | throw new Error(`no such file or directory: ${source}`); 103 | } 104 | const sourceStat = yield ioUtil.stat(source); 105 | if (sourceStat.isDirectory()) { 106 | if (!recursive) { 107 | throw new Error(`Failed to copy. ${source} is a directory, but tried to copy without recursive flag.`); 108 | } 109 | else { 110 | yield cpDirRecursive(source, newDest, 0, force); 111 | } 112 | } 113 | else { 114 | if (path.relative(source, newDest) === '') { 115 | // a file cannot be copied to itself 116 | throw new Error(`'${newDest}' and '${source}' are the same file`); 117 | } 118 | yield copyFile(source, newDest, force); 119 | } 120 | }); 121 | } 122 | exports.cp = cp; 123 | /** 124 | * Moves a path. 125 | * 126 | * @param source source path 127 | * @param dest destination path 128 | * @param options optional. See MoveOptions. 129 | */ 130 | function mv(source, dest, options = {}) { 131 | return __awaiter(this, void 0, void 0, function* () { 132 | if (yield ioUtil.exists(dest)) { 133 | let destExists = true; 134 | if (yield ioUtil.isDirectory(dest)) { 135 | // If dest is directory copy src into dest 136 | dest = path.join(dest, path.basename(source)); 137 | destExists = yield ioUtil.exists(dest); 138 | } 139 | if (destExists) { 140 | if (options.force == null || options.force) { 141 | yield rmRF(dest); 142 | } 143 | else { 144 | throw new Error('Destination already exists'); 145 | } 146 | } 147 | } 148 | yield mkdirP(path.dirname(dest)); 149 | yield ioUtil.rename(source, dest); 150 | }); 151 | } 152 | exports.mv = mv; 153 | /** 154 | * Remove a path recursively with force 155 | * 156 | * @param inputPath path to remove 157 | */ 158 | function rmRF(inputPath) { 159 | return __awaiter(this, void 0, void 0, function* () { 160 | if (ioUtil.IS_WINDOWS) { 161 | // Node doesn't provide a delete operation, only an unlink function. This means that if the file is being used by another 162 | // program (e.g. antivirus), it won't be deleted. To address this, we shell out the work to rd/del. 163 | try { 164 | if (yield ioUtil.isDirectory(inputPath, true)) { 165 | yield exec(`rd /s /q "${inputPath}"`); 166 | } 167 | else { 168 | yield exec(`del /f /a "${inputPath}"`); 169 | } 170 | } 171 | catch (err) { 172 | // if you try to delete a file that doesn't exist, desired result is achieved 173 | // other errors are valid 174 | if (err.code !== 'ENOENT') 175 | throw err; 176 | } 177 | // Shelling out fails to remove a symlink folder with missing source, this unlink catches that 178 | try { 179 | yield ioUtil.unlink(inputPath); 180 | } 181 | catch (err) { 182 | // if you try to delete a file that doesn't exist, desired result is achieved 183 | // other errors are valid 184 | if (err.code !== 'ENOENT') 185 | throw err; 186 | } 187 | } 188 | else { 189 | let isDir = false; 190 | try { 191 | isDir = yield ioUtil.isDirectory(inputPath); 192 | } 193 | catch (err) { 194 | // if you try to delete a file that doesn't exist, desired result is achieved 195 | // other errors are valid 196 | if (err.code !== 'ENOENT') 197 | throw err; 198 | return; 199 | } 200 | if (isDir) { 201 | yield exec(`rm -rf "${inputPath}"`); 202 | } 203 | else { 204 | yield ioUtil.unlink(inputPath); 205 | } 206 | } 207 | }); 208 | } 209 | exports.rmRF = rmRF; 210 | /** 211 | * Make a directory. Creates the full path with folders in between 212 | * Will throw if it fails 213 | * 214 | * @param fsPath path to create 215 | * @returns Promise 216 | */ 217 | function mkdirP(fsPath) { 218 | return __awaiter(this, void 0, void 0, function* () { 219 | yield ioUtil.mkdirP(fsPath); 220 | }); 221 | } 222 | exports.mkdirP = mkdirP; 223 | /** 224 | * Returns path of a tool had the tool actually been invoked. Resolves via paths. 225 | * If you check and the tool does not exist, it will throw. 226 | * 227 | * @param tool name of the tool 228 | * @param check whether to check if tool exists 229 | * @returns Promise path to tool 230 | */ 231 | function which(tool, check) { 232 | return __awaiter(this, void 0, void 0, function* () { 233 | if (!tool) { 234 | throw new Error("parameter 'tool' is required"); 235 | } 236 | // recursive when check=true 237 | if (check) { 238 | const result = yield which(tool, false); 239 | if (!result) { 240 | if (ioUtil.IS_WINDOWS) { 241 | throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also verify the file has a valid extension for an executable file.`); 242 | } 243 | else { 244 | throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also check the file mode to verify the file is executable.`); 245 | } 246 | } 247 | return result; 248 | } 249 | const matches = yield findInPath(tool); 250 | if (matches && matches.length > 0) { 251 | return matches[0]; 252 | } 253 | return ''; 254 | }); 255 | } 256 | exports.which = which; 257 | /** 258 | * Returns a list of all occurrences of the given tool on the system path. 259 | * 260 | * @returns Promise the paths of the tool 261 | */ 262 | function findInPath(tool) { 263 | return __awaiter(this, void 0, void 0, function* () { 264 | if (!tool) { 265 | throw new Error("parameter 'tool' is required"); 266 | } 267 | // build the list of extensions to try 268 | const extensions = []; 269 | if (ioUtil.IS_WINDOWS && process.env['PATHEXT']) { 270 | for (const extension of process.env['PATHEXT'].split(path.delimiter)) { 271 | if (extension) { 272 | extensions.push(extension); 273 | } 274 | } 275 | } 276 | // if it's rooted, return it if exists. otherwise return empty. 277 | if (ioUtil.isRooted(tool)) { 278 | const filePath = yield ioUtil.tryGetExecutablePath(tool, extensions); 279 | if (filePath) { 280 | return [filePath]; 281 | } 282 | return []; 283 | } 284 | // if any path separators, return empty 285 | if (tool.includes(path.sep)) { 286 | return []; 287 | } 288 | // build the list of directories 289 | // 290 | // Note, technically "where" checks the current directory on Windows. From a toolkit perspective, 291 | // it feels like we should not do this. Checking the current directory seems like more of a use 292 | // case of a shell, and the which() function exposed by the toolkit should strive for consistency 293 | // across platforms. 294 | const directories = []; 295 | if (process.env.PATH) { 296 | for (const p of process.env.PATH.split(path.delimiter)) { 297 | if (p) { 298 | directories.push(p); 299 | } 300 | } 301 | } 302 | // find all matches 303 | const matches = []; 304 | for (const directory of directories) { 305 | const filePath = yield ioUtil.tryGetExecutablePath(path.join(directory, tool), extensions); 306 | if (filePath) { 307 | matches.push(filePath); 308 | } 309 | } 310 | return matches; 311 | }); 312 | } 313 | exports.findInPath = findInPath; 314 | function readCopyOptions(options) { 315 | const force = options.force == null ? true : options.force; 316 | const recursive = Boolean(options.recursive); 317 | return { force, recursive }; 318 | } 319 | function cpDirRecursive(sourceDir, destDir, currentDepth, force) { 320 | return __awaiter(this, void 0, void 0, function* () { 321 | // Ensure there is not a run away recursive copy 322 | if (currentDepth >= 255) 323 | return; 324 | currentDepth++; 325 | yield mkdirP(destDir); 326 | const files = yield ioUtil.readdir(sourceDir); 327 | for (const fileName of files) { 328 | const srcFile = `${sourceDir}/${fileName}`; 329 | const destFile = `${destDir}/${fileName}`; 330 | const srcFileStat = yield ioUtil.lstat(srcFile); 331 | if (srcFileStat.isDirectory()) { 332 | // Recurse 333 | yield cpDirRecursive(srcFile, destFile, currentDepth, force); 334 | } 335 | else { 336 | yield copyFile(srcFile, destFile, force); 337 | } 338 | } 339 | // Change the mode for the newly created directory 340 | yield ioUtil.chmod(destDir, (yield ioUtil.stat(sourceDir)).mode); 341 | }); 342 | } 343 | // Buffered file copy 344 | function copyFile(srcFile, destFile, force) { 345 | return __awaiter(this, void 0, void 0, function* () { 346 | if ((yield ioUtil.lstat(srcFile)).isSymbolicLink()) { 347 | // unlink/re-link it 348 | try { 349 | yield ioUtil.lstat(destFile); 350 | yield ioUtil.unlink(destFile); 351 | } 352 | catch (e) { 353 | // Try to override file permission 354 | if (e.code === 'EPERM') { 355 | yield ioUtil.chmod(destFile, '0666'); 356 | yield ioUtil.unlink(destFile); 357 | } 358 | // other errors = it doesn't exist, no work to do 359 | } 360 | // Copy over symlink 361 | const symlinkFull = yield ioUtil.readlink(srcFile); 362 | yield ioUtil.symlink(symlinkFull, destFile, ioUtil.IS_WINDOWS ? 'junction' : null); 363 | } 364 | else if (!(yield ioUtil.exists(destFile)) || force) { 365 | yield ioUtil.copyFile(srcFile, destFile); 366 | } 367 | }); 368 | } 369 | //# sourceMappingURL=io.js.map 370 | 371 | /***/ }), 372 | 373 | /***/ 9: 374 | /***/ (function(__unusedmodule, exports, __webpack_require__) { 375 | 376 | "use strict"; 377 | 378 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 379 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 380 | return new (P || (P = Promise))(function (resolve, reject) { 381 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 382 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 383 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 384 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 385 | }); 386 | }; 387 | var __importStar = (this && this.__importStar) || function (mod) { 388 | if (mod && mod.__esModule) return mod; 389 | var result = {}; 390 | if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; 391 | result["default"] = mod; 392 | return result; 393 | }; 394 | Object.defineProperty(exports, "__esModule", { value: true }); 395 | const os = __importStar(__webpack_require__(87)); 396 | const events = __importStar(__webpack_require__(614)); 397 | const child = __importStar(__webpack_require__(129)); 398 | const path = __importStar(__webpack_require__(622)); 399 | const io = __importStar(__webpack_require__(1)); 400 | const ioUtil = __importStar(__webpack_require__(672)); 401 | /* eslint-disable @typescript-eslint/unbound-method */ 402 | const IS_WINDOWS = process.platform === 'win32'; 403 | /* 404 | * Class for running command line tools. Handles quoting and arg parsing in a platform agnostic way. 405 | */ 406 | class ToolRunner extends events.EventEmitter { 407 | constructor(toolPath, args, options) { 408 | super(); 409 | if (!toolPath) { 410 | throw new Error("Parameter 'toolPath' cannot be null or empty."); 411 | } 412 | this.toolPath = toolPath; 413 | this.args = args || []; 414 | this.options = options || {}; 415 | } 416 | _debug(message) { 417 | if (this.options.listeners && this.options.listeners.debug) { 418 | this.options.listeners.debug(message); 419 | } 420 | } 421 | _getCommandString(options, noPrefix) { 422 | const toolPath = this._getSpawnFileName(); 423 | const args = this._getSpawnArgs(options); 424 | let cmd = noPrefix ? '' : '[command]'; // omit prefix when piped to a second tool 425 | if (IS_WINDOWS) { 426 | // Windows + cmd file 427 | if (this._isCmdFile()) { 428 | cmd += toolPath; 429 | for (const a of args) { 430 | cmd += ` ${a}`; 431 | } 432 | } 433 | // Windows + verbatim 434 | else if (options.windowsVerbatimArguments) { 435 | cmd += `"${toolPath}"`; 436 | for (const a of args) { 437 | cmd += ` ${a}`; 438 | } 439 | } 440 | // Windows (regular) 441 | else { 442 | cmd += this._windowsQuoteCmdArg(toolPath); 443 | for (const a of args) { 444 | cmd += ` ${this._windowsQuoteCmdArg(a)}`; 445 | } 446 | } 447 | } 448 | else { 449 | // OSX/Linux - this can likely be improved with some form of quoting. 450 | // creating processes on Unix is fundamentally different than Windows. 451 | // on Unix, execvp() takes an arg array. 452 | cmd += toolPath; 453 | for (const a of args) { 454 | cmd += ` ${a}`; 455 | } 456 | } 457 | return cmd; 458 | } 459 | _processLineBuffer(data, strBuffer, onLine) { 460 | try { 461 | let s = strBuffer + data.toString(); 462 | let n = s.indexOf(os.EOL); 463 | while (n > -1) { 464 | const line = s.substring(0, n); 465 | onLine(line); 466 | // the rest of the string ... 467 | s = s.substring(n + os.EOL.length); 468 | n = s.indexOf(os.EOL); 469 | } 470 | strBuffer = s; 471 | } 472 | catch (err) { 473 | // streaming lines to console is best effort. Don't fail a build. 474 | this._debug(`error processing line. Failed with error ${err}`); 475 | } 476 | } 477 | _getSpawnFileName() { 478 | if (IS_WINDOWS) { 479 | if (this._isCmdFile()) { 480 | return process.env['COMSPEC'] || 'cmd.exe'; 481 | } 482 | } 483 | return this.toolPath; 484 | } 485 | _getSpawnArgs(options) { 486 | if (IS_WINDOWS) { 487 | if (this._isCmdFile()) { 488 | let argline = `/D /S /C "${this._windowsQuoteCmdArg(this.toolPath)}`; 489 | for (const a of this.args) { 490 | argline += ' '; 491 | argline += options.windowsVerbatimArguments 492 | ? a 493 | : this._windowsQuoteCmdArg(a); 494 | } 495 | argline += '"'; 496 | return [argline]; 497 | } 498 | } 499 | return this.args; 500 | } 501 | _endsWith(str, end) { 502 | return str.endsWith(end); 503 | } 504 | _isCmdFile() { 505 | const upperToolPath = this.toolPath.toUpperCase(); 506 | return (this._endsWith(upperToolPath, '.CMD') || 507 | this._endsWith(upperToolPath, '.BAT')); 508 | } 509 | _windowsQuoteCmdArg(arg) { 510 | // for .exe, apply the normal quoting rules that libuv applies 511 | if (!this._isCmdFile()) { 512 | return this._uvQuoteCmdArg(arg); 513 | } 514 | // otherwise apply quoting rules specific to the cmd.exe command line parser. 515 | // the libuv rules are generic and are not designed specifically for cmd.exe 516 | // command line parser. 517 | // 518 | // for a detailed description of the cmd.exe command line parser, refer to 519 | // http://stackoverflow.com/questions/4094699/how-does-the-windows-command-interpreter-cmd-exe-parse-scripts/7970912#7970912 520 | // need quotes for empty arg 521 | if (!arg) { 522 | return '""'; 523 | } 524 | // determine whether the arg needs to be quoted 525 | const cmdSpecialChars = [ 526 | ' ', 527 | '\t', 528 | '&', 529 | '(', 530 | ')', 531 | '[', 532 | ']', 533 | '{', 534 | '}', 535 | '^', 536 | '=', 537 | ';', 538 | '!', 539 | "'", 540 | '+', 541 | ',', 542 | '`', 543 | '~', 544 | '|', 545 | '<', 546 | '>', 547 | '"' 548 | ]; 549 | let needsQuotes = false; 550 | for (const char of arg) { 551 | if (cmdSpecialChars.some(x => x === char)) { 552 | needsQuotes = true; 553 | break; 554 | } 555 | } 556 | // short-circuit if quotes not needed 557 | if (!needsQuotes) { 558 | return arg; 559 | } 560 | // the following quoting rules are very similar to the rules that by libuv applies. 561 | // 562 | // 1) wrap the string in quotes 563 | // 564 | // 2) double-up quotes - i.e. " => "" 565 | // 566 | // this is different from the libuv quoting rules. libuv replaces " with \", which unfortunately 567 | // doesn't work well with a cmd.exe command line. 568 | // 569 | // note, replacing " with "" also works well if the arg is passed to a downstream .NET console app. 570 | // for example, the command line: 571 | // foo.exe "myarg:""my val""" 572 | // is parsed by a .NET console app into an arg array: 573 | // [ "myarg:\"my val\"" ] 574 | // which is the same end result when applying libuv quoting rules. although the actual 575 | // command line from libuv quoting rules would look like: 576 | // foo.exe "myarg:\"my val\"" 577 | // 578 | // 3) double-up slashes that precede a quote, 579 | // e.g. hello \world => "hello \world" 580 | // hello\"world => "hello\\""world" 581 | // hello\\"world => "hello\\\\""world" 582 | // hello world\ => "hello world\\" 583 | // 584 | // technically this is not required for a cmd.exe command line, or the batch argument parser. 585 | // the reasons for including this as a .cmd quoting rule are: 586 | // 587 | // a) this is optimized for the scenario where the argument is passed from the .cmd file to an 588 | // external program. many programs (e.g. .NET console apps) rely on the slash-doubling rule. 589 | // 590 | // b) it's what we've been doing previously (by deferring to node default behavior) and we 591 | // haven't heard any complaints about that aspect. 592 | // 593 | // note, a weakness of the quoting rules chosen here, is that % is not escaped. in fact, % cannot be 594 | // escaped when used on the command line directly - even though within a .cmd file % can be escaped 595 | // by using %%. 596 | // 597 | // the saving grace is, on the command line, %var% is left as-is if var is not defined. this contrasts 598 | // the line parsing rules within a .cmd file, where if var is not defined it is replaced with nothing. 599 | // 600 | // one option that was explored was replacing % with ^% - i.e. %var% => ^%var^%. this hack would 601 | // often work, since it is unlikely that var^ would exist, and the ^ character is removed when the 602 | // variable is used. the problem, however, is that ^ is not removed when %* is used to pass the args 603 | // to an external program. 604 | // 605 | // an unexplored potential solution for the % escaping problem, is to create a wrapper .cmd file. 606 | // % can be escaped within a .cmd file. 607 | let reverse = '"'; 608 | let quoteHit = true; 609 | for (let i = arg.length; i > 0; i--) { 610 | // walk the string in reverse 611 | reverse += arg[i - 1]; 612 | if (quoteHit && arg[i - 1] === '\\') { 613 | reverse += '\\'; // double the slash 614 | } 615 | else if (arg[i - 1] === '"') { 616 | quoteHit = true; 617 | reverse += '"'; // double the quote 618 | } 619 | else { 620 | quoteHit = false; 621 | } 622 | } 623 | reverse += '"'; 624 | return reverse 625 | .split('') 626 | .reverse() 627 | .join(''); 628 | } 629 | _uvQuoteCmdArg(arg) { 630 | // Tool runner wraps child_process.spawn() and needs to apply the same quoting as 631 | // Node in certain cases where the undocumented spawn option windowsVerbatimArguments 632 | // is used. 633 | // 634 | // Since this function is a port of quote_cmd_arg from Node 4.x (technically, lib UV, 635 | // see https://github.com/nodejs/node/blob/v4.x/deps/uv/src/win/process.c for details), 636 | // pasting copyright notice from Node within this function: 637 | // 638 | // Copyright Joyent, Inc. and other Node contributors. All rights reserved. 639 | // 640 | // Permission is hereby granted, free of charge, to any person obtaining a copy 641 | // of this software and associated documentation files (the "Software"), to 642 | // deal in the Software without restriction, including without limitation the 643 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 644 | // sell copies of the Software, and to permit persons to whom the Software is 645 | // furnished to do so, subject to the following conditions: 646 | // 647 | // The above copyright notice and this permission notice shall be included in 648 | // all copies or substantial portions of the Software. 649 | // 650 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 651 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 652 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 653 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 654 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 655 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 656 | // IN THE SOFTWARE. 657 | if (!arg) { 658 | // Need double quotation for empty argument 659 | return '""'; 660 | } 661 | if (!arg.includes(' ') && !arg.includes('\t') && !arg.includes('"')) { 662 | // No quotation needed 663 | return arg; 664 | } 665 | if (!arg.includes('"') && !arg.includes('\\')) { 666 | // No embedded double quotes or backslashes, so I can just wrap 667 | // quote marks around the whole thing. 668 | return `"${arg}"`; 669 | } 670 | // Expected input/output: 671 | // input : hello"world 672 | // output: "hello\"world" 673 | // input : hello""world 674 | // output: "hello\"\"world" 675 | // input : hello\world 676 | // output: hello\world 677 | // input : hello\\world 678 | // output: hello\\world 679 | // input : hello\"world 680 | // output: "hello\\\"world" 681 | // input : hello\\"world 682 | // output: "hello\\\\\"world" 683 | // input : hello world\ 684 | // output: "hello world\\" - note the comment in libuv actually reads "hello world\" 685 | // but it appears the comment is wrong, it should be "hello world\\" 686 | let reverse = '"'; 687 | let quoteHit = true; 688 | for (let i = arg.length; i > 0; i--) { 689 | // walk the string in reverse 690 | reverse += arg[i - 1]; 691 | if (quoteHit && arg[i - 1] === '\\') { 692 | reverse += '\\'; 693 | } 694 | else if (arg[i - 1] === '"') { 695 | quoteHit = true; 696 | reverse += '\\'; 697 | } 698 | else { 699 | quoteHit = false; 700 | } 701 | } 702 | reverse += '"'; 703 | return reverse 704 | .split('') 705 | .reverse() 706 | .join(''); 707 | } 708 | _cloneExecOptions(options) { 709 | options = options || {}; 710 | const result = { 711 | cwd: options.cwd || process.cwd(), 712 | env: options.env || process.env, 713 | silent: options.silent || false, 714 | windowsVerbatimArguments: options.windowsVerbatimArguments || false, 715 | failOnStdErr: options.failOnStdErr || false, 716 | ignoreReturnCode: options.ignoreReturnCode || false, 717 | delay: options.delay || 10000 718 | }; 719 | result.outStream = options.outStream || process.stdout; 720 | result.errStream = options.errStream || process.stderr; 721 | return result; 722 | } 723 | _getSpawnOptions(options, toolPath) { 724 | options = options || {}; 725 | const result = {}; 726 | result.cwd = options.cwd; 727 | result.env = options.env; 728 | result['windowsVerbatimArguments'] = 729 | options.windowsVerbatimArguments || this._isCmdFile(); 730 | if (options.windowsVerbatimArguments) { 731 | result.argv0 = `"${toolPath}"`; 732 | } 733 | return result; 734 | } 735 | /** 736 | * Exec a tool. 737 | * Output will be streamed to the live console. 738 | * Returns promise with return code 739 | * 740 | * @param tool path to tool to exec 741 | * @param options optional exec options. See ExecOptions 742 | * @returns number 743 | */ 744 | exec() { 745 | return __awaiter(this, void 0, void 0, function* () { 746 | // root the tool path if it is unrooted and contains relative pathing 747 | if (!ioUtil.isRooted(this.toolPath) && 748 | (this.toolPath.includes('/') || 749 | (IS_WINDOWS && this.toolPath.includes('\\')))) { 750 | // prefer options.cwd if it is specified, however options.cwd may also need to be rooted 751 | this.toolPath = path.resolve(process.cwd(), this.options.cwd || process.cwd(), this.toolPath); 752 | } 753 | // if the tool is only a file name, then resolve it from the PATH 754 | // otherwise verify it exists (add extension on Windows if necessary) 755 | this.toolPath = yield io.which(this.toolPath, true); 756 | return new Promise((resolve, reject) => { 757 | this._debug(`exec tool: ${this.toolPath}`); 758 | this._debug('arguments:'); 759 | for (const arg of this.args) { 760 | this._debug(` ${arg}`); 761 | } 762 | const optionsNonNull = this._cloneExecOptions(this.options); 763 | if (!optionsNonNull.silent && optionsNonNull.outStream) { 764 | optionsNonNull.outStream.write(this._getCommandString(optionsNonNull) + os.EOL); 765 | } 766 | const state = new ExecState(optionsNonNull, this.toolPath); 767 | state.on('debug', (message) => { 768 | this._debug(message); 769 | }); 770 | const fileName = this._getSpawnFileName(); 771 | const cp = child.spawn(fileName, this._getSpawnArgs(optionsNonNull), this._getSpawnOptions(this.options, fileName)); 772 | const stdbuffer = ''; 773 | if (cp.stdout) { 774 | cp.stdout.on('data', (data) => { 775 | if (this.options.listeners && this.options.listeners.stdout) { 776 | this.options.listeners.stdout(data); 777 | } 778 | if (!optionsNonNull.silent && optionsNonNull.outStream) { 779 | optionsNonNull.outStream.write(data); 780 | } 781 | this._processLineBuffer(data, stdbuffer, (line) => { 782 | if (this.options.listeners && this.options.listeners.stdline) { 783 | this.options.listeners.stdline(line); 784 | } 785 | }); 786 | }); 787 | } 788 | const errbuffer = ''; 789 | if (cp.stderr) { 790 | cp.stderr.on('data', (data) => { 791 | state.processStderr = true; 792 | if (this.options.listeners && this.options.listeners.stderr) { 793 | this.options.listeners.stderr(data); 794 | } 795 | if (!optionsNonNull.silent && 796 | optionsNonNull.errStream && 797 | optionsNonNull.outStream) { 798 | const s = optionsNonNull.failOnStdErr 799 | ? optionsNonNull.errStream 800 | : optionsNonNull.outStream; 801 | s.write(data); 802 | } 803 | this._processLineBuffer(data, errbuffer, (line) => { 804 | if (this.options.listeners && this.options.listeners.errline) { 805 | this.options.listeners.errline(line); 806 | } 807 | }); 808 | }); 809 | } 810 | cp.on('error', (err) => { 811 | state.processError = err.message; 812 | state.processExited = true; 813 | state.processClosed = true; 814 | state.CheckComplete(); 815 | }); 816 | cp.on('exit', (code) => { 817 | state.processExitCode = code; 818 | state.processExited = true; 819 | this._debug(`Exit code ${code} received from tool '${this.toolPath}'`); 820 | state.CheckComplete(); 821 | }); 822 | cp.on('close', (code) => { 823 | state.processExitCode = code; 824 | state.processExited = true; 825 | state.processClosed = true; 826 | this._debug(`STDIO streams have closed for tool '${this.toolPath}'`); 827 | state.CheckComplete(); 828 | }); 829 | state.on('done', (error, exitCode) => { 830 | if (stdbuffer.length > 0) { 831 | this.emit('stdline', stdbuffer); 832 | } 833 | if (errbuffer.length > 0) { 834 | this.emit('errline', errbuffer); 835 | } 836 | cp.removeAllListeners(); 837 | if (error) { 838 | reject(error); 839 | } 840 | else { 841 | resolve(exitCode); 842 | } 843 | }); 844 | if (this.options.input) { 845 | if (!cp.stdin) { 846 | throw new Error('child process missing stdin'); 847 | } 848 | cp.stdin.end(this.options.input); 849 | } 850 | }); 851 | }); 852 | } 853 | } 854 | exports.ToolRunner = ToolRunner; 855 | /** 856 | * Convert an arg string to an array of args. Handles escaping 857 | * 858 | * @param argString string of arguments 859 | * @returns string[] array of arguments 860 | */ 861 | function argStringToArray(argString) { 862 | const args = []; 863 | let inQuotes = false; 864 | let escaped = false; 865 | let arg = ''; 866 | function append(c) { 867 | // we only escape double quotes. 868 | if (escaped && c !== '"') { 869 | arg += '\\'; 870 | } 871 | arg += c; 872 | escaped = false; 873 | } 874 | for (let i = 0; i < argString.length; i++) { 875 | const c = argString.charAt(i); 876 | if (c === '"') { 877 | if (!escaped) { 878 | inQuotes = !inQuotes; 879 | } 880 | else { 881 | append(c); 882 | } 883 | continue; 884 | } 885 | if (c === '\\' && escaped) { 886 | append(c); 887 | continue; 888 | } 889 | if (c === '\\' && inQuotes) { 890 | escaped = true; 891 | continue; 892 | } 893 | if (c === ' ' && !inQuotes) { 894 | if (arg.length > 0) { 895 | args.push(arg); 896 | arg = ''; 897 | } 898 | continue; 899 | } 900 | append(c); 901 | } 902 | if (arg.length > 0) { 903 | args.push(arg.trim()); 904 | } 905 | return args; 906 | } 907 | exports.argStringToArray = argStringToArray; 908 | class ExecState extends events.EventEmitter { 909 | constructor(options, toolPath) { 910 | super(); 911 | this.processClosed = false; // tracks whether the process has exited and stdio is closed 912 | this.processError = ''; 913 | this.processExitCode = 0; 914 | this.processExited = false; // tracks whether the process has exited 915 | this.processStderr = false; // tracks whether stderr was written to 916 | this.delay = 10000; // 10 seconds 917 | this.done = false; 918 | this.timeout = null; 919 | if (!toolPath) { 920 | throw new Error('toolPath must not be empty'); 921 | } 922 | this.options = options; 923 | this.toolPath = toolPath; 924 | if (options.delay) { 925 | this.delay = options.delay; 926 | } 927 | } 928 | CheckComplete() { 929 | if (this.done) { 930 | return; 931 | } 932 | if (this.processClosed) { 933 | this._setResult(); 934 | } 935 | else if (this.processExited) { 936 | this.timeout = setTimeout(ExecState.HandleTimeout, this.delay, this); 937 | } 938 | } 939 | _debug(message) { 940 | this.emit('debug', message); 941 | } 942 | _setResult() { 943 | // determine whether there is an error 944 | let error; 945 | if (this.processExited) { 946 | if (this.processError) { 947 | error = new Error(`There was an error when attempting to execute the process '${this.toolPath}'. This may indicate the process failed to start. Error: ${this.processError}`); 948 | } 949 | else if (this.processExitCode !== 0 && !this.options.ignoreReturnCode) { 950 | error = new Error(`The process '${this.toolPath}' failed with exit code ${this.processExitCode}`); 951 | } 952 | else if (this.processStderr && this.options.failOnStdErr) { 953 | error = new Error(`The process '${this.toolPath}' failed because one or more lines were written to the STDERR stream`); 954 | } 955 | } 956 | // clear the timeout 957 | if (this.timeout) { 958 | clearTimeout(this.timeout); 959 | this.timeout = null; 960 | } 961 | this.done = true; 962 | this.emit('done', error, this.processExitCode); 963 | } 964 | static HandleTimeout(state) { 965 | if (state.done) { 966 | return; 967 | } 968 | if (!state.processClosed && state.processExited) { 969 | const message = `The STDIO streams did not close within ${state.delay / 970 | 1000} seconds of the exit event from process '${state.toolPath}'. This may indicate a child process inherited the STDIO streams and has not yet exited.`; 971 | state._debug(message); 972 | } 973 | state._setResult(); 974 | } 975 | } 976 | //# sourceMappingURL=toolrunner.js.map 977 | 978 | /***/ }), 979 | 980 | /***/ 16: 981 | /***/ (function(module) { 982 | 983 | module.exports = require("tls"); 984 | 985 | /***/ }), 986 | 987 | /***/ 31: 988 | /***/ (function(module, exports, __webpack_require__) { 989 | 990 | "use strict"; 991 | 992 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 993 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 994 | return new (P || (P = Promise))(function (resolve, reject) { 995 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 996 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 997 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 998 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 999 | }); 1000 | }; 1001 | var __importStar = (this && this.__importStar) || function (mod) { 1002 | if (mod && mod.__esModule) return mod; 1003 | var result = {}; 1004 | if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; 1005 | result["default"] = mod; 1006 | return result; 1007 | }; 1008 | Object.defineProperty(exports, "__esModule", { value: true }); 1009 | const semver = __importStar(__webpack_require__(280)); 1010 | const core_1 = __webpack_require__(470); 1011 | // needs to be require for core node modules to be mocked 1012 | /* eslint @typescript-eslint/no-require-imports: 0 */ 1013 | const os = __webpack_require__(87); 1014 | const cp = __webpack_require__(129); 1015 | const fs = __webpack_require__(747); 1016 | function _findMatch(versionSpec, stable, candidates, archFilter) { 1017 | return __awaiter(this, void 0, void 0, function* () { 1018 | const platFilter = os.platform(); 1019 | let result; 1020 | let match; 1021 | let file; 1022 | for (const candidate of candidates) { 1023 | const version = candidate.version; 1024 | core_1.debug(`check ${version} satisfies ${versionSpec}`); 1025 | if (semver.satisfies(version, versionSpec) && 1026 | (!stable || candidate.stable === stable)) { 1027 | file = candidate.files.find(item => { 1028 | core_1.debug(`${item.arch}===${archFilter} && ${item.platform}===${platFilter}`); 1029 | let chk = item.arch === archFilter && item.platform === platFilter; 1030 | if (chk && item.platform_version) { 1031 | const osVersion = module.exports._getOsVersion(); 1032 | if (osVersion === item.platform_version) { 1033 | chk = true; 1034 | } 1035 | else { 1036 | chk = semver.satisfies(osVersion, item.platform_version); 1037 | } 1038 | } 1039 | return chk; 1040 | }); 1041 | if (file) { 1042 | core_1.debug(`matched ${candidate.version}`); 1043 | match = candidate; 1044 | break; 1045 | } 1046 | } 1047 | } 1048 | if (match && file) { 1049 | // clone since we're mutating the file list to be only the file that matches 1050 | result = Object.assign({}, match); 1051 | result.files = [file]; 1052 | } 1053 | return result; 1054 | }); 1055 | } 1056 | exports._findMatch = _findMatch; 1057 | function _getOsVersion() { 1058 | // TODO: add windows and other linux, arm variants 1059 | // right now filtering on version is only an ubuntu and macos scenario for tools we build for hosted (python) 1060 | const plat = os.platform(); 1061 | let version = ''; 1062 | if (plat === 'darwin') { 1063 | version = cp.execSync('sw_vers -productVersion').toString(); 1064 | } 1065 | else if (plat === 'linux') { 1066 | // lsb_release process not in some containers, readfile 1067 | // Run cat /etc/lsb-release 1068 | // DISTRIB_ID=Ubuntu 1069 | // DISTRIB_RELEASE=18.04 1070 | // DISTRIB_CODENAME=bionic 1071 | // DISTRIB_DESCRIPTION="Ubuntu 18.04.4 LTS" 1072 | const lsbContents = module.exports._readLinuxVersionFile(); 1073 | if (lsbContents) { 1074 | const lines = lsbContents.split('\n'); 1075 | for (const line of lines) { 1076 | const parts = line.split('='); 1077 | if (parts.length === 2 && parts[0].trim() === 'DISTRIB_RELEASE') { 1078 | version = parts[1].trim(); 1079 | break; 1080 | } 1081 | } 1082 | } 1083 | } 1084 | return version; 1085 | } 1086 | exports._getOsVersion = _getOsVersion; 1087 | function _readLinuxVersionFile() { 1088 | const lsbFile = '/etc/lsb-release'; 1089 | let contents = ''; 1090 | if (fs.existsSync(lsbFile)) { 1091 | contents = fs.readFileSync(lsbFile).toString(); 1092 | } 1093 | return contents; 1094 | } 1095 | exports._readLinuxVersionFile = _readLinuxVersionFile; 1096 | //# sourceMappingURL=manifest.js.map 1097 | 1098 | /***/ }), 1099 | 1100 | /***/ 82: 1101 | /***/ (function(__unusedmodule, exports) { 1102 | 1103 | "use strict"; 1104 | 1105 | // We use any as a valid input type 1106 | /* eslint-disable @typescript-eslint/no-explicit-any */ 1107 | Object.defineProperty(exports, "__esModule", { value: true }); 1108 | /** 1109 | * Sanitizes an input into a string so it can be passed into issueCommand safely 1110 | * @param input input to sanitize into a string 1111 | */ 1112 | function toCommandValue(input) { 1113 | if (input === null || input === undefined) { 1114 | return ''; 1115 | } 1116 | else if (typeof input === 'string' || input instanceof String) { 1117 | return input; 1118 | } 1119 | return JSON.stringify(input); 1120 | } 1121 | exports.toCommandValue = toCommandValue; 1122 | //# sourceMappingURL=utils.js.map 1123 | 1124 | /***/ }), 1125 | 1126 | /***/ 87: 1127 | /***/ (function(module) { 1128 | 1129 | module.exports = require("os"); 1130 | 1131 | /***/ }), 1132 | 1133 | /***/ 102: 1134 | /***/ (function(__unusedmodule, exports, __webpack_require__) { 1135 | 1136 | "use strict"; 1137 | 1138 | // For internal use, subject to change. 1139 | var __importStar = (this && this.__importStar) || function (mod) { 1140 | if (mod && mod.__esModule) return mod; 1141 | var result = {}; 1142 | if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; 1143 | result["default"] = mod; 1144 | return result; 1145 | }; 1146 | Object.defineProperty(exports, "__esModule", { value: true }); 1147 | // We use any as a valid input type 1148 | /* eslint-disable @typescript-eslint/no-explicit-any */ 1149 | const fs = __importStar(__webpack_require__(747)); 1150 | const os = __importStar(__webpack_require__(87)); 1151 | const utils_1 = __webpack_require__(82); 1152 | function issueCommand(command, message) { 1153 | const filePath = process.env[`GITHUB_${command}`]; 1154 | if (!filePath) { 1155 | throw new Error(`Unable to find environment variable for file command ${command}`); 1156 | } 1157 | if (!fs.existsSync(filePath)) { 1158 | throw new Error(`Missing file at path: ${filePath}`); 1159 | } 1160 | fs.appendFileSync(filePath, `${utils_1.toCommandValue(message)}${os.EOL}`, { 1161 | encoding: 'utf8' 1162 | }); 1163 | } 1164 | exports.issueCommand = issueCommand; 1165 | //# sourceMappingURL=file-command.js.map 1166 | 1167 | /***/ }), 1168 | 1169 | /***/ 129: 1170 | /***/ (function(module) { 1171 | 1172 | module.exports = require("child_process"); 1173 | 1174 | /***/ }), 1175 | 1176 | /***/ 139: 1177 | /***/ (function(module, __unusedexports, __webpack_require__) { 1178 | 1179 | // Unique ID creation requires a high quality random # generator. In node.js 1180 | // this is pretty straight-forward - we use the crypto API. 1181 | 1182 | var crypto = __webpack_require__(417); 1183 | 1184 | module.exports = function nodeRNG() { 1185 | return crypto.randomBytes(16); 1186 | }; 1187 | 1188 | 1189 | /***/ }), 1190 | 1191 | /***/ 141: 1192 | /***/ (function(__unusedmodule, exports, __webpack_require__) { 1193 | 1194 | "use strict"; 1195 | 1196 | 1197 | var net = __webpack_require__(631); 1198 | var tls = __webpack_require__(16); 1199 | var http = __webpack_require__(605); 1200 | var https = __webpack_require__(211); 1201 | var events = __webpack_require__(614); 1202 | var assert = __webpack_require__(357); 1203 | var util = __webpack_require__(669); 1204 | 1205 | 1206 | exports.httpOverHttp = httpOverHttp; 1207 | exports.httpsOverHttp = httpsOverHttp; 1208 | exports.httpOverHttps = httpOverHttps; 1209 | exports.httpsOverHttps = httpsOverHttps; 1210 | 1211 | 1212 | function httpOverHttp(options) { 1213 | var agent = new TunnelingAgent(options); 1214 | agent.request = http.request; 1215 | return agent; 1216 | } 1217 | 1218 | function httpsOverHttp(options) { 1219 | var agent = new TunnelingAgent(options); 1220 | agent.request = http.request; 1221 | agent.createSocket = createSecureSocket; 1222 | agent.defaultPort = 443; 1223 | return agent; 1224 | } 1225 | 1226 | function httpOverHttps(options) { 1227 | var agent = new TunnelingAgent(options); 1228 | agent.request = https.request; 1229 | return agent; 1230 | } 1231 | 1232 | function httpsOverHttps(options) { 1233 | var agent = new TunnelingAgent(options); 1234 | agent.request = https.request; 1235 | agent.createSocket = createSecureSocket; 1236 | agent.defaultPort = 443; 1237 | return agent; 1238 | } 1239 | 1240 | 1241 | function TunnelingAgent(options) { 1242 | var self = this; 1243 | self.options = options || {}; 1244 | self.proxyOptions = self.options.proxy || {}; 1245 | self.maxSockets = self.options.maxSockets || http.Agent.defaultMaxSockets; 1246 | self.requests = []; 1247 | self.sockets = []; 1248 | 1249 | self.on('free', function onFree(socket, host, port, localAddress) { 1250 | var options = toOptions(host, port, localAddress); 1251 | for (var i = 0, len = self.requests.length; i < len; ++i) { 1252 | var pending = self.requests[i]; 1253 | if (pending.host === options.host && pending.port === options.port) { 1254 | // Detect the request to connect same origin server, 1255 | // reuse the connection. 1256 | self.requests.splice(i, 1); 1257 | pending.request.onSocket(socket); 1258 | return; 1259 | } 1260 | } 1261 | socket.destroy(); 1262 | self.removeSocket(socket); 1263 | }); 1264 | } 1265 | util.inherits(TunnelingAgent, events.EventEmitter); 1266 | 1267 | TunnelingAgent.prototype.addRequest = function addRequest(req, host, port, localAddress) { 1268 | var self = this; 1269 | var options = mergeOptions({request: req}, self.options, toOptions(host, port, localAddress)); 1270 | 1271 | if (self.sockets.length >= this.maxSockets) { 1272 | // We are over limit so we'll add it to the queue. 1273 | self.requests.push(options); 1274 | return; 1275 | } 1276 | 1277 | // If we are under maxSockets create a new one. 1278 | self.createSocket(options, function(socket) { 1279 | socket.on('free', onFree); 1280 | socket.on('close', onCloseOrRemove); 1281 | socket.on('agentRemove', onCloseOrRemove); 1282 | req.onSocket(socket); 1283 | 1284 | function onFree() { 1285 | self.emit('free', socket, options); 1286 | } 1287 | 1288 | function onCloseOrRemove(err) { 1289 | self.removeSocket(socket); 1290 | socket.removeListener('free', onFree); 1291 | socket.removeListener('close', onCloseOrRemove); 1292 | socket.removeListener('agentRemove', onCloseOrRemove); 1293 | } 1294 | }); 1295 | }; 1296 | 1297 | TunnelingAgent.prototype.createSocket = function createSocket(options, cb) { 1298 | var self = this; 1299 | var placeholder = {}; 1300 | self.sockets.push(placeholder); 1301 | 1302 | var connectOptions = mergeOptions({}, self.proxyOptions, { 1303 | method: 'CONNECT', 1304 | path: options.host + ':' + options.port, 1305 | agent: false, 1306 | headers: { 1307 | host: options.host + ':' + options.port 1308 | } 1309 | }); 1310 | if (options.localAddress) { 1311 | connectOptions.localAddress = options.localAddress; 1312 | } 1313 | if (connectOptions.proxyAuth) { 1314 | connectOptions.headers = connectOptions.headers || {}; 1315 | connectOptions.headers['Proxy-Authorization'] = 'Basic ' + 1316 | new Buffer(connectOptions.proxyAuth).toString('base64'); 1317 | } 1318 | 1319 | debug('making CONNECT request'); 1320 | var connectReq = self.request(connectOptions); 1321 | connectReq.useChunkedEncodingByDefault = false; // for v0.6 1322 | connectReq.once('response', onResponse); // for v0.6 1323 | connectReq.once('upgrade', onUpgrade); // for v0.6 1324 | connectReq.once('connect', onConnect); // for v0.7 or later 1325 | connectReq.once('error', onError); 1326 | connectReq.end(); 1327 | 1328 | function onResponse(res) { 1329 | // Very hacky. This is necessary to avoid http-parser leaks. 1330 | res.upgrade = true; 1331 | } 1332 | 1333 | function onUpgrade(res, socket, head) { 1334 | // Hacky. 1335 | process.nextTick(function() { 1336 | onConnect(res, socket, head); 1337 | }); 1338 | } 1339 | 1340 | function onConnect(res, socket, head) { 1341 | connectReq.removeAllListeners(); 1342 | socket.removeAllListeners(); 1343 | 1344 | if (res.statusCode !== 200) { 1345 | debug('tunneling socket could not be established, statusCode=%d', 1346 | res.statusCode); 1347 | socket.destroy(); 1348 | var error = new Error('tunneling socket could not be established, ' + 1349 | 'statusCode=' + res.statusCode); 1350 | error.code = 'ECONNRESET'; 1351 | options.request.emit('error', error); 1352 | self.removeSocket(placeholder); 1353 | return; 1354 | } 1355 | if (head.length > 0) { 1356 | debug('got illegal response body from proxy'); 1357 | socket.destroy(); 1358 | var error = new Error('got illegal response body from proxy'); 1359 | error.code = 'ECONNRESET'; 1360 | options.request.emit('error', error); 1361 | self.removeSocket(placeholder); 1362 | return; 1363 | } 1364 | debug('tunneling connection has established'); 1365 | self.sockets[self.sockets.indexOf(placeholder)] = socket; 1366 | return cb(socket); 1367 | } 1368 | 1369 | function onError(cause) { 1370 | connectReq.removeAllListeners(); 1371 | 1372 | debug('tunneling socket could not be established, cause=%s\n', 1373 | cause.message, cause.stack); 1374 | var error = new Error('tunneling socket could not be established, ' + 1375 | 'cause=' + cause.message); 1376 | error.code = 'ECONNRESET'; 1377 | options.request.emit('error', error); 1378 | self.removeSocket(placeholder); 1379 | } 1380 | }; 1381 | 1382 | TunnelingAgent.prototype.removeSocket = function removeSocket(socket) { 1383 | var pos = this.sockets.indexOf(socket) 1384 | if (pos === -1) { 1385 | return; 1386 | } 1387 | this.sockets.splice(pos, 1); 1388 | 1389 | var pending = this.requests.shift(); 1390 | if (pending) { 1391 | // If we have pending requests and a socket gets closed a new one 1392 | // needs to be created to take over in the pool for the one that closed. 1393 | this.createSocket(pending, function(socket) { 1394 | pending.request.onSocket(socket); 1395 | }); 1396 | } 1397 | }; 1398 | 1399 | function createSecureSocket(options, cb) { 1400 | var self = this; 1401 | TunnelingAgent.prototype.createSocket.call(self, options, function(socket) { 1402 | var hostHeader = options.request.getHeader('host'); 1403 | var tlsOptions = mergeOptions({}, self.options, { 1404 | socket: socket, 1405 | servername: hostHeader ? hostHeader.replace(/:.*$/, '') : options.host 1406 | }); 1407 | 1408 | // 0 is dummy port for v0.6 1409 | var secureSocket = tls.connect(0, tlsOptions); 1410 | self.sockets[self.sockets.indexOf(socket)] = secureSocket; 1411 | cb(secureSocket); 1412 | }); 1413 | } 1414 | 1415 | 1416 | function toOptions(host, port, localAddress) { 1417 | if (typeof host === 'string') { // since v0.10 1418 | return { 1419 | host: host, 1420 | port: port, 1421 | localAddress: localAddress 1422 | }; 1423 | } 1424 | return host; // for v0.11 or later 1425 | } 1426 | 1427 | function mergeOptions(target) { 1428 | for (var i = 1, len = arguments.length; i < len; ++i) { 1429 | var overrides = arguments[i]; 1430 | if (typeof overrides === 'object') { 1431 | var keys = Object.keys(overrides); 1432 | for (var j = 0, keyLen = keys.length; j < keyLen; ++j) { 1433 | var k = keys[j]; 1434 | if (overrides[k] !== undefined) { 1435 | target[k] = overrides[k]; 1436 | } 1437 | } 1438 | } 1439 | } 1440 | return target; 1441 | } 1442 | 1443 | 1444 | var debug; 1445 | if (process.env.NODE_DEBUG && /\btunnel\b/.test(process.env.NODE_DEBUG)) { 1446 | debug = function() { 1447 | var args = Array.prototype.slice.call(arguments); 1448 | if (typeof args[0] === 'string') { 1449 | args[0] = 'TUNNEL: ' + args[0]; 1450 | } else { 1451 | args.unshift('TUNNEL:'); 1452 | } 1453 | console.error.apply(console, args); 1454 | } 1455 | } else { 1456 | debug = function() {}; 1457 | } 1458 | exports.debug = debug; // for test 1459 | 1460 | 1461 | /***/ }), 1462 | 1463 | /***/ 211: 1464 | /***/ (function(module) { 1465 | 1466 | module.exports = require("https"); 1467 | 1468 | /***/ }), 1469 | 1470 | /***/ 280: 1471 | /***/ (function(module, exports) { 1472 | 1473 | exports = module.exports = SemVer 1474 | 1475 | var debug 1476 | /* istanbul ignore next */ 1477 | if (typeof process === 'object' && 1478 | process.env && 1479 | process.env.NODE_DEBUG && 1480 | /\bsemver\b/i.test(process.env.NODE_DEBUG)) { 1481 | debug = function () { 1482 | var args = Array.prototype.slice.call(arguments, 0) 1483 | args.unshift('SEMVER') 1484 | console.log.apply(console, args) 1485 | } 1486 | } else { 1487 | debug = function () {} 1488 | } 1489 | 1490 | // Note: this is the semver.org version of the spec that it implements 1491 | // Not necessarily the package version of this code. 1492 | exports.SEMVER_SPEC_VERSION = '2.0.0' 1493 | 1494 | var MAX_LENGTH = 256 1495 | var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || 1496 | /* istanbul ignore next */ 9007199254740991 1497 | 1498 | // Max safe segment length for coercion. 1499 | var MAX_SAFE_COMPONENT_LENGTH = 16 1500 | 1501 | // The actual regexps go on exports.re 1502 | var re = exports.re = [] 1503 | var src = exports.src = [] 1504 | var t = exports.tokens = {} 1505 | var R = 0 1506 | 1507 | function tok (n) { 1508 | t[n] = R++ 1509 | } 1510 | 1511 | // The following Regular Expressions can be used for tokenizing, 1512 | // validating, and parsing SemVer version strings. 1513 | 1514 | // ## Numeric Identifier 1515 | // A single `0`, or a non-zero digit followed by zero or more digits. 1516 | 1517 | tok('NUMERICIDENTIFIER') 1518 | src[t.NUMERICIDENTIFIER] = '0|[1-9]\\d*' 1519 | tok('NUMERICIDENTIFIERLOOSE') 1520 | src[t.NUMERICIDENTIFIERLOOSE] = '[0-9]+' 1521 | 1522 | // ## Non-numeric Identifier 1523 | // Zero or more digits, followed by a letter or hyphen, and then zero or 1524 | // more letters, digits, or hyphens. 1525 | 1526 | tok('NONNUMERICIDENTIFIER') 1527 | src[t.NONNUMERICIDENTIFIER] = '\\d*[a-zA-Z-][a-zA-Z0-9-]*' 1528 | 1529 | // ## Main Version 1530 | // Three dot-separated numeric identifiers. 1531 | 1532 | tok('MAINVERSION') 1533 | src[t.MAINVERSION] = '(' + src[t.NUMERICIDENTIFIER] + ')\\.' + 1534 | '(' + src[t.NUMERICIDENTIFIER] + ')\\.' + 1535 | '(' + src[t.NUMERICIDENTIFIER] + ')' 1536 | 1537 | tok('MAINVERSIONLOOSE') 1538 | src[t.MAINVERSIONLOOSE] = '(' + src[t.NUMERICIDENTIFIERLOOSE] + ')\\.' + 1539 | '(' + src[t.NUMERICIDENTIFIERLOOSE] + ')\\.' + 1540 | '(' + src[t.NUMERICIDENTIFIERLOOSE] + ')' 1541 | 1542 | // ## Pre-release Version Identifier 1543 | // A numeric identifier, or a non-numeric identifier. 1544 | 1545 | tok('PRERELEASEIDENTIFIER') 1546 | src[t.PRERELEASEIDENTIFIER] = '(?:' + src[t.NUMERICIDENTIFIER] + 1547 | '|' + src[t.NONNUMERICIDENTIFIER] + ')' 1548 | 1549 | tok('PRERELEASEIDENTIFIERLOOSE') 1550 | src[t.PRERELEASEIDENTIFIERLOOSE] = '(?:' + src[t.NUMERICIDENTIFIERLOOSE] + 1551 | '|' + src[t.NONNUMERICIDENTIFIER] + ')' 1552 | 1553 | // ## Pre-release Version 1554 | // Hyphen, followed by one or more dot-separated pre-release version 1555 | // identifiers. 1556 | 1557 | tok('PRERELEASE') 1558 | src[t.PRERELEASE] = '(?:-(' + src[t.PRERELEASEIDENTIFIER] + 1559 | '(?:\\.' + src[t.PRERELEASEIDENTIFIER] + ')*))' 1560 | 1561 | tok('PRERELEASELOOSE') 1562 | src[t.PRERELEASELOOSE] = '(?:-?(' + src[t.PRERELEASEIDENTIFIERLOOSE] + 1563 | '(?:\\.' + src[t.PRERELEASEIDENTIFIERLOOSE] + ')*))' 1564 | 1565 | // ## Build Metadata Identifier 1566 | // Any combination of digits, letters, or hyphens. 1567 | 1568 | tok('BUILDIDENTIFIER') 1569 | src[t.BUILDIDENTIFIER] = '[0-9A-Za-z-]+' 1570 | 1571 | // ## Build Metadata 1572 | // Plus sign, followed by one or more period-separated build metadata 1573 | // identifiers. 1574 | 1575 | tok('BUILD') 1576 | src[t.BUILD] = '(?:\\+(' + src[t.BUILDIDENTIFIER] + 1577 | '(?:\\.' + src[t.BUILDIDENTIFIER] + ')*))' 1578 | 1579 | // ## Full Version String 1580 | // A main version, followed optionally by a pre-release version and 1581 | // build metadata. 1582 | 1583 | // Note that the only major, minor, patch, and pre-release sections of 1584 | // the version string are capturing groups. The build metadata is not a 1585 | // capturing group, because it should not ever be used in version 1586 | // comparison. 1587 | 1588 | tok('FULL') 1589 | tok('FULLPLAIN') 1590 | src[t.FULLPLAIN] = 'v?' + src[t.MAINVERSION] + 1591 | src[t.PRERELEASE] + '?' + 1592 | src[t.BUILD] + '?' 1593 | 1594 | src[t.FULL] = '^' + src[t.FULLPLAIN] + '$' 1595 | 1596 | // like full, but allows v1.2.3 and =1.2.3, which people do sometimes. 1597 | // also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty 1598 | // common in the npm registry. 1599 | tok('LOOSEPLAIN') 1600 | src[t.LOOSEPLAIN] = '[v=\\s]*' + src[t.MAINVERSIONLOOSE] + 1601 | src[t.PRERELEASELOOSE] + '?' + 1602 | src[t.BUILD] + '?' 1603 | 1604 | tok('LOOSE') 1605 | src[t.LOOSE] = '^' + src[t.LOOSEPLAIN] + '$' 1606 | 1607 | tok('GTLT') 1608 | src[t.GTLT] = '((?:<|>)?=?)' 1609 | 1610 | // Something like "2.*" or "1.2.x". 1611 | // Note that "x.x" is a valid xRange identifer, meaning "any version" 1612 | // Only the first item is strictly required. 1613 | tok('XRANGEIDENTIFIERLOOSE') 1614 | src[t.XRANGEIDENTIFIERLOOSE] = src[t.NUMERICIDENTIFIERLOOSE] + '|x|X|\\*' 1615 | tok('XRANGEIDENTIFIER') 1616 | src[t.XRANGEIDENTIFIER] = src[t.NUMERICIDENTIFIER] + '|x|X|\\*' 1617 | 1618 | tok('XRANGEPLAIN') 1619 | src[t.XRANGEPLAIN] = '[v=\\s]*(' + src[t.XRANGEIDENTIFIER] + ')' + 1620 | '(?:\\.(' + src[t.XRANGEIDENTIFIER] + ')' + 1621 | '(?:\\.(' + src[t.XRANGEIDENTIFIER] + ')' + 1622 | '(?:' + src[t.PRERELEASE] + ')?' + 1623 | src[t.BUILD] + '?' + 1624 | ')?)?' 1625 | 1626 | tok('XRANGEPLAINLOOSE') 1627 | src[t.XRANGEPLAINLOOSE] = '[v=\\s]*(' + src[t.XRANGEIDENTIFIERLOOSE] + ')' + 1628 | '(?:\\.(' + src[t.XRANGEIDENTIFIERLOOSE] + ')' + 1629 | '(?:\\.(' + src[t.XRANGEIDENTIFIERLOOSE] + ')' + 1630 | '(?:' + src[t.PRERELEASELOOSE] + ')?' + 1631 | src[t.BUILD] + '?' + 1632 | ')?)?' 1633 | 1634 | tok('XRANGE') 1635 | src[t.XRANGE] = '^' + src[t.GTLT] + '\\s*' + src[t.XRANGEPLAIN] + '$' 1636 | tok('XRANGELOOSE') 1637 | src[t.XRANGELOOSE] = '^' + src[t.GTLT] + '\\s*' + src[t.XRANGEPLAINLOOSE] + '$' 1638 | 1639 | // Coercion. 1640 | // Extract anything that could conceivably be a part of a valid semver 1641 | tok('COERCE') 1642 | src[t.COERCE] = '(^|[^\\d])' + 1643 | '(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '})' + 1644 | '(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' + 1645 | '(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' + 1646 | '(?:$|[^\\d])' 1647 | tok('COERCERTL') 1648 | re[t.COERCERTL] = new RegExp(src[t.COERCE], 'g') 1649 | 1650 | // Tilde ranges. 1651 | // Meaning is "reasonably at or greater than" 1652 | tok('LONETILDE') 1653 | src[t.LONETILDE] = '(?:~>?)' 1654 | 1655 | tok('TILDETRIM') 1656 | src[t.TILDETRIM] = '(\\s*)' + src[t.LONETILDE] + '\\s+' 1657 | re[t.TILDETRIM] = new RegExp(src[t.TILDETRIM], 'g') 1658 | var tildeTrimReplace = '$1~' 1659 | 1660 | tok('TILDE') 1661 | src[t.TILDE] = '^' + src[t.LONETILDE] + src[t.XRANGEPLAIN] + '$' 1662 | tok('TILDELOOSE') 1663 | src[t.TILDELOOSE] = '^' + src[t.LONETILDE] + src[t.XRANGEPLAINLOOSE] + '$' 1664 | 1665 | // Caret ranges. 1666 | // Meaning is "at least and backwards compatible with" 1667 | tok('LONECARET') 1668 | src[t.LONECARET] = '(?:\\^)' 1669 | 1670 | tok('CARETTRIM') 1671 | src[t.CARETTRIM] = '(\\s*)' + src[t.LONECARET] + '\\s+' 1672 | re[t.CARETTRIM] = new RegExp(src[t.CARETTRIM], 'g') 1673 | var caretTrimReplace = '$1^' 1674 | 1675 | tok('CARET') 1676 | src[t.CARET] = '^' + src[t.LONECARET] + src[t.XRANGEPLAIN] + '$' 1677 | tok('CARETLOOSE') 1678 | src[t.CARETLOOSE] = '^' + src[t.LONECARET] + src[t.XRANGEPLAINLOOSE] + '$' 1679 | 1680 | // A simple gt/lt/eq thing, or just "" to indicate "any version" 1681 | tok('COMPARATORLOOSE') 1682 | src[t.COMPARATORLOOSE] = '^' + src[t.GTLT] + '\\s*(' + src[t.LOOSEPLAIN] + ')$|^$' 1683 | tok('COMPARATOR') 1684 | src[t.COMPARATOR] = '^' + src[t.GTLT] + '\\s*(' + src[t.FULLPLAIN] + ')$|^$' 1685 | 1686 | // An expression to strip any whitespace between the gtlt and the thing 1687 | // it modifies, so that `> 1.2.3` ==> `>1.2.3` 1688 | tok('COMPARATORTRIM') 1689 | src[t.COMPARATORTRIM] = '(\\s*)' + src[t.GTLT] + 1690 | '\\s*(' + src[t.LOOSEPLAIN] + '|' + src[t.XRANGEPLAIN] + ')' 1691 | 1692 | // this one has to use the /g flag 1693 | re[t.COMPARATORTRIM] = new RegExp(src[t.COMPARATORTRIM], 'g') 1694 | var comparatorTrimReplace = '$1$2$3' 1695 | 1696 | // Something like `1.2.3 - 1.2.4` 1697 | // Note that these all use the loose form, because they'll be 1698 | // checked against either the strict or loose comparator form 1699 | // later. 1700 | tok('HYPHENRANGE') 1701 | src[t.HYPHENRANGE] = '^\\s*(' + src[t.XRANGEPLAIN] + ')' + 1702 | '\\s+-\\s+' + 1703 | '(' + src[t.XRANGEPLAIN] + ')' + 1704 | '\\s*$' 1705 | 1706 | tok('HYPHENRANGELOOSE') 1707 | src[t.HYPHENRANGELOOSE] = '^\\s*(' + src[t.XRANGEPLAINLOOSE] + ')' + 1708 | '\\s+-\\s+' + 1709 | '(' + src[t.XRANGEPLAINLOOSE] + ')' + 1710 | '\\s*$' 1711 | 1712 | // Star ranges basically just allow anything at all. 1713 | tok('STAR') 1714 | src[t.STAR] = '(<|>)?=?\\s*\\*' 1715 | 1716 | // Compile to actual regexp objects. 1717 | // All are flag-free, unless they were created above with a flag. 1718 | for (var i = 0; i < R; i++) { 1719 | debug(i, src[i]) 1720 | if (!re[i]) { 1721 | re[i] = new RegExp(src[i]) 1722 | } 1723 | } 1724 | 1725 | exports.parse = parse 1726 | function parse (version, options) { 1727 | if (!options || typeof options !== 'object') { 1728 | options = { 1729 | loose: !!options, 1730 | includePrerelease: false 1731 | } 1732 | } 1733 | 1734 | if (version instanceof SemVer) { 1735 | return version 1736 | } 1737 | 1738 | if (typeof version !== 'string') { 1739 | return null 1740 | } 1741 | 1742 | if (version.length > MAX_LENGTH) { 1743 | return null 1744 | } 1745 | 1746 | var r = options.loose ? re[t.LOOSE] : re[t.FULL] 1747 | if (!r.test(version)) { 1748 | return null 1749 | } 1750 | 1751 | try { 1752 | return new SemVer(version, options) 1753 | } catch (er) { 1754 | return null 1755 | } 1756 | } 1757 | 1758 | exports.valid = valid 1759 | function valid (version, options) { 1760 | var v = parse(version, options) 1761 | return v ? v.version : null 1762 | } 1763 | 1764 | exports.clean = clean 1765 | function clean (version, options) { 1766 | var s = parse(version.trim().replace(/^[=v]+/, ''), options) 1767 | return s ? s.version : null 1768 | } 1769 | 1770 | exports.SemVer = SemVer 1771 | 1772 | function SemVer (version, options) { 1773 | if (!options || typeof options !== 'object') { 1774 | options = { 1775 | loose: !!options, 1776 | includePrerelease: false 1777 | } 1778 | } 1779 | if (version instanceof SemVer) { 1780 | if (version.loose === options.loose) { 1781 | return version 1782 | } else { 1783 | version = version.version 1784 | } 1785 | } else if (typeof version !== 'string') { 1786 | throw new TypeError('Invalid Version: ' + version) 1787 | } 1788 | 1789 | if (version.length > MAX_LENGTH) { 1790 | throw new TypeError('version is longer than ' + MAX_LENGTH + ' characters') 1791 | } 1792 | 1793 | if (!(this instanceof SemVer)) { 1794 | return new SemVer(version, options) 1795 | } 1796 | 1797 | debug('SemVer', version, options) 1798 | this.options = options 1799 | this.loose = !!options.loose 1800 | 1801 | var m = version.trim().match(options.loose ? re[t.LOOSE] : re[t.FULL]) 1802 | 1803 | if (!m) { 1804 | throw new TypeError('Invalid Version: ' + version) 1805 | } 1806 | 1807 | this.raw = version 1808 | 1809 | // these are actually numbers 1810 | this.major = +m[1] 1811 | this.minor = +m[2] 1812 | this.patch = +m[3] 1813 | 1814 | if (this.major > MAX_SAFE_INTEGER || this.major < 0) { 1815 | throw new TypeError('Invalid major version') 1816 | } 1817 | 1818 | if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) { 1819 | throw new TypeError('Invalid minor version') 1820 | } 1821 | 1822 | if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) { 1823 | throw new TypeError('Invalid patch version') 1824 | } 1825 | 1826 | // numberify any prerelease numeric ids 1827 | if (!m[4]) { 1828 | this.prerelease = [] 1829 | } else { 1830 | this.prerelease = m[4].split('.').map(function (id) { 1831 | if (/^[0-9]+$/.test(id)) { 1832 | var num = +id 1833 | if (num >= 0 && num < MAX_SAFE_INTEGER) { 1834 | return num 1835 | } 1836 | } 1837 | return id 1838 | }) 1839 | } 1840 | 1841 | this.build = m[5] ? m[5].split('.') : [] 1842 | this.format() 1843 | } 1844 | 1845 | SemVer.prototype.format = function () { 1846 | this.version = this.major + '.' + this.minor + '.' + this.patch 1847 | if (this.prerelease.length) { 1848 | this.version += '-' + this.prerelease.join('.') 1849 | } 1850 | return this.version 1851 | } 1852 | 1853 | SemVer.prototype.toString = function () { 1854 | return this.version 1855 | } 1856 | 1857 | SemVer.prototype.compare = function (other) { 1858 | debug('SemVer.compare', this.version, this.options, other) 1859 | if (!(other instanceof SemVer)) { 1860 | other = new SemVer(other, this.options) 1861 | } 1862 | 1863 | return this.compareMain(other) || this.comparePre(other) 1864 | } 1865 | 1866 | SemVer.prototype.compareMain = function (other) { 1867 | if (!(other instanceof SemVer)) { 1868 | other = new SemVer(other, this.options) 1869 | } 1870 | 1871 | return compareIdentifiers(this.major, other.major) || 1872 | compareIdentifiers(this.minor, other.minor) || 1873 | compareIdentifiers(this.patch, other.patch) 1874 | } 1875 | 1876 | SemVer.prototype.comparePre = function (other) { 1877 | if (!(other instanceof SemVer)) { 1878 | other = new SemVer(other, this.options) 1879 | } 1880 | 1881 | // NOT having a prerelease is > having one 1882 | if (this.prerelease.length && !other.prerelease.length) { 1883 | return -1 1884 | } else if (!this.prerelease.length && other.prerelease.length) { 1885 | return 1 1886 | } else if (!this.prerelease.length && !other.prerelease.length) { 1887 | return 0 1888 | } 1889 | 1890 | var i = 0 1891 | do { 1892 | var a = this.prerelease[i] 1893 | var b = other.prerelease[i] 1894 | debug('prerelease compare', i, a, b) 1895 | if (a === undefined && b === undefined) { 1896 | return 0 1897 | } else if (b === undefined) { 1898 | return 1 1899 | } else if (a === undefined) { 1900 | return -1 1901 | } else if (a === b) { 1902 | continue 1903 | } else { 1904 | return compareIdentifiers(a, b) 1905 | } 1906 | } while (++i) 1907 | } 1908 | 1909 | SemVer.prototype.compareBuild = function (other) { 1910 | if (!(other instanceof SemVer)) { 1911 | other = new SemVer(other, this.options) 1912 | } 1913 | 1914 | var i = 0 1915 | do { 1916 | var a = this.build[i] 1917 | var b = other.build[i] 1918 | debug('prerelease compare', i, a, b) 1919 | if (a === undefined && b === undefined) { 1920 | return 0 1921 | } else if (b === undefined) { 1922 | return 1 1923 | } else if (a === undefined) { 1924 | return -1 1925 | } else if (a === b) { 1926 | continue 1927 | } else { 1928 | return compareIdentifiers(a, b) 1929 | } 1930 | } while (++i) 1931 | } 1932 | 1933 | // preminor will bump the version up to the next minor release, and immediately 1934 | // down to pre-release. premajor and prepatch work the same way. 1935 | SemVer.prototype.inc = function (release, identifier) { 1936 | switch (release) { 1937 | case 'premajor': 1938 | this.prerelease.length = 0 1939 | this.patch = 0 1940 | this.minor = 0 1941 | this.major++ 1942 | this.inc('pre', identifier) 1943 | break 1944 | case 'preminor': 1945 | this.prerelease.length = 0 1946 | this.patch = 0 1947 | this.minor++ 1948 | this.inc('pre', identifier) 1949 | break 1950 | case 'prepatch': 1951 | // If this is already a prerelease, it will bump to the next version 1952 | // drop any prereleases that might already exist, since they are not 1953 | // relevant at this point. 1954 | this.prerelease.length = 0 1955 | this.inc('patch', identifier) 1956 | this.inc('pre', identifier) 1957 | break 1958 | // If the input is a non-prerelease version, this acts the same as 1959 | // prepatch. 1960 | case 'prerelease': 1961 | if (this.prerelease.length === 0) { 1962 | this.inc('patch', identifier) 1963 | } 1964 | this.inc('pre', identifier) 1965 | break 1966 | 1967 | case 'major': 1968 | // If this is a pre-major version, bump up to the same major version. 1969 | // Otherwise increment major. 1970 | // 1.0.0-5 bumps to 1.0.0 1971 | // 1.1.0 bumps to 2.0.0 1972 | if (this.minor !== 0 || 1973 | this.patch !== 0 || 1974 | this.prerelease.length === 0) { 1975 | this.major++ 1976 | } 1977 | this.minor = 0 1978 | this.patch = 0 1979 | this.prerelease = [] 1980 | break 1981 | case 'minor': 1982 | // If this is a pre-minor version, bump up to the same minor version. 1983 | // Otherwise increment minor. 1984 | // 1.2.0-5 bumps to 1.2.0 1985 | // 1.2.1 bumps to 1.3.0 1986 | if (this.patch !== 0 || this.prerelease.length === 0) { 1987 | this.minor++ 1988 | } 1989 | this.patch = 0 1990 | this.prerelease = [] 1991 | break 1992 | case 'patch': 1993 | // If this is not a pre-release version, it will increment the patch. 1994 | // If it is a pre-release it will bump up to the same patch version. 1995 | // 1.2.0-5 patches to 1.2.0 1996 | // 1.2.0 patches to 1.2.1 1997 | if (this.prerelease.length === 0) { 1998 | this.patch++ 1999 | } 2000 | this.prerelease = [] 2001 | break 2002 | // This probably shouldn't be used publicly. 2003 | // 1.0.0 "pre" would become 1.0.0-0 which is the wrong direction. 2004 | case 'pre': 2005 | if (this.prerelease.length === 0) { 2006 | this.prerelease = [0] 2007 | } else { 2008 | var i = this.prerelease.length 2009 | while (--i >= 0) { 2010 | if (typeof this.prerelease[i] === 'number') { 2011 | this.prerelease[i]++ 2012 | i = -2 2013 | } 2014 | } 2015 | if (i === -1) { 2016 | // didn't increment anything 2017 | this.prerelease.push(0) 2018 | } 2019 | } 2020 | if (identifier) { 2021 | // 1.2.0-beta.1 bumps to 1.2.0-beta.2, 2022 | // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0 2023 | if (this.prerelease[0] === identifier) { 2024 | if (isNaN(this.prerelease[1])) { 2025 | this.prerelease = [identifier, 0] 2026 | } 2027 | } else { 2028 | this.prerelease = [identifier, 0] 2029 | } 2030 | } 2031 | break 2032 | 2033 | default: 2034 | throw new Error('invalid increment argument: ' + release) 2035 | } 2036 | this.format() 2037 | this.raw = this.version 2038 | return this 2039 | } 2040 | 2041 | exports.inc = inc 2042 | function inc (version, release, loose, identifier) { 2043 | if (typeof (loose) === 'string') { 2044 | identifier = loose 2045 | loose = undefined 2046 | } 2047 | 2048 | try { 2049 | return new SemVer(version, loose).inc(release, identifier).version 2050 | } catch (er) { 2051 | return null 2052 | } 2053 | } 2054 | 2055 | exports.diff = diff 2056 | function diff (version1, version2) { 2057 | if (eq(version1, version2)) { 2058 | return null 2059 | } else { 2060 | var v1 = parse(version1) 2061 | var v2 = parse(version2) 2062 | var prefix = '' 2063 | if (v1.prerelease.length || v2.prerelease.length) { 2064 | prefix = 'pre' 2065 | var defaultResult = 'prerelease' 2066 | } 2067 | for (var key in v1) { 2068 | if (key === 'major' || key === 'minor' || key === 'patch') { 2069 | if (v1[key] !== v2[key]) { 2070 | return prefix + key 2071 | } 2072 | } 2073 | } 2074 | return defaultResult // may be undefined 2075 | } 2076 | } 2077 | 2078 | exports.compareIdentifiers = compareIdentifiers 2079 | 2080 | var numeric = /^[0-9]+$/ 2081 | function compareIdentifiers (a, b) { 2082 | var anum = numeric.test(a) 2083 | var bnum = numeric.test(b) 2084 | 2085 | if (anum && bnum) { 2086 | a = +a 2087 | b = +b 2088 | } 2089 | 2090 | return a === b ? 0 2091 | : (anum && !bnum) ? -1 2092 | : (bnum && !anum) ? 1 2093 | : a < b ? -1 2094 | : 1 2095 | } 2096 | 2097 | exports.rcompareIdentifiers = rcompareIdentifiers 2098 | function rcompareIdentifiers (a, b) { 2099 | return compareIdentifiers(b, a) 2100 | } 2101 | 2102 | exports.major = major 2103 | function major (a, loose) { 2104 | return new SemVer(a, loose).major 2105 | } 2106 | 2107 | exports.minor = minor 2108 | function minor (a, loose) { 2109 | return new SemVer(a, loose).minor 2110 | } 2111 | 2112 | exports.patch = patch 2113 | function patch (a, loose) { 2114 | return new SemVer(a, loose).patch 2115 | } 2116 | 2117 | exports.compare = compare 2118 | function compare (a, b, loose) { 2119 | return new SemVer(a, loose).compare(new SemVer(b, loose)) 2120 | } 2121 | 2122 | exports.compareLoose = compareLoose 2123 | function compareLoose (a, b) { 2124 | return compare(a, b, true) 2125 | } 2126 | 2127 | exports.compareBuild = compareBuild 2128 | function compareBuild (a, b, loose) { 2129 | var versionA = new SemVer(a, loose) 2130 | var versionB = new SemVer(b, loose) 2131 | return versionA.compare(versionB) || versionA.compareBuild(versionB) 2132 | } 2133 | 2134 | exports.rcompare = rcompare 2135 | function rcompare (a, b, loose) { 2136 | return compare(b, a, loose) 2137 | } 2138 | 2139 | exports.sort = sort 2140 | function sort (list, loose) { 2141 | return list.sort(function (a, b) { 2142 | return exports.compareBuild(a, b, loose) 2143 | }) 2144 | } 2145 | 2146 | exports.rsort = rsort 2147 | function rsort (list, loose) { 2148 | return list.sort(function (a, b) { 2149 | return exports.compareBuild(b, a, loose) 2150 | }) 2151 | } 2152 | 2153 | exports.gt = gt 2154 | function gt (a, b, loose) { 2155 | return compare(a, b, loose) > 0 2156 | } 2157 | 2158 | exports.lt = lt 2159 | function lt (a, b, loose) { 2160 | return compare(a, b, loose) < 0 2161 | } 2162 | 2163 | exports.eq = eq 2164 | function eq (a, b, loose) { 2165 | return compare(a, b, loose) === 0 2166 | } 2167 | 2168 | exports.neq = neq 2169 | function neq (a, b, loose) { 2170 | return compare(a, b, loose) !== 0 2171 | } 2172 | 2173 | exports.gte = gte 2174 | function gte (a, b, loose) { 2175 | return compare(a, b, loose) >= 0 2176 | } 2177 | 2178 | exports.lte = lte 2179 | function lte (a, b, loose) { 2180 | return compare(a, b, loose) <= 0 2181 | } 2182 | 2183 | exports.cmp = cmp 2184 | function cmp (a, op, b, loose) { 2185 | switch (op) { 2186 | case '===': 2187 | if (typeof a === 'object') 2188 | a = a.version 2189 | if (typeof b === 'object') 2190 | b = b.version 2191 | return a === b 2192 | 2193 | case '!==': 2194 | if (typeof a === 'object') 2195 | a = a.version 2196 | if (typeof b === 'object') 2197 | b = b.version 2198 | return a !== b 2199 | 2200 | case '': 2201 | case '=': 2202 | case '==': 2203 | return eq(a, b, loose) 2204 | 2205 | case '!=': 2206 | return neq(a, b, loose) 2207 | 2208 | case '>': 2209 | return gt(a, b, loose) 2210 | 2211 | case '>=': 2212 | return gte(a, b, loose) 2213 | 2214 | case '<': 2215 | return lt(a, b, loose) 2216 | 2217 | case '<=': 2218 | return lte(a, b, loose) 2219 | 2220 | default: 2221 | throw new TypeError('Invalid operator: ' + op) 2222 | } 2223 | } 2224 | 2225 | exports.Comparator = Comparator 2226 | function Comparator (comp, options) { 2227 | if (!options || typeof options !== 'object') { 2228 | options = { 2229 | loose: !!options, 2230 | includePrerelease: false 2231 | } 2232 | } 2233 | 2234 | if (comp instanceof Comparator) { 2235 | if (comp.loose === !!options.loose) { 2236 | return comp 2237 | } else { 2238 | comp = comp.value 2239 | } 2240 | } 2241 | 2242 | if (!(this instanceof Comparator)) { 2243 | return new Comparator(comp, options) 2244 | } 2245 | 2246 | debug('comparator', comp, options) 2247 | this.options = options 2248 | this.loose = !!options.loose 2249 | this.parse(comp) 2250 | 2251 | if (this.semver === ANY) { 2252 | this.value = '' 2253 | } else { 2254 | this.value = this.operator + this.semver.version 2255 | } 2256 | 2257 | debug('comp', this) 2258 | } 2259 | 2260 | var ANY = {} 2261 | Comparator.prototype.parse = function (comp) { 2262 | var r = this.options.loose ? re[t.COMPARATORLOOSE] : re[t.COMPARATOR] 2263 | var m = comp.match(r) 2264 | 2265 | if (!m) { 2266 | throw new TypeError('Invalid comparator: ' + comp) 2267 | } 2268 | 2269 | this.operator = m[1] !== undefined ? m[1] : '' 2270 | if (this.operator === '=') { 2271 | this.operator = '' 2272 | } 2273 | 2274 | // if it literally is just '>' or '' then allow anything. 2275 | if (!m[2]) { 2276 | this.semver = ANY 2277 | } else { 2278 | this.semver = new SemVer(m[2], this.options.loose) 2279 | } 2280 | } 2281 | 2282 | Comparator.prototype.toString = function () { 2283 | return this.value 2284 | } 2285 | 2286 | Comparator.prototype.test = function (version) { 2287 | debug('Comparator.test', version, this.options.loose) 2288 | 2289 | if (this.semver === ANY || version === ANY) { 2290 | return true 2291 | } 2292 | 2293 | if (typeof version === 'string') { 2294 | try { 2295 | version = new SemVer(version, this.options) 2296 | } catch (er) { 2297 | return false 2298 | } 2299 | } 2300 | 2301 | return cmp(version, this.operator, this.semver, this.options) 2302 | } 2303 | 2304 | Comparator.prototype.intersects = function (comp, options) { 2305 | if (!(comp instanceof Comparator)) { 2306 | throw new TypeError('a Comparator is required') 2307 | } 2308 | 2309 | if (!options || typeof options !== 'object') { 2310 | options = { 2311 | loose: !!options, 2312 | includePrerelease: false 2313 | } 2314 | } 2315 | 2316 | var rangeTmp 2317 | 2318 | if (this.operator === '') { 2319 | if (this.value === '') { 2320 | return true 2321 | } 2322 | rangeTmp = new Range(comp.value, options) 2323 | return satisfies(this.value, rangeTmp, options) 2324 | } else if (comp.operator === '') { 2325 | if (comp.value === '') { 2326 | return true 2327 | } 2328 | rangeTmp = new Range(this.value, options) 2329 | return satisfies(comp.semver, rangeTmp, options) 2330 | } 2331 | 2332 | var sameDirectionIncreasing = 2333 | (this.operator === '>=' || this.operator === '>') && 2334 | (comp.operator === '>=' || comp.operator === '>') 2335 | var sameDirectionDecreasing = 2336 | (this.operator === '<=' || this.operator === '<') && 2337 | (comp.operator === '<=' || comp.operator === '<') 2338 | var sameSemVer = this.semver.version === comp.semver.version 2339 | var differentDirectionsInclusive = 2340 | (this.operator === '>=' || this.operator === '<=') && 2341 | (comp.operator === '>=' || comp.operator === '<=') 2342 | var oppositeDirectionsLessThan = 2343 | cmp(this.semver, '<', comp.semver, options) && 2344 | ((this.operator === '>=' || this.operator === '>') && 2345 | (comp.operator === '<=' || comp.operator === '<')) 2346 | var oppositeDirectionsGreaterThan = 2347 | cmp(this.semver, '>', comp.semver, options) && 2348 | ((this.operator === '<=' || this.operator === '<') && 2349 | (comp.operator === '>=' || comp.operator === '>')) 2350 | 2351 | return sameDirectionIncreasing || sameDirectionDecreasing || 2352 | (sameSemVer && differentDirectionsInclusive) || 2353 | oppositeDirectionsLessThan || oppositeDirectionsGreaterThan 2354 | } 2355 | 2356 | exports.Range = Range 2357 | function Range (range, options) { 2358 | if (!options || typeof options !== 'object') { 2359 | options = { 2360 | loose: !!options, 2361 | includePrerelease: false 2362 | } 2363 | } 2364 | 2365 | if (range instanceof Range) { 2366 | if (range.loose === !!options.loose && 2367 | range.includePrerelease === !!options.includePrerelease) { 2368 | return range 2369 | } else { 2370 | return new Range(range.raw, options) 2371 | } 2372 | } 2373 | 2374 | if (range instanceof Comparator) { 2375 | return new Range(range.value, options) 2376 | } 2377 | 2378 | if (!(this instanceof Range)) { 2379 | return new Range(range, options) 2380 | } 2381 | 2382 | this.options = options 2383 | this.loose = !!options.loose 2384 | this.includePrerelease = !!options.includePrerelease 2385 | 2386 | // First, split based on boolean or || 2387 | this.raw = range 2388 | this.set = range.split(/\s*\|\|\s*/).map(function (range) { 2389 | return this.parseRange(range.trim()) 2390 | }, this).filter(function (c) { 2391 | // throw out any that are not relevant for whatever reason 2392 | return c.length 2393 | }) 2394 | 2395 | if (!this.set.length) { 2396 | throw new TypeError('Invalid SemVer Range: ' + range) 2397 | } 2398 | 2399 | this.format() 2400 | } 2401 | 2402 | Range.prototype.format = function () { 2403 | this.range = this.set.map(function (comps) { 2404 | return comps.join(' ').trim() 2405 | }).join('||').trim() 2406 | return this.range 2407 | } 2408 | 2409 | Range.prototype.toString = function () { 2410 | return this.range 2411 | } 2412 | 2413 | Range.prototype.parseRange = function (range) { 2414 | var loose = this.options.loose 2415 | range = range.trim() 2416 | // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4` 2417 | var hr = loose ? re[t.HYPHENRANGELOOSE] : re[t.HYPHENRANGE] 2418 | range = range.replace(hr, hyphenReplace) 2419 | debug('hyphen replace', range) 2420 | // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5` 2421 | range = range.replace(re[t.COMPARATORTRIM], comparatorTrimReplace) 2422 | debug('comparator trim', range, re[t.COMPARATORTRIM]) 2423 | 2424 | // `~ 1.2.3` => `~1.2.3` 2425 | range = range.replace(re[t.TILDETRIM], tildeTrimReplace) 2426 | 2427 | // `^ 1.2.3` => `^1.2.3` 2428 | range = range.replace(re[t.CARETTRIM], caretTrimReplace) 2429 | 2430 | // normalize spaces 2431 | range = range.split(/\s+/).join(' ') 2432 | 2433 | // At this point, the range is completely trimmed and 2434 | // ready to be split into comparators. 2435 | 2436 | var compRe = loose ? re[t.COMPARATORLOOSE] : re[t.COMPARATOR] 2437 | var set = range.split(' ').map(function (comp) { 2438 | return parseComparator(comp, this.options) 2439 | }, this).join(' ').split(/\s+/) 2440 | if (this.options.loose) { 2441 | // in loose mode, throw out any that are not valid comparators 2442 | set = set.filter(function (comp) { 2443 | return !!comp.match(compRe) 2444 | }) 2445 | } 2446 | set = set.map(function (comp) { 2447 | return new Comparator(comp, this.options) 2448 | }, this) 2449 | 2450 | return set 2451 | } 2452 | 2453 | Range.prototype.intersects = function (range, options) { 2454 | if (!(range instanceof Range)) { 2455 | throw new TypeError('a Range is required') 2456 | } 2457 | 2458 | return this.set.some(function (thisComparators) { 2459 | return ( 2460 | isSatisfiable(thisComparators, options) && 2461 | range.set.some(function (rangeComparators) { 2462 | return ( 2463 | isSatisfiable(rangeComparators, options) && 2464 | thisComparators.every(function (thisComparator) { 2465 | return rangeComparators.every(function (rangeComparator) { 2466 | return thisComparator.intersects(rangeComparator, options) 2467 | }) 2468 | }) 2469 | ) 2470 | }) 2471 | ) 2472 | }) 2473 | } 2474 | 2475 | // take a set of comparators and determine whether there 2476 | // exists a version which can satisfy it 2477 | function isSatisfiable (comparators, options) { 2478 | var result = true 2479 | var remainingComparators = comparators.slice() 2480 | var testComparator = remainingComparators.pop() 2481 | 2482 | while (result && remainingComparators.length) { 2483 | result = remainingComparators.every(function (otherComparator) { 2484 | return testComparator.intersects(otherComparator, options) 2485 | }) 2486 | 2487 | testComparator = remainingComparators.pop() 2488 | } 2489 | 2490 | return result 2491 | } 2492 | 2493 | // Mostly just for testing and legacy API reasons 2494 | exports.toComparators = toComparators 2495 | function toComparators (range, options) { 2496 | return new Range(range, options).set.map(function (comp) { 2497 | return comp.map(function (c) { 2498 | return c.value 2499 | }).join(' ').trim().split(' ') 2500 | }) 2501 | } 2502 | 2503 | // comprised of xranges, tildes, stars, and gtlt's at this point. 2504 | // already replaced the hyphen ranges 2505 | // turn into a set of JUST comparators. 2506 | function parseComparator (comp, options) { 2507 | debug('comp', comp, options) 2508 | comp = replaceCarets(comp, options) 2509 | debug('caret', comp) 2510 | comp = replaceTildes(comp, options) 2511 | debug('tildes', comp) 2512 | comp = replaceXRanges(comp, options) 2513 | debug('xrange', comp) 2514 | comp = replaceStars(comp, options) 2515 | debug('stars', comp) 2516 | return comp 2517 | } 2518 | 2519 | function isX (id) { 2520 | return !id || id.toLowerCase() === 'x' || id === '*' 2521 | } 2522 | 2523 | // ~, ~> --> * (any, kinda silly) 2524 | // ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0 2525 | // ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0 2526 | // ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0 2527 | // ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0 2528 | // ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0 2529 | function replaceTildes (comp, options) { 2530 | return comp.trim().split(/\s+/).map(function (comp) { 2531 | return replaceTilde(comp, options) 2532 | }).join(' ') 2533 | } 2534 | 2535 | function replaceTilde (comp, options) { 2536 | var r = options.loose ? re[t.TILDELOOSE] : re[t.TILDE] 2537 | return comp.replace(r, function (_, M, m, p, pr) { 2538 | debug('tilde', comp, _, M, m, p, pr) 2539 | var ret 2540 | 2541 | if (isX(M)) { 2542 | ret = '' 2543 | } else if (isX(m)) { 2544 | ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0' 2545 | } else if (isX(p)) { 2546 | // ~1.2 == >=1.2.0 <1.3.0 2547 | ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0' 2548 | } else if (pr) { 2549 | debug('replaceTilde pr', pr) 2550 | ret = '>=' + M + '.' + m + '.' + p + '-' + pr + 2551 | ' <' + M + '.' + (+m + 1) + '.0' 2552 | } else { 2553 | // ~1.2.3 == >=1.2.3 <1.3.0 2554 | ret = '>=' + M + '.' + m + '.' + p + 2555 | ' <' + M + '.' + (+m + 1) + '.0' 2556 | } 2557 | 2558 | debug('tilde return', ret) 2559 | return ret 2560 | }) 2561 | } 2562 | 2563 | // ^ --> * (any, kinda silly) 2564 | // ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0 2565 | // ^2.0, ^2.0.x --> >=2.0.0 <3.0.0 2566 | // ^1.2, ^1.2.x --> >=1.2.0 <2.0.0 2567 | // ^1.2.3 --> >=1.2.3 <2.0.0 2568 | // ^1.2.0 --> >=1.2.0 <2.0.0 2569 | function replaceCarets (comp, options) { 2570 | return comp.trim().split(/\s+/).map(function (comp) { 2571 | return replaceCaret(comp, options) 2572 | }).join(' ') 2573 | } 2574 | 2575 | function replaceCaret (comp, options) { 2576 | debug('caret', comp, options) 2577 | var r = options.loose ? re[t.CARETLOOSE] : re[t.CARET] 2578 | return comp.replace(r, function (_, M, m, p, pr) { 2579 | debug('caret', comp, _, M, m, p, pr) 2580 | var ret 2581 | 2582 | if (isX(M)) { 2583 | ret = '' 2584 | } else if (isX(m)) { 2585 | ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0' 2586 | } else if (isX(p)) { 2587 | if (M === '0') { 2588 | ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0' 2589 | } else { 2590 | ret = '>=' + M + '.' + m + '.0 <' + (+M + 1) + '.0.0' 2591 | } 2592 | } else if (pr) { 2593 | debug('replaceCaret pr', pr) 2594 | if (M === '0') { 2595 | if (m === '0') { 2596 | ret = '>=' + M + '.' + m + '.' + p + '-' + pr + 2597 | ' <' + M + '.' + m + '.' + (+p + 1) 2598 | } else { 2599 | ret = '>=' + M + '.' + m + '.' + p + '-' + pr + 2600 | ' <' + M + '.' + (+m + 1) + '.0' 2601 | } 2602 | } else { 2603 | ret = '>=' + M + '.' + m + '.' + p + '-' + pr + 2604 | ' <' + (+M + 1) + '.0.0' 2605 | } 2606 | } else { 2607 | debug('no pr') 2608 | if (M === '0') { 2609 | if (m === '0') { 2610 | ret = '>=' + M + '.' + m + '.' + p + 2611 | ' <' + M + '.' + m + '.' + (+p + 1) 2612 | } else { 2613 | ret = '>=' + M + '.' + m + '.' + p + 2614 | ' <' + M + '.' + (+m + 1) + '.0' 2615 | } 2616 | } else { 2617 | ret = '>=' + M + '.' + m + '.' + p + 2618 | ' <' + (+M + 1) + '.0.0' 2619 | } 2620 | } 2621 | 2622 | debug('caret return', ret) 2623 | return ret 2624 | }) 2625 | } 2626 | 2627 | function replaceXRanges (comp, options) { 2628 | debug('replaceXRanges', comp, options) 2629 | return comp.split(/\s+/).map(function (comp) { 2630 | return replaceXRange(comp, options) 2631 | }).join(' ') 2632 | } 2633 | 2634 | function replaceXRange (comp, options) { 2635 | comp = comp.trim() 2636 | var r = options.loose ? re[t.XRANGELOOSE] : re[t.XRANGE] 2637 | return comp.replace(r, function (ret, gtlt, M, m, p, pr) { 2638 | debug('xRange', comp, ret, gtlt, M, m, p, pr) 2639 | var xM = isX(M) 2640 | var xm = xM || isX(m) 2641 | var xp = xm || isX(p) 2642 | var anyX = xp 2643 | 2644 | if (gtlt === '=' && anyX) { 2645 | gtlt = '' 2646 | } 2647 | 2648 | // if we're including prereleases in the match, then we need 2649 | // to fix this to -0, the lowest possible prerelease value 2650 | pr = options.includePrerelease ? '-0' : '' 2651 | 2652 | if (xM) { 2653 | if (gtlt === '>' || gtlt === '<') { 2654 | // nothing is allowed 2655 | ret = '<0.0.0-0' 2656 | } else { 2657 | // nothing is forbidden 2658 | ret = '*' 2659 | } 2660 | } else if (gtlt && anyX) { 2661 | // we know patch is an x, because we have any x at all. 2662 | // replace X with 0 2663 | if (xm) { 2664 | m = 0 2665 | } 2666 | p = 0 2667 | 2668 | if (gtlt === '>') { 2669 | // >1 => >=2.0.0 2670 | // >1.2 => >=1.3.0 2671 | // >1.2.3 => >= 1.2.4 2672 | gtlt = '>=' 2673 | if (xm) { 2674 | M = +M + 1 2675 | m = 0 2676 | p = 0 2677 | } else { 2678 | m = +m + 1 2679 | p = 0 2680 | } 2681 | } else if (gtlt === '<=') { 2682 | // <=0.7.x is actually <0.8.0, since any 0.7.x should 2683 | // pass. Similarly, <=7.x is actually <8.0.0, etc. 2684 | gtlt = '<' 2685 | if (xm) { 2686 | M = +M + 1 2687 | } else { 2688 | m = +m + 1 2689 | } 2690 | } 2691 | 2692 | ret = gtlt + M + '.' + m + '.' + p + pr 2693 | } else if (xm) { 2694 | ret = '>=' + M + '.0.0' + pr + ' <' + (+M + 1) + '.0.0' + pr 2695 | } else if (xp) { 2696 | ret = '>=' + M + '.' + m + '.0' + pr + 2697 | ' <' + M + '.' + (+m + 1) + '.0' + pr 2698 | } 2699 | 2700 | debug('xRange return', ret) 2701 | 2702 | return ret 2703 | }) 2704 | } 2705 | 2706 | // Because * is AND-ed with everything else in the comparator, 2707 | // and '' means "any version", just remove the *s entirely. 2708 | function replaceStars (comp, options) { 2709 | debug('replaceStars', comp, options) 2710 | // Looseness is ignored here. star is always as loose as it gets! 2711 | return comp.trim().replace(re[t.STAR], '') 2712 | } 2713 | 2714 | // This function is passed to string.replace(re[t.HYPHENRANGE]) 2715 | // M, m, patch, prerelease, build 2716 | // 1.2 - 3.4.5 => >=1.2.0 <=3.4.5 2717 | // 1.2.3 - 3.4 => >=1.2.0 <3.5.0 Any 3.4.x will do 2718 | // 1.2 - 3.4 => >=1.2.0 <3.5.0 2719 | function hyphenReplace ($0, 2720 | from, fM, fm, fp, fpr, fb, 2721 | to, tM, tm, tp, tpr, tb) { 2722 | if (isX(fM)) { 2723 | from = '' 2724 | } else if (isX(fm)) { 2725 | from = '>=' + fM + '.0.0' 2726 | } else if (isX(fp)) { 2727 | from = '>=' + fM + '.' + fm + '.0' 2728 | } else { 2729 | from = '>=' + from 2730 | } 2731 | 2732 | if (isX(tM)) { 2733 | to = '' 2734 | } else if (isX(tm)) { 2735 | to = '<' + (+tM + 1) + '.0.0' 2736 | } else if (isX(tp)) { 2737 | to = '<' + tM + '.' + (+tm + 1) + '.0' 2738 | } else if (tpr) { 2739 | to = '<=' + tM + '.' + tm + '.' + tp + '-' + tpr 2740 | } else { 2741 | to = '<=' + to 2742 | } 2743 | 2744 | return (from + ' ' + to).trim() 2745 | } 2746 | 2747 | // if ANY of the sets match ALL of its comparators, then pass 2748 | Range.prototype.test = function (version) { 2749 | if (!version) { 2750 | return false 2751 | } 2752 | 2753 | if (typeof version === 'string') { 2754 | try { 2755 | version = new SemVer(version, this.options) 2756 | } catch (er) { 2757 | return false 2758 | } 2759 | } 2760 | 2761 | for (var i = 0; i < this.set.length; i++) { 2762 | if (testSet(this.set[i], version, this.options)) { 2763 | return true 2764 | } 2765 | } 2766 | return false 2767 | } 2768 | 2769 | function testSet (set, version, options) { 2770 | for (var i = 0; i < set.length; i++) { 2771 | if (!set[i].test(version)) { 2772 | return false 2773 | } 2774 | } 2775 | 2776 | if (version.prerelease.length && !options.includePrerelease) { 2777 | // Find the set of versions that are allowed to have prereleases 2778 | // For example, ^1.2.3-pr.1 desugars to >=1.2.3-pr.1 <2.0.0 2779 | // That should allow `1.2.3-pr.2` to pass. 2780 | // However, `1.2.4-alpha.notready` should NOT be allowed, 2781 | // even though it's within the range set by the comparators. 2782 | for (i = 0; i < set.length; i++) { 2783 | debug(set[i].semver) 2784 | if (set[i].semver === ANY) { 2785 | continue 2786 | } 2787 | 2788 | if (set[i].semver.prerelease.length > 0) { 2789 | var allowed = set[i].semver 2790 | if (allowed.major === version.major && 2791 | allowed.minor === version.minor && 2792 | allowed.patch === version.patch) { 2793 | return true 2794 | } 2795 | } 2796 | } 2797 | 2798 | // Version has a -pre, but it's not one of the ones we like. 2799 | return false 2800 | } 2801 | 2802 | return true 2803 | } 2804 | 2805 | exports.satisfies = satisfies 2806 | function satisfies (version, range, options) { 2807 | try { 2808 | range = new Range(range, options) 2809 | } catch (er) { 2810 | return false 2811 | } 2812 | return range.test(version) 2813 | } 2814 | 2815 | exports.maxSatisfying = maxSatisfying 2816 | function maxSatisfying (versions, range, options) { 2817 | var max = null 2818 | var maxSV = null 2819 | try { 2820 | var rangeObj = new Range(range, options) 2821 | } catch (er) { 2822 | return null 2823 | } 2824 | versions.forEach(function (v) { 2825 | if (rangeObj.test(v)) { 2826 | // satisfies(v, range, options) 2827 | if (!max || maxSV.compare(v) === -1) { 2828 | // compare(max, v, true) 2829 | max = v 2830 | maxSV = new SemVer(max, options) 2831 | } 2832 | } 2833 | }) 2834 | return max 2835 | } 2836 | 2837 | exports.minSatisfying = minSatisfying 2838 | function minSatisfying (versions, range, options) { 2839 | var min = null 2840 | var minSV = null 2841 | try { 2842 | var rangeObj = new Range(range, options) 2843 | } catch (er) { 2844 | return null 2845 | } 2846 | versions.forEach(function (v) { 2847 | if (rangeObj.test(v)) { 2848 | // satisfies(v, range, options) 2849 | if (!min || minSV.compare(v) === 1) { 2850 | // compare(min, v, true) 2851 | min = v 2852 | minSV = new SemVer(min, options) 2853 | } 2854 | } 2855 | }) 2856 | return min 2857 | } 2858 | 2859 | exports.minVersion = minVersion 2860 | function minVersion (range, loose) { 2861 | range = new Range(range, loose) 2862 | 2863 | var minver = new SemVer('0.0.0') 2864 | if (range.test(minver)) { 2865 | return minver 2866 | } 2867 | 2868 | minver = new SemVer('0.0.0-0') 2869 | if (range.test(minver)) { 2870 | return minver 2871 | } 2872 | 2873 | minver = null 2874 | for (var i = 0; i < range.set.length; ++i) { 2875 | var comparators = range.set[i] 2876 | 2877 | comparators.forEach(function (comparator) { 2878 | // Clone to avoid manipulating the comparator's semver object. 2879 | var compver = new SemVer(comparator.semver.version) 2880 | switch (comparator.operator) { 2881 | case '>': 2882 | if (compver.prerelease.length === 0) { 2883 | compver.patch++ 2884 | } else { 2885 | compver.prerelease.push(0) 2886 | } 2887 | compver.raw = compver.format() 2888 | /* fallthrough */ 2889 | case '': 2890 | case '>=': 2891 | if (!minver || gt(minver, compver)) { 2892 | minver = compver 2893 | } 2894 | break 2895 | case '<': 2896 | case '<=': 2897 | /* Ignore maximum versions */ 2898 | break 2899 | /* istanbul ignore next */ 2900 | default: 2901 | throw new Error('Unexpected operation: ' + comparator.operator) 2902 | } 2903 | }) 2904 | } 2905 | 2906 | if (minver && range.test(minver)) { 2907 | return minver 2908 | } 2909 | 2910 | return null 2911 | } 2912 | 2913 | exports.validRange = validRange 2914 | function validRange (range, options) { 2915 | try { 2916 | // Return '*' instead of '' so that truthiness works. 2917 | // This will throw if it's invalid anyway 2918 | return new Range(range, options).range || '*' 2919 | } catch (er) { 2920 | return null 2921 | } 2922 | } 2923 | 2924 | // Determine if version is less than all the versions possible in the range 2925 | exports.ltr = ltr 2926 | function ltr (version, range, options) { 2927 | return outside(version, range, '<', options) 2928 | } 2929 | 2930 | // Determine if version is greater than all the versions possible in the range. 2931 | exports.gtr = gtr 2932 | function gtr (version, range, options) { 2933 | return outside(version, range, '>', options) 2934 | } 2935 | 2936 | exports.outside = outside 2937 | function outside (version, range, hilo, options) { 2938 | version = new SemVer(version, options) 2939 | range = new Range(range, options) 2940 | 2941 | var gtfn, ltefn, ltfn, comp, ecomp 2942 | switch (hilo) { 2943 | case '>': 2944 | gtfn = gt 2945 | ltefn = lte 2946 | ltfn = lt 2947 | comp = '>' 2948 | ecomp = '>=' 2949 | break 2950 | case '<': 2951 | gtfn = lt 2952 | ltefn = gte 2953 | ltfn = gt 2954 | comp = '<' 2955 | ecomp = '<=' 2956 | break 2957 | default: 2958 | throw new TypeError('Must provide a hilo val of "<" or ">"') 2959 | } 2960 | 2961 | // If it satisifes the range it is not outside 2962 | if (satisfies(version, range, options)) { 2963 | return false 2964 | } 2965 | 2966 | // From now on, variable terms are as if we're in "gtr" mode. 2967 | // but note that everything is flipped for the "ltr" function. 2968 | 2969 | for (var i = 0; i < range.set.length; ++i) { 2970 | var comparators = range.set[i] 2971 | 2972 | var high = null 2973 | var low = null 2974 | 2975 | comparators.forEach(function (comparator) { 2976 | if (comparator.semver === ANY) { 2977 | comparator = new Comparator('>=0.0.0') 2978 | } 2979 | high = high || comparator 2980 | low = low || comparator 2981 | if (gtfn(comparator.semver, high.semver, options)) { 2982 | high = comparator 2983 | } else if (ltfn(comparator.semver, low.semver, options)) { 2984 | low = comparator 2985 | } 2986 | }) 2987 | 2988 | // If the edge version comparator has a operator then our version 2989 | // isn't outside it 2990 | if (high.operator === comp || high.operator === ecomp) { 2991 | return false 2992 | } 2993 | 2994 | // If the lowest version comparator has an operator and our version 2995 | // is less than it then it isn't higher than the range 2996 | if ((!low.operator || low.operator === comp) && 2997 | ltefn(version, low.semver)) { 2998 | return false 2999 | } else if (low.operator === ecomp && ltfn(version, low.semver)) { 3000 | return false 3001 | } 3002 | } 3003 | return true 3004 | } 3005 | 3006 | exports.prerelease = prerelease 3007 | function prerelease (version, options) { 3008 | var parsed = parse(version, options) 3009 | return (parsed && parsed.prerelease.length) ? parsed.prerelease : null 3010 | } 3011 | 3012 | exports.intersects = intersects 3013 | function intersects (r1, r2, options) { 3014 | r1 = new Range(r1, options) 3015 | r2 = new Range(r2, options) 3016 | return r1.intersects(r2) 3017 | } 3018 | 3019 | exports.coerce = coerce 3020 | function coerce (version, options) { 3021 | if (version instanceof SemVer) { 3022 | return version 3023 | } 3024 | 3025 | if (typeof version === 'number') { 3026 | version = String(version) 3027 | } 3028 | 3029 | if (typeof version !== 'string') { 3030 | return null 3031 | } 3032 | 3033 | options = options || {} 3034 | 3035 | var match = null 3036 | if (!options.rtl) { 3037 | match = version.match(re[t.COERCE]) 3038 | } else { 3039 | // Find the right-most coercible string that does not share 3040 | // a terminus with a more left-ward coercible string. 3041 | // Eg, '1.2.3.4' wants to coerce '2.3.4', not '3.4' or '4' 3042 | // 3043 | // Walk through the string checking with a /g regexp 3044 | // Manually set the index so as to pick up overlapping matches. 3045 | // Stop when we get a match that ends at the string end, since no 3046 | // coercible string can be more right-ward without the same terminus. 3047 | var next 3048 | while ((next = re[t.COERCERTL].exec(version)) && 3049 | (!match || match.index + match[0].length !== version.length) 3050 | ) { 3051 | if (!match || 3052 | next.index + next[0].length !== match.index + match[0].length) { 3053 | match = next 3054 | } 3055 | re[t.COERCERTL].lastIndex = next.index + next[1].length + next[2].length 3056 | } 3057 | // leave it in a clean state 3058 | re[t.COERCERTL].lastIndex = -1 3059 | } 3060 | 3061 | if (match === null) { 3062 | return null 3063 | } 3064 | 3065 | return parse(match[2] + 3066 | '.' + (match[3] || '0') + 3067 | '.' + (match[4] || '0'), options) 3068 | } 3069 | 3070 | 3071 | /***/ }), 3072 | 3073 | /***/ 357: 3074 | /***/ (function(module) { 3075 | 3076 | module.exports = require("assert"); 3077 | 3078 | /***/ }), 3079 | 3080 | /***/ 413: 3081 | /***/ (function(module, __unusedexports, __webpack_require__) { 3082 | 3083 | module.exports = __webpack_require__(141); 3084 | 3085 | 3086 | /***/ }), 3087 | 3088 | /***/ 417: 3089 | /***/ (function(module) { 3090 | 3091 | module.exports = require("crypto"); 3092 | 3093 | /***/ }), 3094 | 3095 | /***/ 431: 3096 | /***/ (function(__unusedmodule, exports, __webpack_require__) { 3097 | 3098 | "use strict"; 3099 | 3100 | var __importStar = (this && this.__importStar) || function (mod) { 3101 | if (mod && mod.__esModule) return mod; 3102 | var result = {}; 3103 | if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; 3104 | result["default"] = mod; 3105 | return result; 3106 | }; 3107 | Object.defineProperty(exports, "__esModule", { value: true }); 3108 | const os = __importStar(__webpack_require__(87)); 3109 | const utils_1 = __webpack_require__(82); 3110 | /** 3111 | * Commands 3112 | * 3113 | * Command Format: 3114 | * ::name key=value,key=value::message 3115 | * 3116 | * Examples: 3117 | * ::warning::This is the message 3118 | * ::set-env name=MY_VAR::some value 3119 | */ 3120 | function issueCommand(command, properties, message) { 3121 | const cmd = new Command(command, properties, message); 3122 | process.stdout.write(cmd.toString() + os.EOL); 3123 | } 3124 | exports.issueCommand = issueCommand; 3125 | function issue(name, message = '') { 3126 | issueCommand(name, {}, message); 3127 | } 3128 | exports.issue = issue; 3129 | const CMD_STRING = '::'; 3130 | class Command { 3131 | constructor(command, properties, message) { 3132 | if (!command) { 3133 | command = 'missing.command'; 3134 | } 3135 | this.command = command; 3136 | this.properties = properties; 3137 | this.message = message; 3138 | } 3139 | toString() { 3140 | let cmdStr = CMD_STRING + this.command; 3141 | if (this.properties && Object.keys(this.properties).length > 0) { 3142 | cmdStr += ' '; 3143 | let first = true; 3144 | for (const key in this.properties) { 3145 | if (this.properties.hasOwnProperty(key)) { 3146 | const val = this.properties[key]; 3147 | if (val) { 3148 | if (first) { 3149 | first = false; 3150 | } 3151 | else { 3152 | cmdStr += ','; 3153 | } 3154 | cmdStr += `${key}=${escapeProperty(val)}`; 3155 | } 3156 | } 3157 | } 3158 | } 3159 | cmdStr += `${CMD_STRING}${escapeData(this.message)}`; 3160 | return cmdStr; 3161 | } 3162 | } 3163 | function escapeData(s) { 3164 | return utils_1.toCommandValue(s) 3165 | .replace(/%/g, '%25') 3166 | .replace(/\r/g, '%0D') 3167 | .replace(/\n/g, '%0A'); 3168 | } 3169 | function escapeProperty(s) { 3170 | return utils_1.toCommandValue(s) 3171 | .replace(/%/g, '%25') 3172 | .replace(/\r/g, '%0D') 3173 | .replace(/\n/g, '%0A') 3174 | .replace(/:/g, '%3A') 3175 | .replace(/,/g, '%2C'); 3176 | } 3177 | //# sourceMappingURL=command.js.map 3178 | 3179 | /***/ }), 3180 | 3181 | /***/ 470: 3182 | /***/ (function(__unusedmodule, exports, __webpack_require__) { 3183 | 3184 | "use strict"; 3185 | 3186 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 3187 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 3188 | return new (P || (P = Promise))(function (resolve, reject) { 3189 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 3190 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 3191 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 3192 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 3193 | }); 3194 | }; 3195 | var __importStar = (this && this.__importStar) || function (mod) { 3196 | if (mod && mod.__esModule) return mod; 3197 | var result = {}; 3198 | if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; 3199 | result["default"] = mod; 3200 | return result; 3201 | }; 3202 | Object.defineProperty(exports, "__esModule", { value: true }); 3203 | const command_1 = __webpack_require__(431); 3204 | const file_command_1 = __webpack_require__(102); 3205 | const utils_1 = __webpack_require__(82); 3206 | const os = __importStar(__webpack_require__(87)); 3207 | const path = __importStar(__webpack_require__(622)); 3208 | /** 3209 | * The code to exit an action 3210 | */ 3211 | var ExitCode; 3212 | (function (ExitCode) { 3213 | /** 3214 | * A code indicating that the action was successful 3215 | */ 3216 | ExitCode[ExitCode["Success"] = 0] = "Success"; 3217 | /** 3218 | * A code indicating that the action was a failure 3219 | */ 3220 | ExitCode[ExitCode["Failure"] = 1] = "Failure"; 3221 | })(ExitCode = exports.ExitCode || (exports.ExitCode = {})); 3222 | //----------------------------------------------------------------------- 3223 | // Variables 3224 | //----------------------------------------------------------------------- 3225 | /** 3226 | * Sets env variable for this action and future actions in the job 3227 | * @param name the name of the variable to set 3228 | * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify 3229 | */ 3230 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 3231 | function exportVariable(name, val) { 3232 | const convertedVal = utils_1.toCommandValue(val); 3233 | process.env[name] = convertedVal; 3234 | const filePath = process.env['GITHUB_ENV'] || ''; 3235 | if (filePath) { 3236 | const delimiter = '_GitHubActionsFileCommandDelimeter_'; 3237 | const commandValue = `${name}<<${delimiter}${os.EOL}${convertedVal}${os.EOL}${delimiter}`; 3238 | file_command_1.issueCommand('ENV', commandValue); 3239 | } 3240 | else { 3241 | command_1.issueCommand('set-env', { name }, convertedVal); 3242 | } 3243 | } 3244 | exports.exportVariable = exportVariable; 3245 | /** 3246 | * Registers a secret which will get masked from logs 3247 | * @param secret value of the secret 3248 | */ 3249 | function setSecret(secret) { 3250 | command_1.issueCommand('add-mask', {}, secret); 3251 | } 3252 | exports.setSecret = setSecret; 3253 | /** 3254 | * Prepends inputPath to the PATH (for this action and future actions) 3255 | * @param inputPath 3256 | */ 3257 | function addPath(inputPath) { 3258 | const filePath = process.env['GITHUB_PATH'] || ''; 3259 | if (filePath) { 3260 | file_command_1.issueCommand('PATH', inputPath); 3261 | } 3262 | else { 3263 | command_1.issueCommand('add-path', {}, inputPath); 3264 | } 3265 | process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`; 3266 | } 3267 | exports.addPath = addPath; 3268 | /** 3269 | * Gets the value of an input. The value is also trimmed. 3270 | * 3271 | * @param name name of the input to get 3272 | * @param options optional. See InputOptions. 3273 | * @returns string 3274 | */ 3275 | function getInput(name, options) { 3276 | const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || ''; 3277 | if (options && options.required && !val) { 3278 | throw new Error(`Input required and not supplied: ${name}`); 3279 | } 3280 | return val.trim(); 3281 | } 3282 | exports.getInput = getInput; 3283 | /** 3284 | * Sets the value of an output. 3285 | * 3286 | * @param name name of the output to set 3287 | * @param value value to store. Non-string values will be converted to a string via JSON.stringify 3288 | */ 3289 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 3290 | function setOutput(name, value) { 3291 | process.stdout.write(os.EOL); 3292 | command_1.issueCommand('set-output', { name }, value); 3293 | } 3294 | exports.setOutput = setOutput; 3295 | /** 3296 | * Enables or disables the echoing of commands into stdout for the rest of the step. 3297 | * Echoing is disabled by default if ACTIONS_STEP_DEBUG is not set. 3298 | * 3299 | */ 3300 | function setCommandEcho(enabled) { 3301 | command_1.issue('echo', enabled ? 'on' : 'off'); 3302 | } 3303 | exports.setCommandEcho = setCommandEcho; 3304 | //----------------------------------------------------------------------- 3305 | // Results 3306 | //----------------------------------------------------------------------- 3307 | /** 3308 | * Sets the action status to failed. 3309 | * When the action exits it will be with an exit code of 1 3310 | * @param message add error issue message 3311 | */ 3312 | function setFailed(message) { 3313 | process.exitCode = ExitCode.Failure; 3314 | error(message); 3315 | } 3316 | exports.setFailed = setFailed; 3317 | //----------------------------------------------------------------------- 3318 | // Logging Commands 3319 | //----------------------------------------------------------------------- 3320 | /** 3321 | * Gets whether Actions Step Debug is on or not 3322 | */ 3323 | function isDebug() { 3324 | return process.env['RUNNER_DEBUG'] === '1'; 3325 | } 3326 | exports.isDebug = isDebug; 3327 | /** 3328 | * Writes debug message to user log 3329 | * @param message debug message 3330 | */ 3331 | function debug(message) { 3332 | command_1.issueCommand('debug', {}, message); 3333 | } 3334 | exports.debug = debug; 3335 | /** 3336 | * Adds an error issue 3337 | * @param message error issue message. Errors will be converted to string via toString() 3338 | */ 3339 | function error(message) { 3340 | command_1.issue('error', message instanceof Error ? message.toString() : message); 3341 | } 3342 | exports.error = error; 3343 | /** 3344 | * Adds an warning issue 3345 | * @param message warning issue message. Errors will be converted to string via toString() 3346 | */ 3347 | function warning(message) { 3348 | command_1.issue('warning', message instanceof Error ? message.toString() : message); 3349 | } 3350 | exports.warning = warning; 3351 | /** 3352 | * Writes info to log with console.log. 3353 | * @param message info message 3354 | */ 3355 | function info(message) { 3356 | process.stdout.write(message + os.EOL); 3357 | } 3358 | exports.info = info; 3359 | /** 3360 | * Begin an output group. 3361 | * 3362 | * Output until the next `groupEnd` will be foldable in this group 3363 | * 3364 | * @param name The name of the output group 3365 | */ 3366 | function startGroup(name) { 3367 | command_1.issue('group', name); 3368 | } 3369 | exports.startGroup = startGroup; 3370 | /** 3371 | * End an output group. 3372 | */ 3373 | function endGroup() { 3374 | command_1.issue('endgroup'); 3375 | } 3376 | exports.endGroup = endGroup; 3377 | /** 3378 | * Wrap an asynchronous function call in a group. 3379 | * 3380 | * Returns the same type as the function itself. 3381 | * 3382 | * @param name The name of the group 3383 | * @param fn The function to wrap in the group 3384 | */ 3385 | function group(name, fn) { 3386 | return __awaiter(this, void 0, void 0, function* () { 3387 | startGroup(name); 3388 | let result; 3389 | try { 3390 | result = yield fn(); 3391 | } 3392 | finally { 3393 | endGroup(); 3394 | } 3395 | return result; 3396 | }); 3397 | } 3398 | exports.group = group; 3399 | //----------------------------------------------------------------------- 3400 | // Wrapper action state 3401 | //----------------------------------------------------------------------- 3402 | /** 3403 | * Saves state for current action, the state can only be retrieved by this action's post job execution. 3404 | * 3405 | * @param name name of the state to store 3406 | * @param value value to store. Non-string values will be converted to a string via JSON.stringify 3407 | */ 3408 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 3409 | function saveState(name, value) { 3410 | command_1.issueCommand('save-state', { name }, value); 3411 | } 3412 | exports.saveState = saveState; 3413 | /** 3414 | * Gets the value of an state set by this action's main execution. 3415 | * 3416 | * @param name name of the state to get 3417 | * @returns string 3418 | */ 3419 | function getState(name) { 3420 | return process.env[`STATE_${name}`] || ''; 3421 | } 3422 | exports.getState = getState; 3423 | //# sourceMappingURL=core.js.map 3424 | 3425 | /***/ }), 3426 | 3427 | /***/ 533: 3428 | /***/ (function(__unusedmodule, exports, __webpack_require__) { 3429 | 3430 | "use strict"; 3431 | 3432 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 3433 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 3434 | return new (P || (P = Promise))(function (resolve, reject) { 3435 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 3436 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 3437 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 3438 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 3439 | }); 3440 | }; 3441 | var __importStar = (this && this.__importStar) || function (mod) { 3442 | if (mod && mod.__esModule) return mod; 3443 | var result = {}; 3444 | if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; 3445 | result["default"] = mod; 3446 | return result; 3447 | }; 3448 | var __importDefault = (this && this.__importDefault) || function (mod) { 3449 | return (mod && mod.__esModule) ? mod : { "default": mod }; 3450 | }; 3451 | Object.defineProperty(exports, "__esModule", { value: true }); 3452 | const core = __importStar(__webpack_require__(470)); 3453 | const io = __importStar(__webpack_require__(1)); 3454 | const fs = __importStar(__webpack_require__(747)); 3455 | const mm = __importStar(__webpack_require__(31)); 3456 | const os = __importStar(__webpack_require__(87)); 3457 | const path = __importStar(__webpack_require__(622)); 3458 | const httpm = __importStar(__webpack_require__(539)); 3459 | const semver = __importStar(__webpack_require__(280)); 3460 | const stream = __importStar(__webpack_require__(794)); 3461 | const util = __importStar(__webpack_require__(669)); 3462 | const v4_1 = __importDefault(__webpack_require__(826)); 3463 | const exec_1 = __webpack_require__(986); 3464 | const assert_1 = __webpack_require__(357); 3465 | const retry_helper_1 = __webpack_require__(979); 3466 | class HTTPError extends Error { 3467 | constructor(httpStatusCode) { 3468 | super(`Unexpected HTTP response: ${httpStatusCode}`); 3469 | this.httpStatusCode = httpStatusCode; 3470 | Object.setPrototypeOf(this, new.target.prototype); 3471 | } 3472 | } 3473 | exports.HTTPError = HTTPError; 3474 | const IS_WINDOWS = process.platform === 'win32'; 3475 | const IS_MAC = process.platform === 'darwin'; 3476 | const userAgent = 'actions/tool-cache'; 3477 | /** 3478 | * Download a tool from an url and stream it into a file 3479 | * 3480 | * @param url url of tool to download 3481 | * @param dest path to download tool 3482 | * @param auth authorization header 3483 | * @returns path to downloaded tool 3484 | */ 3485 | function downloadTool(url, dest, auth) { 3486 | return __awaiter(this, void 0, void 0, function* () { 3487 | dest = dest || path.join(_getTempDirectory(), v4_1.default()); 3488 | yield io.mkdirP(path.dirname(dest)); 3489 | core.debug(`Downloading ${url}`); 3490 | core.debug(`Destination ${dest}`); 3491 | const maxAttempts = 3; 3492 | const minSeconds = _getGlobal('TEST_DOWNLOAD_TOOL_RETRY_MIN_SECONDS', 10); 3493 | const maxSeconds = _getGlobal('TEST_DOWNLOAD_TOOL_RETRY_MAX_SECONDS', 20); 3494 | const retryHelper = new retry_helper_1.RetryHelper(maxAttempts, minSeconds, maxSeconds); 3495 | return yield retryHelper.execute(() => __awaiter(this, void 0, void 0, function* () { 3496 | return yield downloadToolAttempt(url, dest || '', auth); 3497 | }), (err) => { 3498 | if (err instanceof HTTPError && err.httpStatusCode) { 3499 | // Don't retry anything less than 500, except 408 Request Timeout and 429 Too Many Requests 3500 | if (err.httpStatusCode < 500 && 3501 | err.httpStatusCode !== 408 && 3502 | err.httpStatusCode !== 429) { 3503 | return false; 3504 | } 3505 | } 3506 | // Otherwise retry 3507 | return true; 3508 | }); 3509 | }); 3510 | } 3511 | exports.downloadTool = downloadTool; 3512 | function downloadToolAttempt(url, dest, auth) { 3513 | return __awaiter(this, void 0, void 0, function* () { 3514 | if (fs.existsSync(dest)) { 3515 | throw new Error(`Destination file path ${dest} already exists`); 3516 | } 3517 | // Get the response headers 3518 | const http = new httpm.HttpClient(userAgent, [], { 3519 | allowRetries: false 3520 | }); 3521 | let headers; 3522 | if (auth) { 3523 | core.debug('set auth'); 3524 | headers = { 3525 | authorization: auth 3526 | }; 3527 | } 3528 | const response = yield http.get(url, headers); 3529 | if (response.message.statusCode !== 200) { 3530 | const err = new HTTPError(response.message.statusCode); 3531 | core.debug(`Failed to download from "${url}". Code(${response.message.statusCode}) Message(${response.message.statusMessage})`); 3532 | throw err; 3533 | } 3534 | // Download the response body 3535 | const pipeline = util.promisify(stream.pipeline); 3536 | const responseMessageFactory = _getGlobal('TEST_DOWNLOAD_TOOL_RESPONSE_MESSAGE_FACTORY', () => response.message); 3537 | const readStream = responseMessageFactory(); 3538 | let succeeded = false; 3539 | try { 3540 | yield pipeline(readStream, fs.createWriteStream(dest)); 3541 | core.debug('download complete'); 3542 | succeeded = true; 3543 | return dest; 3544 | } 3545 | finally { 3546 | // Error, delete dest before retry 3547 | if (!succeeded) { 3548 | core.debug('download failed'); 3549 | try { 3550 | yield io.rmRF(dest); 3551 | } 3552 | catch (err) { 3553 | core.debug(`Failed to delete '${dest}'. ${err.message}`); 3554 | } 3555 | } 3556 | } 3557 | }); 3558 | } 3559 | /** 3560 | * Extract a .7z file 3561 | * 3562 | * @param file path to the .7z file 3563 | * @param dest destination directory. Optional. 3564 | * @param _7zPath path to 7zr.exe. Optional, for long path support. Most .7z archives do not have this 3565 | * problem. If your .7z archive contains very long paths, you can pass the path to 7zr.exe which will 3566 | * gracefully handle long paths. By default 7zdec.exe is used because it is a very small program and is 3567 | * bundled with the tool lib. However it does not support long paths. 7zr.exe is the reduced command line 3568 | * interface, it is smaller than the full command line interface, and it does support long paths. At the 3569 | * time of this writing, it is freely available from the LZMA SDK that is available on the 7zip website. 3570 | * Be sure to check the current license agreement. If 7zr.exe is bundled with your action, then the path 3571 | * to 7zr.exe can be pass to this function. 3572 | * @returns path to the destination directory 3573 | */ 3574 | function extract7z(file, dest, _7zPath) { 3575 | return __awaiter(this, void 0, void 0, function* () { 3576 | assert_1.ok(IS_WINDOWS, 'extract7z() not supported on current OS'); 3577 | assert_1.ok(file, 'parameter "file" is required'); 3578 | dest = yield _createExtractFolder(dest); 3579 | const originalCwd = process.cwd(); 3580 | process.chdir(dest); 3581 | if (_7zPath) { 3582 | try { 3583 | const logLevel = core.isDebug() ? '-bb1' : '-bb0'; 3584 | const args = [ 3585 | 'x', 3586 | logLevel, 3587 | '-bd', 3588 | '-sccUTF-8', 3589 | file 3590 | ]; 3591 | const options = { 3592 | silent: true 3593 | }; 3594 | yield exec_1.exec(`"${_7zPath}"`, args, options); 3595 | } 3596 | finally { 3597 | process.chdir(originalCwd); 3598 | } 3599 | } 3600 | else { 3601 | const escapedScript = path 3602 | .join(__dirname, '..', 'scripts', 'Invoke-7zdec.ps1') 3603 | .replace(/'/g, "''") 3604 | .replace(/"|\n|\r/g, ''); // double-up single quotes, remove double quotes and newlines 3605 | const escapedFile = file.replace(/'/g, "''").replace(/"|\n|\r/g, ''); 3606 | const escapedTarget = dest.replace(/'/g, "''").replace(/"|\n|\r/g, ''); 3607 | const command = `& '${escapedScript}' -Source '${escapedFile}' -Target '${escapedTarget}'`; 3608 | const args = [ 3609 | '-NoLogo', 3610 | '-Sta', 3611 | '-NoProfile', 3612 | '-NonInteractive', 3613 | '-ExecutionPolicy', 3614 | 'Unrestricted', 3615 | '-Command', 3616 | command 3617 | ]; 3618 | const options = { 3619 | silent: true 3620 | }; 3621 | try { 3622 | const powershellPath = yield io.which('powershell', true); 3623 | yield exec_1.exec(`"${powershellPath}"`, args, options); 3624 | } 3625 | finally { 3626 | process.chdir(originalCwd); 3627 | } 3628 | } 3629 | return dest; 3630 | }); 3631 | } 3632 | exports.extract7z = extract7z; 3633 | /** 3634 | * Extract a compressed tar archive 3635 | * 3636 | * @param file path to the tar 3637 | * @param dest destination directory. Optional. 3638 | * @param flags flags for the tar command to use for extraction. Defaults to 'xz' (extracting gzipped tars). Optional. 3639 | * @returns path to the destination directory 3640 | */ 3641 | function extractTar(file, dest, flags = 'xz') { 3642 | return __awaiter(this, void 0, void 0, function* () { 3643 | if (!file) { 3644 | throw new Error("parameter 'file' is required"); 3645 | } 3646 | // Create dest 3647 | dest = yield _createExtractFolder(dest); 3648 | // Determine whether GNU tar 3649 | core.debug('Checking tar --version'); 3650 | let versionOutput = ''; 3651 | yield exec_1.exec('tar --version', [], { 3652 | ignoreReturnCode: true, 3653 | silent: true, 3654 | listeners: { 3655 | stdout: (data) => (versionOutput += data.toString()), 3656 | stderr: (data) => (versionOutput += data.toString()) 3657 | } 3658 | }); 3659 | core.debug(versionOutput.trim()); 3660 | const isGnuTar = versionOutput.toUpperCase().includes('GNU TAR'); 3661 | // Initialize args 3662 | let args; 3663 | if (flags instanceof Array) { 3664 | args = flags; 3665 | } 3666 | else { 3667 | args = [flags]; 3668 | } 3669 | if (core.isDebug() && !flags.includes('v')) { 3670 | args.push('-v'); 3671 | } 3672 | let destArg = dest; 3673 | let fileArg = file; 3674 | if (IS_WINDOWS && isGnuTar) { 3675 | args.push('--force-local'); 3676 | destArg = dest.replace(/\\/g, '/'); 3677 | // Technically only the dest needs to have `/` but for aesthetic consistency 3678 | // convert slashes in the file arg too. 3679 | fileArg = file.replace(/\\/g, '/'); 3680 | } 3681 | if (isGnuTar) { 3682 | // Suppress warnings when using GNU tar to extract archives created by BSD tar 3683 | args.push('--warning=no-unknown-keyword'); 3684 | } 3685 | args.push('-C', destArg, '-f', fileArg); 3686 | yield exec_1.exec(`tar`, args); 3687 | return dest; 3688 | }); 3689 | } 3690 | exports.extractTar = extractTar; 3691 | /** 3692 | * Extract a xar compatible archive 3693 | * 3694 | * @param file path to the archive 3695 | * @param dest destination directory. Optional. 3696 | * @param flags flags for the xar. Optional. 3697 | * @returns path to the destination directory 3698 | */ 3699 | function extractXar(file, dest, flags = []) { 3700 | return __awaiter(this, void 0, void 0, function* () { 3701 | assert_1.ok(IS_MAC, 'extractXar() not supported on current OS'); 3702 | assert_1.ok(file, 'parameter "file" is required'); 3703 | dest = yield _createExtractFolder(dest); 3704 | let args; 3705 | if (flags instanceof Array) { 3706 | args = flags; 3707 | } 3708 | else { 3709 | args = [flags]; 3710 | } 3711 | args.push('-x', '-C', dest, '-f', file); 3712 | if (core.isDebug()) { 3713 | args.push('-v'); 3714 | } 3715 | const xarPath = yield io.which('xar', true); 3716 | yield exec_1.exec(`"${xarPath}"`, _unique(args)); 3717 | return dest; 3718 | }); 3719 | } 3720 | exports.extractXar = extractXar; 3721 | /** 3722 | * Extract a zip 3723 | * 3724 | * @param file path to the zip 3725 | * @param dest destination directory. Optional. 3726 | * @returns path to the destination directory 3727 | */ 3728 | function extractZip(file, dest) { 3729 | return __awaiter(this, void 0, void 0, function* () { 3730 | if (!file) { 3731 | throw new Error("parameter 'file' is required"); 3732 | } 3733 | dest = yield _createExtractFolder(dest); 3734 | if (IS_WINDOWS) { 3735 | yield extractZipWin(file, dest); 3736 | } 3737 | else { 3738 | yield extractZipNix(file, dest); 3739 | } 3740 | return dest; 3741 | }); 3742 | } 3743 | exports.extractZip = extractZip; 3744 | function extractZipWin(file, dest) { 3745 | return __awaiter(this, void 0, void 0, function* () { 3746 | // build the powershell command 3747 | const escapedFile = file.replace(/'/g, "''").replace(/"|\n|\r/g, ''); // double-up single quotes, remove double quotes and newlines 3748 | const escapedDest = dest.replace(/'/g, "''").replace(/"|\n|\r/g, ''); 3749 | const command = `$ErrorActionPreference = 'Stop' ; try { Add-Type -AssemblyName System.IO.Compression.FileSystem } catch { } ; [System.IO.Compression.ZipFile]::ExtractToDirectory('${escapedFile}', '${escapedDest}')`; 3750 | // run powershell 3751 | const powershellPath = yield io.which('powershell', true); 3752 | const args = [ 3753 | '-NoLogo', 3754 | '-Sta', 3755 | '-NoProfile', 3756 | '-NonInteractive', 3757 | '-ExecutionPolicy', 3758 | 'Unrestricted', 3759 | '-Command', 3760 | command 3761 | ]; 3762 | yield exec_1.exec(`"${powershellPath}"`, args); 3763 | }); 3764 | } 3765 | function extractZipNix(file, dest) { 3766 | return __awaiter(this, void 0, void 0, function* () { 3767 | const unzipPath = yield io.which('unzip', true); 3768 | const args = [file]; 3769 | if (!core.isDebug()) { 3770 | args.unshift('-q'); 3771 | } 3772 | yield exec_1.exec(`"${unzipPath}"`, args, { cwd: dest }); 3773 | }); 3774 | } 3775 | /** 3776 | * Caches a directory and installs it into the tool cacheDir 3777 | * 3778 | * @param sourceDir the directory to cache into tools 3779 | * @param tool tool name 3780 | * @param version version of the tool. semver format 3781 | * @param arch architecture of the tool. Optional. Defaults to machine architecture 3782 | */ 3783 | function cacheDir(sourceDir, tool, version, arch) { 3784 | return __awaiter(this, void 0, void 0, function* () { 3785 | version = semver.clean(version) || version; 3786 | arch = arch || os.arch(); 3787 | core.debug(`Caching tool ${tool} ${version} ${arch}`); 3788 | core.debug(`source dir: ${sourceDir}`); 3789 | if (!fs.statSync(sourceDir).isDirectory()) { 3790 | throw new Error('sourceDir is not a directory'); 3791 | } 3792 | // Create the tool dir 3793 | const destPath = yield _createToolPath(tool, version, arch); 3794 | // copy each child item. do not move. move can fail on Windows 3795 | // due to anti-virus software having an open handle on a file. 3796 | for (const itemName of fs.readdirSync(sourceDir)) { 3797 | const s = path.join(sourceDir, itemName); 3798 | yield io.cp(s, destPath, { recursive: true }); 3799 | } 3800 | // write .complete 3801 | _completeToolPath(tool, version, arch); 3802 | return destPath; 3803 | }); 3804 | } 3805 | exports.cacheDir = cacheDir; 3806 | /** 3807 | * Caches a downloaded file (GUID) and installs it 3808 | * into the tool cache with a given targetName 3809 | * 3810 | * @param sourceFile the file to cache into tools. Typically a result of downloadTool which is a guid. 3811 | * @param targetFile the name of the file name in the tools directory 3812 | * @param tool tool name 3813 | * @param version version of the tool. semver format 3814 | * @param arch architecture of the tool. Optional. Defaults to machine architecture 3815 | */ 3816 | function cacheFile(sourceFile, targetFile, tool, version, arch) { 3817 | return __awaiter(this, void 0, void 0, function* () { 3818 | version = semver.clean(version) || version; 3819 | arch = arch || os.arch(); 3820 | core.debug(`Caching tool ${tool} ${version} ${arch}`); 3821 | core.debug(`source file: ${sourceFile}`); 3822 | if (!fs.statSync(sourceFile).isFile()) { 3823 | throw new Error('sourceFile is not a file'); 3824 | } 3825 | // create the tool dir 3826 | const destFolder = yield _createToolPath(tool, version, arch); 3827 | // copy instead of move. move can fail on Windows due to 3828 | // anti-virus software having an open handle on a file. 3829 | const destPath = path.join(destFolder, targetFile); 3830 | core.debug(`destination file ${destPath}`); 3831 | yield io.cp(sourceFile, destPath); 3832 | // write .complete 3833 | _completeToolPath(tool, version, arch); 3834 | return destFolder; 3835 | }); 3836 | } 3837 | exports.cacheFile = cacheFile; 3838 | /** 3839 | * Finds the path to a tool version in the local installed tool cache 3840 | * 3841 | * @param toolName name of the tool 3842 | * @param versionSpec version of the tool 3843 | * @param arch optional arch. defaults to arch of computer 3844 | */ 3845 | function find(toolName, versionSpec, arch) { 3846 | if (!toolName) { 3847 | throw new Error('toolName parameter is required'); 3848 | } 3849 | if (!versionSpec) { 3850 | throw new Error('versionSpec parameter is required'); 3851 | } 3852 | arch = arch || os.arch(); 3853 | // attempt to resolve an explicit version 3854 | if (!_isExplicitVersion(versionSpec)) { 3855 | const localVersions = findAllVersions(toolName, arch); 3856 | const match = _evaluateVersions(localVersions, versionSpec); 3857 | versionSpec = match; 3858 | } 3859 | // check for the explicit version in the cache 3860 | let toolPath = ''; 3861 | if (versionSpec) { 3862 | versionSpec = semver.clean(versionSpec) || ''; 3863 | const cachePath = path.join(_getCacheDirectory(), toolName, versionSpec, arch); 3864 | core.debug(`checking cache: ${cachePath}`); 3865 | if (fs.existsSync(cachePath) && fs.existsSync(`${cachePath}.complete`)) { 3866 | core.debug(`Found tool in cache ${toolName} ${versionSpec} ${arch}`); 3867 | toolPath = cachePath; 3868 | } 3869 | else { 3870 | core.debug('not found'); 3871 | } 3872 | } 3873 | return toolPath; 3874 | } 3875 | exports.find = find; 3876 | /** 3877 | * Finds the paths to all versions of a tool that are installed in the local tool cache 3878 | * 3879 | * @param toolName name of the tool 3880 | * @param arch optional arch. defaults to arch of computer 3881 | */ 3882 | function findAllVersions(toolName, arch) { 3883 | const versions = []; 3884 | arch = arch || os.arch(); 3885 | const toolPath = path.join(_getCacheDirectory(), toolName); 3886 | if (fs.existsSync(toolPath)) { 3887 | const children = fs.readdirSync(toolPath); 3888 | for (const child of children) { 3889 | if (_isExplicitVersion(child)) { 3890 | const fullPath = path.join(toolPath, child, arch || ''); 3891 | if (fs.existsSync(fullPath) && fs.existsSync(`${fullPath}.complete`)) { 3892 | versions.push(child); 3893 | } 3894 | } 3895 | } 3896 | } 3897 | return versions; 3898 | } 3899 | exports.findAllVersions = findAllVersions; 3900 | function getManifestFromRepo(owner, repo, auth, branch = 'master') { 3901 | return __awaiter(this, void 0, void 0, function* () { 3902 | let releases = []; 3903 | const treeUrl = `https://api.github.com/repos/${owner}/${repo}/git/trees/${branch}`; 3904 | const http = new httpm.HttpClient('tool-cache'); 3905 | const headers = {}; 3906 | if (auth) { 3907 | core.debug('set auth'); 3908 | headers.authorization = auth; 3909 | } 3910 | const response = yield http.getJson(treeUrl, headers); 3911 | if (!response.result) { 3912 | return releases; 3913 | } 3914 | let manifestUrl = ''; 3915 | for (const item of response.result.tree) { 3916 | if (item.path === 'versions-manifest.json') { 3917 | manifestUrl = item.url; 3918 | break; 3919 | } 3920 | } 3921 | headers['accept'] = 'application/vnd.github.VERSION.raw'; 3922 | let versionsRaw = yield (yield http.get(manifestUrl, headers)).readBody(); 3923 | if (versionsRaw) { 3924 | // shouldn't be needed but protects against invalid json saved with BOM 3925 | versionsRaw = versionsRaw.replace(/^\uFEFF/, ''); 3926 | try { 3927 | releases = JSON.parse(versionsRaw); 3928 | } 3929 | catch (_a) { 3930 | core.debug('Invalid json'); 3931 | } 3932 | } 3933 | return releases; 3934 | }); 3935 | } 3936 | exports.getManifestFromRepo = getManifestFromRepo; 3937 | function findFromManifest(versionSpec, stable, manifest, archFilter = os.arch()) { 3938 | return __awaiter(this, void 0, void 0, function* () { 3939 | // wrap the internal impl 3940 | const match = yield mm._findMatch(versionSpec, stable, manifest, archFilter); 3941 | return match; 3942 | }); 3943 | } 3944 | exports.findFromManifest = findFromManifest; 3945 | function _createExtractFolder(dest) { 3946 | return __awaiter(this, void 0, void 0, function* () { 3947 | if (!dest) { 3948 | // create a temp dir 3949 | dest = path.join(_getTempDirectory(), v4_1.default()); 3950 | } 3951 | yield io.mkdirP(dest); 3952 | return dest; 3953 | }); 3954 | } 3955 | function _createToolPath(tool, version, arch) { 3956 | return __awaiter(this, void 0, void 0, function* () { 3957 | const folderPath = path.join(_getCacheDirectory(), tool, semver.clean(version) || version, arch || ''); 3958 | core.debug(`destination ${folderPath}`); 3959 | const markerPath = `${folderPath}.complete`; 3960 | yield io.rmRF(folderPath); 3961 | yield io.rmRF(markerPath); 3962 | yield io.mkdirP(folderPath); 3963 | return folderPath; 3964 | }); 3965 | } 3966 | function _completeToolPath(tool, version, arch) { 3967 | const folderPath = path.join(_getCacheDirectory(), tool, semver.clean(version) || version, arch || ''); 3968 | const markerPath = `${folderPath}.complete`; 3969 | fs.writeFileSync(markerPath, ''); 3970 | core.debug('finished caching tool'); 3971 | } 3972 | function _isExplicitVersion(versionSpec) { 3973 | const c = semver.clean(versionSpec) || ''; 3974 | core.debug(`isExplicit: ${c}`); 3975 | const valid = semver.valid(c) != null; 3976 | core.debug(`explicit? ${valid}`); 3977 | return valid; 3978 | } 3979 | function _evaluateVersions(versions, versionSpec) { 3980 | let version = ''; 3981 | core.debug(`evaluating ${versions.length} versions`); 3982 | versions = versions.sort((a, b) => { 3983 | if (semver.gt(a, b)) { 3984 | return 1; 3985 | } 3986 | return -1; 3987 | }); 3988 | for (let i = versions.length - 1; i >= 0; i--) { 3989 | const potential = versions[i]; 3990 | const satisfied = semver.satisfies(potential, versionSpec); 3991 | if (satisfied) { 3992 | version = potential; 3993 | break; 3994 | } 3995 | } 3996 | if (version) { 3997 | core.debug(`matched: ${version}`); 3998 | } 3999 | else { 4000 | core.debug('match not found'); 4001 | } 4002 | return version; 4003 | } 4004 | /** 4005 | * Gets RUNNER_TOOL_CACHE 4006 | */ 4007 | function _getCacheDirectory() { 4008 | const cacheDirectory = process.env['RUNNER_TOOL_CACHE'] || ''; 4009 | assert_1.ok(cacheDirectory, 'Expected RUNNER_TOOL_CACHE to be defined'); 4010 | return cacheDirectory; 4011 | } 4012 | /** 4013 | * Gets RUNNER_TEMP 4014 | */ 4015 | function _getTempDirectory() { 4016 | const tempDirectory = process.env['RUNNER_TEMP'] || ''; 4017 | assert_1.ok(tempDirectory, 'Expected RUNNER_TEMP to be defined'); 4018 | return tempDirectory; 4019 | } 4020 | /** 4021 | * Gets a global variable 4022 | */ 4023 | function _getGlobal(key, defaultValue) { 4024 | /* eslint-disable @typescript-eslint/no-explicit-any */ 4025 | const value = global[key]; 4026 | /* eslint-enable @typescript-eslint/no-explicit-any */ 4027 | return value !== undefined ? value : defaultValue; 4028 | } 4029 | /** 4030 | * Returns an array of unique values. 4031 | * @param values Values to make unique. 4032 | */ 4033 | function _unique(values) { 4034 | return Array.from(new Set(values)); 4035 | } 4036 | //# sourceMappingURL=tool-cache.js.map 4037 | 4038 | /***/ }), 4039 | 4040 | /***/ 539: 4041 | /***/ (function(__unusedmodule, exports, __webpack_require__) { 4042 | 4043 | "use strict"; 4044 | 4045 | Object.defineProperty(exports, "__esModule", { value: true }); 4046 | const http = __webpack_require__(605); 4047 | const https = __webpack_require__(211); 4048 | const pm = __webpack_require__(950); 4049 | let tunnel; 4050 | var HttpCodes; 4051 | (function (HttpCodes) { 4052 | HttpCodes[HttpCodes["OK"] = 200] = "OK"; 4053 | HttpCodes[HttpCodes["MultipleChoices"] = 300] = "MultipleChoices"; 4054 | HttpCodes[HttpCodes["MovedPermanently"] = 301] = "MovedPermanently"; 4055 | HttpCodes[HttpCodes["ResourceMoved"] = 302] = "ResourceMoved"; 4056 | HttpCodes[HttpCodes["SeeOther"] = 303] = "SeeOther"; 4057 | HttpCodes[HttpCodes["NotModified"] = 304] = "NotModified"; 4058 | HttpCodes[HttpCodes["UseProxy"] = 305] = "UseProxy"; 4059 | HttpCodes[HttpCodes["SwitchProxy"] = 306] = "SwitchProxy"; 4060 | HttpCodes[HttpCodes["TemporaryRedirect"] = 307] = "TemporaryRedirect"; 4061 | HttpCodes[HttpCodes["PermanentRedirect"] = 308] = "PermanentRedirect"; 4062 | HttpCodes[HttpCodes["BadRequest"] = 400] = "BadRequest"; 4063 | HttpCodes[HttpCodes["Unauthorized"] = 401] = "Unauthorized"; 4064 | HttpCodes[HttpCodes["PaymentRequired"] = 402] = "PaymentRequired"; 4065 | HttpCodes[HttpCodes["Forbidden"] = 403] = "Forbidden"; 4066 | HttpCodes[HttpCodes["NotFound"] = 404] = "NotFound"; 4067 | HttpCodes[HttpCodes["MethodNotAllowed"] = 405] = "MethodNotAllowed"; 4068 | HttpCodes[HttpCodes["NotAcceptable"] = 406] = "NotAcceptable"; 4069 | HttpCodes[HttpCodes["ProxyAuthenticationRequired"] = 407] = "ProxyAuthenticationRequired"; 4070 | HttpCodes[HttpCodes["RequestTimeout"] = 408] = "RequestTimeout"; 4071 | HttpCodes[HttpCodes["Conflict"] = 409] = "Conflict"; 4072 | HttpCodes[HttpCodes["Gone"] = 410] = "Gone"; 4073 | HttpCodes[HttpCodes["TooManyRequests"] = 429] = "TooManyRequests"; 4074 | HttpCodes[HttpCodes["InternalServerError"] = 500] = "InternalServerError"; 4075 | HttpCodes[HttpCodes["NotImplemented"] = 501] = "NotImplemented"; 4076 | HttpCodes[HttpCodes["BadGateway"] = 502] = "BadGateway"; 4077 | HttpCodes[HttpCodes["ServiceUnavailable"] = 503] = "ServiceUnavailable"; 4078 | HttpCodes[HttpCodes["GatewayTimeout"] = 504] = "GatewayTimeout"; 4079 | })(HttpCodes = exports.HttpCodes || (exports.HttpCodes = {})); 4080 | var Headers; 4081 | (function (Headers) { 4082 | Headers["Accept"] = "accept"; 4083 | Headers["ContentType"] = "content-type"; 4084 | })(Headers = exports.Headers || (exports.Headers = {})); 4085 | var MediaTypes; 4086 | (function (MediaTypes) { 4087 | MediaTypes["ApplicationJson"] = "application/json"; 4088 | })(MediaTypes = exports.MediaTypes || (exports.MediaTypes = {})); 4089 | /** 4090 | * Returns the proxy URL, depending upon the supplied url and proxy environment variables. 4091 | * @param serverUrl The server URL where the request will be sent. For example, https://api.github.com 4092 | */ 4093 | function getProxyUrl(serverUrl) { 4094 | let proxyUrl = pm.getProxyUrl(new URL(serverUrl)); 4095 | return proxyUrl ? proxyUrl.href : ''; 4096 | } 4097 | exports.getProxyUrl = getProxyUrl; 4098 | const HttpRedirectCodes = [ 4099 | HttpCodes.MovedPermanently, 4100 | HttpCodes.ResourceMoved, 4101 | HttpCodes.SeeOther, 4102 | HttpCodes.TemporaryRedirect, 4103 | HttpCodes.PermanentRedirect 4104 | ]; 4105 | const HttpResponseRetryCodes = [ 4106 | HttpCodes.BadGateway, 4107 | HttpCodes.ServiceUnavailable, 4108 | HttpCodes.GatewayTimeout 4109 | ]; 4110 | const RetryableHttpVerbs = ['OPTIONS', 'GET', 'DELETE', 'HEAD']; 4111 | const ExponentialBackoffCeiling = 10; 4112 | const ExponentialBackoffTimeSlice = 5; 4113 | class HttpClientError extends Error { 4114 | constructor(message, statusCode) { 4115 | super(message); 4116 | this.name = 'HttpClientError'; 4117 | this.statusCode = statusCode; 4118 | Object.setPrototypeOf(this, HttpClientError.prototype); 4119 | } 4120 | } 4121 | exports.HttpClientError = HttpClientError; 4122 | class HttpClientResponse { 4123 | constructor(message) { 4124 | this.message = message; 4125 | } 4126 | readBody() { 4127 | return new Promise(async (resolve, reject) => { 4128 | let output = Buffer.alloc(0); 4129 | this.message.on('data', (chunk) => { 4130 | output = Buffer.concat([output, chunk]); 4131 | }); 4132 | this.message.on('end', () => { 4133 | resolve(output.toString()); 4134 | }); 4135 | }); 4136 | } 4137 | } 4138 | exports.HttpClientResponse = HttpClientResponse; 4139 | function isHttps(requestUrl) { 4140 | let parsedUrl = new URL(requestUrl); 4141 | return parsedUrl.protocol === 'https:'; 4142 | } 4143 | exports.isHttps = isHttps; 4144 | class HttpClient { 4145 | constructor(userAgent, handlers, requestOptions) { 4146 | this._ignoreSslError = false; 4147 | this._allowRedirects = true; 4148 | this._allowRedirectDowngrade = false; 4149 | this._maxRedirects = 50; 4150 | this._allowRetries = false; 4151 | this._maxRetries = 1; 4152 | this._keepAlive = false; 4153 | this._disposed = false; 4154 | this.userAgent = userAgent; 4155 | this.handlers = handlers || []; 4156 | this.requestOptions = requestOptions; 4157 | if (requestOptions) { 4158 | if (requestOptions.ignoreSslError != null) { 4159 | this._ignoreSslError = requestOptions.ignoreSslError; 4160 | } 4161 | this._socketTimeout = requestOptions.socketTimeout; 4162 | if (requestOptions.allowRedirects != null) { 4163 | this._allowRedirects = requestOptions.allowRedirects; 4164 | } 4165 | if (requestOptions.allowRedirectDowngrade != null) { 4166 | this._allowRedirectDowngrade = requestOptions.allowRedirectDowngrade; 4167 | } 4168 | if (requestOptions.maxRedirects != null) { 4169 | this._maxRedirects = Math.max(requestOptions.maxRedirects, 0); 4170 | } 4171 | if (requestOptions.keepAlive != null) { 4172 | this._keepAlive = requestOptions.keepAlive; 4173 | } 4174 | if (requestOptions.allowRetries != null) { 4175 | this._allowRetries = requestOptions.allowRetries; 4176 | } 4177 | if (requestOptions.maxRetries != null) { 4178 | this._maxRetries = requestOptions.maxRetries; 4179 | } 4180 | } 4181 | } 4182 | options(requestUrl, additionalHeaders) { 4183 | return this.request('OPTIONS', requestUrl, null, additionalHeaders || {}); 4184 | } 4185 | get(requestUrl, additionalHeaders) { 4186 | return this.request('GET', requestUrl, null, additionalHeaders || {}); 4187 | } 4188 | del(requestUrl, additionalHeaders) { 4189 | return this.request('DELETE', requestUrl, null, additionalHeaders || {}); 4190 | } 4191 | post(requestUrl, data, additionalHeaders) { 4192 | return this.request('POST', requestUrl, data, additionalHeaders || {}); 4193 | } 4194 | patch(requestUrl, data, additionalHeaders) { 4195 | return this.request('PATCH', requestUrl, data, additionalHeaders || {}); 4196 | } 4197 | put(requestUrl, data, additionalHeaders) { 4198 | return this.request('PUT', requestUrl, data, additionalHeaders || {}); 4199 | } 4200 | head(requestUrl, additionalHeaders) { 4201 | return this.request('HEAD', requestUrl, null, additionalHeaders || {}); 4202 | } 4203 | sendStream(verb, requestUrl, stream, additionalHeaders) { 4204 | return this.request(verb, requestUrl, stream, additionalHeaders); 4205 | } 4206 | /** 4207 | * Gets a typed object from an endpoint 4208 | * Be aware that not found returns a null. Other errors (4xx, 5xx) reject the promise 4209 | */ 4210 | async getJson(requestUrl, additionalHeaders = {}) { 4211 | additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); 4212 | let res = await this.get(requestUrl, additionalHeaders); 4213 | return this._processResponse(res, this.requestOptions); 4214 | } 4215 | async postJson(requestUrl, obj, additionalHeaders = {}) { 4216 | let data = JSON.stringify(obj, null, 2); 4217 | additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); 4218 | additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson); 4219 | let res = await this.post(requestUrl, data, additionalHeaders); 4220 | return this._processResponse(res, this.requestOptions); 4221 | } 4222 | async putJson(requestUrl, obj, additionalHeaders = {}) { 4223 | let data = JSON.stringify(obj, null, 2); 4224 | additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); 4225 | additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson); 4226 | let res = await this.put(requestUrl, data, additionalHeaders); 4227 | return this._processResponse(res, this.requestOptions); 4228 | } 4229 | async patchJson(requestUrl, obj, additionalHeaders = {}) { 4230 | let data = JSON.stringify(obj, null, 2); 4231 | additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); 4232 | additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson); 4233 | let res = await this.patch(requestUrl, data, additionalHeaders); 4234 | return this._processResponse(res, this.requestOptions); 4235 | } 4236 | /** 4237 | * Makes a raw http request. 4238 | * All other methods such as get, post, patch, and request ultimately call this. 4239 | * Prefer get, del, post and patch 4240 | */ 4241 | async request(verb, requestUrl, data, headers) { 4242 | if (this._disposed) { 4243 | throw new Error('Client has already been disposed.'); 4244 | } 4245 | let parsedUrl = new URL(requestUrl); 4246 | let info = this._prepareRequest(verb, parsedUrl, headers); 4247 | // Only perform retries on reads since writes may not be idempotent. 4248 | let maxTries = this._allowRetries && RetryableHttpVerbs.indexOf(verb) != -1 4249 | ? this._maxRetries + 1 4250 | : 1; 4251 | let numTries = 0; 4252 | let response; 4253 | while (numTries < maxTries) { 4254 | response = await this.requestRaw(info, data); 4255 | // Check if it's an authentication challenge 4256 | if (response && 4257 | response.message && 4258 | response.message.statusCode === HttpCodes.Unauthorized) { 4259 | let authenticationHandler; 4260 | for (let i = 0; i < this.handlers.length; i++) { 4261 | if (this.handlers[i].canHandleAuthentication(response)) { 4262 | authenticationHandler = this.handlers[i]; 4263 | break; 4264 | } 4265 | } 4266 | if (authenticationHandler) { 4267 | return authenticationHandler.handleAuthentication(this, info, data); 4268 | } 4269 | else { 4270 | // We have received an unauthorized response but have no handlers to handle it. 4271 | // Let the response return to the caller. 4272 | return response; 4273 | } 4274 | } 4275 | let redirectsRemaining = this._maxRedirects; 4276 | while (HttpRedirectCodes.indexOf(response.message.statusCode) != -1 && 4277 | this._allowRedirects && 4278 | redirectsRemaining > 0) { 4279 | const redirectUrl = response.message.headers['location']; 4280 | if (!redirectUrl) { 4281 | // if there's no location to redirect to, we won't 4282 | break; 4283 | } 4284 | let parsedRedirectUrl = new URL(redirectUrl); 4285 | if (parsedUrl.protocol == 'https:' && 4286 | parsedUrl.protocol != parsedRedirectUrl.protocol && 4287 | !this._allowRedirectDowngrade) { 4288 | throw new Error('Redirect from HTTPS to HTTP protocol. This downgrade is not allowed for security reasons. If you want to allow this behavior, set the allowRedirectDowngrade option to true.'); 4289 | } 4290 | // we need to finish reading the response before reassigning response 4291 | // which will leak the open socket. 4292 | await response.readBody(); 4293 | // strip authorization header if redirected to a different hostname 4294 | if (parsedRedirectUrl.hostname !== parsedUrl.hostname) { 4295 | for (let header in headers) { 4296 | // header names are case insensitive 4297 | if (header.toLowerCase() === 'authorization') { 4298 | delete headers[header]; 4299 | } 4300 | } 4301 | } 4302 | // let's make the request with the new redirectUrl 4303 | info = this._prepareRequest(verb, parsedRedirectUrl, headers); 4304 | response = await this.requestRaw(info, data); 4305 | redirectsRemaining--; 4306 | } 4307 | if (HttpResponseRetryCodes.indexOf(response.message.statusCode) == -1) { 4308 | // If not a retry code, return immediately instead of retrying 4309 | return response; 4310 | } 4311 | numTries += 1; 4312 | if (numTries < maxTries) { 4313 | await response.readBody(); 4314 | await this._performExponentialBackoff(numTries); 4315 | } 4316 | } 4317 | return response; 4318 | } 4319 | /** 4320 | * Needs to be called if keepAlive is set to true in request options. 4321 | */ 4322 | dispose() { 4323 | if (this._agent) { 4324 | this._agent.destroy(); 4325 | } 4326 | this._disposed = true; 4327 | } 4328 | /** 4329 | * Raw request. 4330 | * @param info 4331 | * @param data 4332 | */ 4333 | requestRaw(info, data) { 4334 | return new Promise((resolve, reject) => { 4335 | let callbackForResult = function (err, res) { 4336 | if (err) { 4337 | reject(err); 4338 | } 4339 | resolve(res); 4340 | }; 4341 | this.requestRawWithCallback(info, data, callbackForResult); 4342 | }); 4343 | } 4344 | /** 4345 | * Raw request with callback. 4346 | * @param info 4347 | * @param data 4348 | * @param onResult 4349 | */ 4350 | requestRawWithCallback(info, data, onResult) { 4351 | let socket; 4352 | if (typeof data === 'string') { 4353 | info.options.headers['Content-Length'] = Buffer.byteLength(data, 'utf8'); 4354 | } 4355 | let callbackCalled = false; 4356 | let handleResult = (err, res) => { 4357 | if (!callbackCalled) { 4358 | callbackCalled = true; 4359 | onResult(err, res); 4360 | } 4361 | }; 4362 | let req = info.httpModule.request(info.options, (msg) => { 4363 | let res = new HttpClientResponse(msg); 4364 | handleResult(null, res); 4365 | }); 4366 | req.on('socket', sock => { 4367 | socket = sock; 4368 | }); 4369 | // If we ever get disconnected, we want the socket to timeout eventually 4370 | req.setTimeout(this._socketTimeout || 3 * 60000, () => { 4371 | if (socket) { 4372 | socket.end(); 4373 | } 4374 | handleResult(new Error('Request timeout: ' + info.options.path), null); 4375 | }); 4376 | req.on('error', function (err) { 4377 | // err has statusCode property 4378 | // res should have headers 4379 | handleResult(err, null); 4380 | }); 4381 | if (data && typeof data === 'string') { 4382 | req.write(data, 'utf8'); 4383 | } 4384 | if (data && typeof data !== 'string') { 4385 | data.on('close', function () { 4386 | req.end(); 4387 | }); 4388 | data.pipe(req); 4389 | } 4390 | else { 4391 | req.end(); 4392 | } 4393 | } 4394 | /** 4395 | * Gets an http agent. This function is useful when you need an http agent that handles 4396 | * routing through a proxy server - depending upon the url and proxy environment variables. 4397 | * @param serverUrl The server URL where the request will be sent. For example, https://api.github.com 4398 | */ 4399 | getAgent(serverUrl) { 4400 | let parsedUrl = new URL(serverUrl); 4401 | return this._getAgent(parsedUrl); 4402 | } 4403 | _prepareRequest(method, requestUrl, headers) { 4404 | const info = {}; 4405 | info.parsedUrl = requestUrl; 4406 | const usingSsl = info.parsedUrl.protocol === 'https:'; 4407 | info.httpModule = usingSsl ? https : http; 4408 | const defaultPort = usingSsl ? 443 : 80; 4409 | info.options = {}; 4410 | info.options.host = info.parsedUrl.hostname; 4411 | info.options.port = info.parsedUrl.port 4412 | ? parseInt(info.parsedUrl.port) 4413 | : defaultPort; 4414 | info.options.path = 4415 | (info.parsedUrl.pathname || '') + (info.parsedUrl.search || ''); 4416 | info.options.method = method; 4417 | info.options.headers = this._mergeHeaders(headers); 4418 | if (this.userAgent != null) { 4419 | info.options.headers['user-agent'] = this.userAgent; 4420 | } 4421 | info.options.agent = this._getAgent(info.parsedUrl); 4422 | // gives handlers an opportunity to participate 4423 | if (this.handlers) { 4424 | this.handlers.forEach(handler => { 4425 | handler.prepareRequest(info.options); 4426 | }); 4427 | } 4428 | return info; 4429 | } 4430 | _mergeHeaders(headers) { 4431 | const lowercaseKeys = obj => Object.keys(obj).reduce((c, k) => ((c[k.toLowerCase()] = obj[k]), c), {}); 4432 | if (this.requestOptions && this.requestOptions.headers) { 4433 | return Object.assign({}, lowercaseKeys(this.requestOptions.headers), lowercaseKeys(headers)); 4434 | } 4435 | return lowercaseKeys(headers || {}); 4436 | } 4437 | _getExistingOrDefaultHeader(additionalHeaders, header, _default) { 4438 | const lowercaseKeys = obj => Object.keys(obj).reduce((c, k) => ((c[k.toLowerCase()] = obj[k]), c), {}); 4439 | let clientHeader; 4440 | if (this.requestOptions && this.requestOptions.headers) { 4441 | clientHeader = lowercaseKeys(this.requestOptions.headers)[header]; 4442 | } 4443 | return additionalHeaders[header] || clientHeader || _default; 4444 | } 4445 | _getAgent(parsedUrl) { 4446 | let agent; 4447 | let proxyUrl = pm.getProxyUrl(parsedUrl); 4448 | let useProxy = proxyUrl && proxyUrl.hostname; 4449 | if (this._keepAlive && useProxy) { 4450 | agent = this._proxyAgent; 4451 | } 4452 | if (this._keepAlive && !useProxy) { 4453 | agent = this._agent; 4454 | } 4455 | // if agent is already assigned use that agent. 4456 | if (!!agent) { 4457 | return agent; 4458 | } 4459 | const usingSsl = parsedUrl.protocol === 'https:'; 4460 | let maxSockets = 100; 4461 | if (!!this.requestOptions) { 4462 | maxSockets = this.requestOptions.maxSockets || http.globalAgent.maxSockets; 4463 | } 4464 | if (useProxy) { 4465 | // If using proxy, need tunnel 4466 | if (!tunnel) { 4467 | tunnel = __webpack_require__(413); 4468 | } 4469 | const agentOptions = { 4470 | maxSockets: maxSockets, 4471 | keepAlive: this._keepAlive, 4472 | proxy: { 4473 | proxyAuth: `${proxyUrl.username}:${proxyUrl.password}`, 4474 | host: proxyUrl.hostname, 4475 | port: proxyUrl.port 4476 | } 4477 | }; 4478 | let tunnelAgent; 4479 | const overHttps = proxyUrl.protocol === 'https:'; 4480 | if (usingSsl) { 4481 | tunnelAgent = overHttps ? tunnel.httpsOverHttps : tunnel.httpsOverHttp; 4482 | } 4483 | else { 4484 | tunnelAgent = overHttps ? tunnel.httpOverHttps : tunnel.httpOverHttp; 4485 | } 4486 | agent = tunnelAgent(agentOptions); 4487 | this._proxyAgent = agent; 4488 | } 4489 | // if reusing agent across request and tunneling agent isn't assigned create a new agent 4490 | if (this._keepAlive && !agent) { 4491 | const options = { keepAlive: this._keepAlive, maxSockets: maxSockets }; 4492 | agent = usingSsl ? new https.Agent(options) : new http.Agent(options); 4493 | this._agent = agent; 4494 | } 4495 | // if not using private agent and tunnel agent isn't setup then use global agent 4496 | if (!agent) { 4497 | agent = usingSsl ? https.globalAgent : http.globalAgent; 4498 | } 4499 | if (usingSsl && this._ignoreSslError) { 4500 | // we don't want to set NODE_TLS_REJECT_UNAUTHORIZED=0 since that will affect request for entire process 4501 | // http.RequestOptions doesn't expose a way to modify RequestOptions.agent.options 4502 | // we have to cast it to any and change it directly 4503 | agent.options = Object.assign(agent.options || {}, { 4504 | rejectUnauthorized: false 4505 | }); 4506 | } 4507 | return agent; 4508 | } 4509 | _performExponentialBackoff(retryNumber) { 4510 | retryNumber = Math.min(ExponentialBackoffCeiling, retryNumber); 4511 | const ms = ExponentialBackoffTimeSlice * Math.pow(2, retryNumber); 4512 | return new Promise(resolve => setTimeout(() => resolve(), ms)); 4513 | } 4514 | static dateTimeDeserializer(key, value) { 4515 | if (typeof value === 'string') { 4516 | let a = new Date(value); 4517 | if (!isNaN(a.valueOf())) { 4518 | return a; 4519 | } 4520 | } 4521 | return value; 4522 | } 4523 | async _processResponse(res, options) { 4524 | return new Promise(async (resolve, reject) => { 4525 | const statusCode = res.message.statusCode; 4526 | const response = { 4527 | statusCode: statusCode, 4528 | result: null, 4529 | headers: {} 4530 | }; 4531 | // not found leads to null obj returned 4532 | if (statusCode == HttpCodes.NotFound) { 4533 | resolve(response); 4534 | } 4535 | let obj; 4536 | let contents; 4537 | // get the result from the body 4538 | try { 4539 | contents = await res.readBody(); 4540 | if (contents && contents.length > 0) { 4541 | if (options && options.deserializeDates) { 4542 | obj = JSON.parse(contents, HttpClient.dateTimeDeserializer); 4543 | } 4544 | else { 4545 | obj = JSON.parse(contents); 4546 | } 4547 | response.result = obj; 4548 | } 4549 | response.headers = res.message.headers; 4550 | } 4551 | catch (err) { 4552 | // Invalid resource (contents not json); leaving result obj null 4553 | } 4554 | // note that 3xx redirects are handled by the http layer. 4555 | if (statusCode > 299) { 4556 | let msg; 4557 | // if exception/error in body, attempt to get better error 4558 | if (obj && obj.message) { 4559 | msg = obj.message; 4560 | } 4561 | else if (contents && contents.length > 0) { 4562 | // it may be the case that the exception is in the body message as string 4563 | msg = contents; 4564 | } 4565 | else { 4566 | msg = 'Failed request: (' + statusCode + ')'; 4567 | } 4568 | let err = new HttpClientError(msg, statusCode); 4569 | err.result = response.result; 4570 | reject(err); 4571 | } 4572 | else { 4573 | resolve(response); 4574 | } 4575 | }); 4576 | } 4577 | } 4578 | exports.HttpClient = HttpClient; 4579 | 4580 | 4581 | /***/ }), 4582 | 4583 | /***/ 605: 4584 | /***/ (function(module) { 4585 | 4586 | module.exports = require("http"); 4587 | 4588 | /***/ }), 4589 | 4590 | /***/ 614: 4591 | /***/ (function(module) { 4592 | 4593 | module.exports = require("events"); 4594 | 4595 | /***/ }), 4596 | 4597 | /***/ 622: 4598 | /***/ (function(module) { 4599 | 4600 | module.exports = require("path"); 4601 | 4602 | /***/ }), 4603 | 4604 | /***/ 631: 4605 | /***/ (function(module) { 4606 | 4607 | module.exports = require("net"); 4608 | 4609 | /***/ }), 4610 | 4611 | /***/ 669: 4612 | /***/ (function(module) { 4613 | 4614 | module.exports = require("util"); 4615 | 4616 | /***/ }), 4617 | 4618 | /***/ 672: 4619 | /***/ (function(__unusedmodule, exports, __webpack_require__) { 4620 | 4621 | "use strict"; 4622 | 4623 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 4624 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 4625 | return new (P || (P = Promise))(function (resolve, reject) { 4626 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 4627 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 4628 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 4629 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 4630 | }); 4631 | }; 4632 | var __importStar = (this && this.__importStar) || function (mod) { 4633 | if (mod && mod.__esModule) return mod; 4634 | var result = {}; 4635 | if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; 4636 | result["default"] = mod; 4637 | return result; 4638 | }; 4639 | var _a; 4640 | Object.defineProperty(exports, "__esModule", { value: true }); 4641 | const assert_1 = __webpack_require__(357); 4642 | const fs = __importStar(__webpack_require__(747)); 4643 | const path = __importStar(__webpack_require__(622)); 4644 | _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; 4645 | exports.IS_WINDOWS = process.platform === 'win32'; 4646 | function exists(fsPath) { 4647 | return __awaiter(this, void 0, void 0, function* () { 4648 | try { 4649 | yield exports.stat(fsPath); 4650 | } 4651 | catch (err) { 4652 | if (err.code === 'ENOENT') { 4653 | return false; 4654 | } 4655 | throw err; 4656 | } 4657 | return true; 4658 | }); 4659 | } 4660 | exports.exists = exists; 4661 | function isDirectory(fsPath, useStat = false) { 4662 | return __awaiter(this, void 0, void 0, function* () { 4663 | const stats = useStat ? yield exports.stat(fsPath) : yield exports.lstat(fsPath); 4664 | return stats.isDirectory(); 4665 | }); 4666 | } 4667 | exports.isDirectory = isDirectory; 4668 | /** 4669 | * On OSX/Linux, true if path starts with '/'. On Windows, true for paths like: 4670 | * \, \hello, \\hello\share, C:, and C:\hello (and corresponding alternate separator cases). 4671 | */ 4672 | function isRooted(p) { 4673 | p = normalizeSeparators(p); 4674 | if (!p) { 4675 | throw new Error('isRooted() parameter "p" cannot be empty'); 4676 | } 4677 | if (exports.IS_WINDOWS) { 4678 | return (p.startsWith('\\') || /^[A-Z]:/i.test(p) // e.g. \ or \hello or \\hello 4679 | ); // e.g. C: or C:\hello 4680 | } 4681 | return p.startsWith('/'); 4682 | } 4683 | exports.isRooted = isRooted; 4684 | /** 4685 | * Recursively create a directory at `fsPath`. 4686 | * 4687 | * This implementation is optimistic, meaning it attempts to create the full 4688 | * path first, and backs up the path stack from there. 4689 | * 4690 | * @param fsPath The path to create 4691 | * @param maxDepth The maximum recursion depth 4692 | * @param depth The current recursion depth 4693 | */ 4694 | function mkdirP(fsPath, maxDepth = 1000, depth = 1) { 4695 | return __awaiter(this, void 0, void 0, function* () { 4696 | assert_1.ok(fsPath, 'a path argument must be provided'); 4697 | fsPath = path.resolve(fsPath); 4698 | if (depth >= maxDepth) 4699 | return exports.mkdir(fsPath); 4700 | try { 4701 | yield exports.mkdir(fsPath); 4702 | return; 4703 | } 4704 | catch (err) { 4705 | switch (err.code) { 4706 | case 'ENOENT': { 4707 | yield mkdirP(path.dirname(fsPath), maxDepth, depth + 1); 4708 | yield exports.mkdir(fsPath); 4709 | return; 4710 | } 4711 | default: { 4712 | let stats; 4713 | try { 4714 | stats = yield exports.stat(fsPath); 4715 | } 4716 | catch (err2) { 4717 | throw err; 4718 | } 4719 | if (!stats.isDirectory()) 4720 | throw err; 4721 | } 4722 | } 4723 | } 4724 | }); 4725 | } 4726 | exports.mkdirP = mkdirP; 4727 | /** 4728 | * Best effort attempt to determine whether a file exists and is executable. 4729 | * @param filePath file path to check 4730 | * @param extensions additional file extensions to try 4731 | * @return if file exists and is executable, returns the file path. otherwise empty string. 4732 | */ 4733 | function tryGetExecutablePath(filePath, extensions) { 4734 | return __awaiter(this, void 0, void 0, function* () { 4735 | let stats = undefined; 4736 | try { 4737 | // test file exists 4738 | stats = yield exports.stat(filePath); 4739 | } 4740 | catch (err) { 4741 | if (err.code !== 'ENOENT') { 4742 | // eslint-disable-next-line no-console 4743 | console.log(`Unexpected error attempting to determine if executable file exists '${filePath}': ${err}`); 4744 | } 4745 | } 4746 | if (stats && stats.isFile()) { 4747 | if (exports.IS_WINDOWS) { 4748 | // on Windows, test for valid extension 4749 | const upperExt = path.extname(filePath).toUpperCase(); 4750 | if (extensions.some(validExt => validExt.toUpperCase() === upperExt)) { 4751 | return filePath; 4752 | } 4753 | } 4754 | else { 4755 | if (isUnixExecutable(stats)) { 4756 | return filePath; 4757 | } 4758 | } 4759 | } 4760 | // try each extension 4761 | const originalFilePath = filePath; 4762 | for (const extension of extensions) { 4763 | filePath = originalFilePath + extension; 4764 | stats = undefined; 4765 | try { 4766 | stats = yield exports.stat(filePath); 4767 | } 4768 | catch (err) { 4769 | if (err.code !== 'ENOENT') { 4770 | // eslint-disable-next-line no-console 4771 | console.log(`Unexpected error attempting to determine if executable file exists '${filePath}': ${err}`); 4772 | } 4773 | } 4774 | if (stats && stats.isFile()) { 4775 | if (exports.IS_WINDOWS) { 4776 | // preserve the case of the actual file (since an extension was appended) 4777 | try { 4778 | const directory = path.dirname(filePath); 4779 | const upperName = path.basename(filePath).toUpperCase(); 4780 | for (const actualName of yield exports.readdir(directory)) { 4781 | if (upperName === actualName.toUpperCase()) { 4782 | filePath = path.join(directory, actualName); 4783 | break; 4784 | } 4785 | } 4786 | } 4787 | catch (err) { 4788 | // eslint-disable-next-line no-console 4789 | console.log(`Unexpected error attempting to determine the actual case of the file '${filePath}': ${err}`); 4790 | } 4791 | return filePath; 4792 | } 4793 | else { 4794 | if (isUnixExecutable(stats)) { 4795 | return filePath; 4796 | } 4797 | } 4798 | } 4799 | } 4800 | return ''; 4801 | }); 4802 | } 4803 | exports.tryGetExecutablePath = tryGetExecutablePath; 4804 | function normalizeSeparators(p) { 4805 | p = p || ''; 4806 | if (exports.IS_WINDOWS) { 4807 | // convert slashes on Windows 4808 | p = p.replace(/\//g, '\\'); 4809 | // remove redundant slashes 4810 | return p.replace(/\\\\+/g, '\\'); 4811 | } 4812 | // remove redundant slashes 4813 | return p.replace(/\/\/+/g, '/'); 4814 | } 4815 | // on Mac/Linux, test the execute bit 4816 | // R W X R W X R W X 4817 | // 256 128 64 32 16 8 4 2 1 4818 | function isUnixExecutable(stats) { 4819 | return ((stats.mode & 1) > 0 || 4820 | ((stats.mode & 8) > 0 && stats.gid === process.getgid()) || 4821 | ((stats.mode & 64) > 0 && stats.uid === process.getuid())); 4822 | } 4823 | //# sourceMappingURL=io-util.js.map 4824 | 4825 | /***/ }), 4826 | 4827 | /***/ 722: 4828 | /***/ (function(module) { 4829 | 4830 | /** 4831 | * Convert array of 16 byte values to UUID string format of the form: 4832 | * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX 4833 | */ 4834 | var byteToHex = []; 4835 | for (var i = 0; i < 256; ++i) { 4836 | byteToHex[i] = (i + 0x100).toString(16).substr(1); 4837 | } 4838 | 4839 | function bytesToUuid(buf, offset) { 4840 | var i = offset || 0; 4841 | var bth = byteToHex; 4842 | // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4 4843 | return ([ 4844 | bth[buf[i++]], bth[buf[i++]], 4845 | bth[buf[i++]], bth[buf[i++]], '-', 4846 | bth[buf[i++]], bth[buf[i++]], '-', 4847 | bth[buf[i++]], bth[buf[i++]], '-', 4848 | bth[buf[i++]], bth[buf[i++]], '-', 4849 | bth[buf[i++]], bth[buf[i++]], 4850 | bth[buf[i++]], bth[buf[i++]], 4851 | bth[buf[i++]], bth[buf[i++]] 4852 | ]).join(''); 4853 | } 4854 | 4855 | module.exports = bytesToUuid; 4856 | 4857 | 4858 | /***/ }), 4859 | 4860 | /***/ 747: 4861 | /***/ (function(module) { 4862 | 4863 | module.exports = require("fs"); 4864 | 4865 | /***/ }), 4866 | 4867 | /***/ 794: 4868 | /***/ (function(module) { 4869 | 4870 | module.exports = require("stream"); 4871 | 4872 | /***/ }), 4873 | 4874 | /***/ 826: 4875 | /***/ (function(module, __unusedexports, __webpack_require__) { 4876 | 4877 | var rng = __webpack_require__(139); 4878 | var bytesToUuid = __webpack_require__(722); 4879 | 4880 | function v4(options, buf, offset) { 4881 | var i = buf && offset || 0; 4882 | 4883 | if (typeof(options) == 'string') { 4884 | buf = options === 'binary' ? new Array(16) : null; 4885 | options = null; 4886 | } 4887 | options = options || {}; 4888 | 4889 | var rnds = options.random || (options.rng || rng)(); 4890 | 4891 | // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` 4892 | rnds[6] = (rnds[6] & 0x0f) | 0x40; 4893 | rnds[8] = (rnds[8] & 0x3f) | 0x80; 4894 | 4895 | // Copy bytes to buffer, if provided 4896 | if (buf) { 4897 | for (var ii = 0; ii < 16; ++ii) { 4898 | buf[i + ii] = rnds[ii]; 4899 | } 4900 | } 4901 | 4902 | return buf || bytesToUuid(rnds); 4903 | } 4904 | 4905 | module.exports = v4; 4906 | 4907 | 4908 | /***/ }), 4909 | 4910 | /***/ 950: 4911 | /***/ (function(__unusedmodule, exports) { 4912 | 4913 | "use strict"; 4914 | 4915 | Object.defineProperty(exports, "__esModule", { value: true }); 4916 | function getProxyUrl(reqUrl) { 4917 | let usingSsl = reqUrl.protocol === 'https:'; 4918 | let proxyUrl; 4919 | if (checkBypass(reqUrl)) { 4920 | return proxyUrl; 4921 | } 4922 | let proxyVar; 4923 | if (usingSsl) { 4924 | proxyVar = process.env['https_proxy'] || process.env['HTTPS_PROXY']; 4925 | } 4926 | else { 4927 | proxyVar = process.env['http_proxy'] || process.env['HTTP_PROXY']; 4928 | } 4929 | if (proxyVar) { 4930 | proxyUrl = new URL(proxyVar); 4931 | } 4932 | return proxyUrl; 4933 | } 4934 | exports.getProxyUrl = getProxyUrl; 4935 | function checkBypass(reqUrl) { 4936 | if (!reqUrl.hostname) { 4937 | return false; 4938 | } 4939 | let noProxy = process.env['no_proxy'] || process.env['NO_PROXY'] || ''; 4940 | if (!noProxy) { 4941 | return false; 4942 | } 4943 | // Determine the request port 4944 | let reqPort; 4945 | if (reqUrl.port) { 4946 | reqPort = Number(reqUrl.port); 4947 | } 4948 | else if (reqUrl.protocol === 'http:') { 4949 | reqPort = 80; 4950 | } 4951 | else if (reqUrl.protocol === 'https:') { 4952 | reqPort = 443; 4953 | } 4954 | // Format the request hostname and hostname with port 4955 | let upperReqHosts = [reqUrl.hostname.toUpperCase()]; 4956 | if (typeof reqPort === 'number') { 4957 | upperReqHosts.push(`${upperReqHosts[0]}:${reqPort}`); 4958 | } 4959 | // Compare request host against noproxy 4960 | for (let upperNoProxyItem of noProxy 4961 | .split(',') 4962 | .map(x => x.trim().toUpperCase()) 4963 | .filter(x => x)) { 4964 | if (upperReqHosts.some(x => x === upperNoProxyItem)) { 4965 | return true; 4966 | } 4967 | } 4968 | return false; 4969 | } 4970 | exports.checkBypass = checkBypass; 4971 | 4972 | 4973 | /***/ }), 4974 | 4975 | /***/ 966: 4976 | /***/ (function(__unusedmodule, __webpack_exports__, __webpack_require__) { 4977 | 4978 | "use strict"; 4979 | __webpack_require__.r(__webpack_exports__); 4980 | 4981 | // EXTERNAL MODULE: ./node_modules/@actions/core/lib/core.js 4982 | var core = __webpack_require__(470); 4983 | 4984 | // EXTERNAL MODULE: external "path" 4985 | var external_path_ = __webpack_require__(622); 4986 | 4987 | // EXTERNAL MODULE: ./node_modules/@actions/exec/lib/exec.js 4988 | var exec = __webpack_require__(986); 4989 | 4990 | // EXTERNAL MODULE: ./node_modules/@actions/io/lib/io.js 4991 | var io = __webpack_require__(1); 4992 | 4993 | // EXTERNAL MODULE: ./node_modules/@actions/tool-cache/lib/tool-cache.js 4994 | var tool_cache = __webpack_require__(533); 4995 | 4996 | // EXTERNAL MODULE: external "fs" 4997 | var external_fs_ = __webpack_require__(747); 4998 | 4999 | // CONCATENATED MODULE: ./src/installer.js 5000 | 5001 | 5002 | 5003 | 5004 | 5005 | 5006 | 5007 | const IS_WINDOWS = process.platform === 'win32'; 5008 | const PLATFORM = IS_WINDOWS ? 'windows' : process.platform === 'darwin' ? 'darwin' : 'linux'; 5009 | const ARCH = process.arch === 'arm64' ? 'aarch64' : 'amd64' ; 5010 | const TOOL_NAME = 'GraalVM'; 5011 | 5012 | const OPTIONS = { 5013 | tempDir : process.env['RUNNER_TEMP'] || Object(external_path_.join)(IS_WINDOWS ? process.env['USERPROFILE'] || 'C:\\' : PLATFORM === 'darwin' ? '/Users' : '/home', 'actions', 'temp'), 5014 | jvmDir : '/Library/Java/JavaVirtualMachines', 5015 | binDir : 'bin', 5016 | appDir : '/Contents/Home', 5017 | javaHome : 'JAVA_HOME', 5018 | graalHome : 'GRAALVM_HOME', 5019 | }; 5020 | 5021 | const getGraalVM = async (javaVersion, graalvmVersion, options = {}) => { 5022 | options = { 5023 | ...OPTIONS, 5024 | ...options, 5025 | }; 5026 | 5027 | const version = getVersion(javaVersion, graalvmVersion); 5028 | const tempDir = Object(external_path_.join)(options.tempDir, 'temp_' + Math.floor(Math.random() * 2000000000)); 5029 | 5030 | let toolPath = Object(tool_cache.find)(TOOL_NAME, version); 5031 | if (toolPath) { 5032 | Object(core.debug)(`${TOOL_NAME} found in cache ${toolPath}`); 5033 | } else { 5034 | const compressedFileExtension = IS_WINDOWS ? '.zip' : '.tar.gz'; 5035 | const downloadUrl = `https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-${graalvmVersion}/graalvm-ce-${version}${compressedFileExtension}`; 5036 | 5037 | Object(core.info)(`Downloading ${TOOL_NAME} from ${downloadUrl}`); 5038 | 5039 | const graalvmFile = await Object(tool_cache.downloadTool)(downloadUrl); 5040 | const graalvmDir = await decompressDownload(graalvmFile, compressedFileExtension, tempDir); 5041 | 5042 | Object(core.debug)(`${TOOL_NAME} extracted to ${graalvmDir}`); 5043 | 5044 | toolPath = await Object(tool_cache.cacheDir)(graalvmDir, TOOL_NAME, version); 5045 | } 5046 | 5047 | if (PLATFORM === 'darwin') { 5048 | await Object(io.rmRF)(tempDir); 5049 | 5050 | Object(core.exportVariable)(options.javaHome, Object(external_path_.join)(toolPath, options.appDir)); 5051 | Object(core.exportVariable)(options.graalHome, Object(external_path_.join)(toolPath, options.appDir)); 5052 | Object(core.addPath)(Object(external_path_.join)(toolPath, options.appDir, options.binDir)); 5053 | } else { 5054 | Object(core.exportVariable)(options.javaHome, toolPath); 5055 | Object(core.exportVariable)(options.graalHome, toolPath); 5056 | Object(core.addPath)(Object(external_path_.join)(toolPath, options.binDir)); 5057 | } 5058 | 5059 | return toolPath; 5060 | }; 5061 | 5062 | const getNativeImage = async () => { 5063 | await Object(exec.exec)('gu install native-image'); 5064 | }; 5065 | 5066 | const getVersion = (javaVersion, graalvmVersion) => { 5067 | return `java${javaVersion}-${PLATFORM}-${ARCH}-${graalvmVersion}`; 5068 | }; 5069 | 5070 | const decompressDownload = async (compressedFile, compressedFileExtension, destinationDir) => { 5071 | await Object(io.mkdirP)(destinationDir); 5072 | 5073 | const graalvmFile = Object(external_path_.normalize)(compressedFile); 5074 | const stats = Object(external_fs_.statSync)(graalvmFile); 5075 | 5076 | if (stats) { 5077 | if (stats.isFile()) { 5078 | await extractFiles(graalvmFile, compressedFileExtension, destinationDir); 5079 | 5080 | return Object(external_path_.join)(destinationDir, Object(external_fs_.readdirSync)(destinationDir)[0]); 5081 | } else { 5082 | throw new Error(`Failed to extract ${graalvmFile} which is not a file`); 5083 | } 5084 | } else { 5085 | throw new Error(`${graalvmFile} does not exist`); 5086 | } 5087 | }; 5088 | 5089 | const extractFiles = async (compressedFile, compressedFileExtension, destinationDir) => { 5090 | const stats = Object(external_fs_.statSync)(compressedFile); 5091 | if (stats) { 5092 | if (stats.isFile()) { 5093 | if ('.tar' === compressedFileExtension || '.tar.gz' === compressedFileExtension) { 5094 | await Object(tool_cache.extractTar)(compressedFile, destinationDir); 5095 | } else if ('.zip' === compressedFileExtension) { 5096 | await Object(tool_cache.extractZip)(compressedFile, destinationDir); 5097 | } else { 5098 | throw new Error(`Failed to extract ${compressedFile} which is in an unrecognized compression format`); 5099 | } 5100 | } else { 5101 | throw new Error(`Failed to extract ${compressedFile} which is not a file`); 5102 | } 5103 | } else { 5104 | throw new Error(`${compressedFile} does not exist`); 5105 | } 5106 | }; 5107 | 5108 | // CONCATENATED MODULE: ./src/setup-graalvm.js 5109 | 5110 | 5111 | 5112 | 5113 | 5114 | const run = async () => { 5115 | try { 5116 | await getGraalVM(Object(core.getInput)('java-version', { 5117 | required : true, 5118 | }), Object(core.getInput)('graalvm-version', { 5119 | required : true, 5120 | })); 5121 | 5122 | if (Object(core.getInput)('native-image')) await getNativeImage(); 5123 | 5124 | console.log(`##[add-matcher]${Object(external_path_.join)(Object(external_path_.join)(__dirname, '..', '.github'), 'graalvm.json')}`); 5125 | } catch (error) { 5126 | Object(core.setFailed)(error); 5127 | } 5128 | }; 5129 | 5130 | run(); 5131 | 5132 | 5133 | /***/ }), 5134 | 5135 | /***/ 979: 5136 | /***/ (function(__unusedmodule, exports, __webpack_require__) { 5137 | 5138 | "use strict"; 5139 | 5140 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 5141 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 5142 | return new (P || (P = Promise))(function (resolve, reject) { 5143 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 5144 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 5145 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 5146 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 5147 | }); 5148 | }; 5149 | var __importStar = (this && this.__importStar) || function (mod) { 5150 | if (mod && mod.__esModule) return mod; 5151 | var result = {}; 5152 | if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; 5153 | result["default"] = mod; 5154 | return result; 5155 | }; 5156 | Object.defineProperty(exports, "__esModule", { value: true }); 5157 | const core = __importStar(__webpack_require__(470)); 5158 | /** 5159 | * Internal class for retries 5160 | */ 5161 | class RetryHelper { 5162 | constructor(maxAttempts, minSeconds, maxSeconds) { 5163 | if (maxAttempts < 1) { 5164 | throw new Error('max attempts should be greater than or equal to 1'); 5165 | } 5166 | this.maxAttempts = maxAttempts; 5167 | this.minSeconds = Math.floor(minSeconds); 5168 | this.maxSeconds = Math.floor(maxSeconds); 5169 | if (this.minSeconds > this.maxSeconds) { 5170 | throw new Error('min seconds should be less than or equal to max seconds'); 5171 | } 5172 | } 5173 | execute(action, isRetryable) { 5174 | return __awaiter(this, void 0, void 0, function* () { 5175 | let attempt = 1; 5176 | while (attempt < this.maxAttempts) { 5177 | // Try 5178 | try { 5179 | return yield action(); 5180 | } 5181 | catch (err) { 5182 | if (isRetryable && !isRetryable(err)) { 5183 | throw err; 5184 | } 5185 | core.info(err.message); 5186 | } 5187 | // Sleep 5188 | const seconds = this.getSleepAmount(); 5189 | core.info(`Waiting ${seconds} seconds before trying again`); 5190 | yield this.sleep(seconds); 5191 | attempt++; 5192 | } 5193 | // Last attempt 5194 | return yield action(); 5195 | }); 5196 | } 5197 | getSleepAmount() { 5198 | return (Math.floor(Math.random() * (this.maxSeconds - this.minSeconds + 1)) + 5199 | this.minSeconds); 5200 | } 5201 | sleep(seconds) { 5202 | return __awaiter(this, void 0, void 0, function* () { 5203 | return new Promise(resolve => setTimeout(resolve, seconds * 1000)); 5204 | }); 5205 | } 5206 | } 5207 | exports.RetryHelper = RetryHelper; 5208 | //# sourceMappingURL=retry-helper.js.map 5209 | 5210 | /***/ }), 5211 | 5212 | /***/ 986: 5213 | /***/ (function(__unusedmodule, exports, __webpack_require__) { 5214 | 5215 | "use strict"; 5216 | 5217 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 5218 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 5219 | return new (P || (P = Promise))(function (resolve, reject) { 5220 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 5221 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 5222 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 5223 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 5224 | }); 5225 | }; 5226 | var __importStar = (this && this.__importStar) || function (mod) { 5227 | if (mod && mod.__esModule) return mod; 5228 | var result = {}; 5229 | if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; 5230 | result["default"] = mod; 5231 | return result; 5232 | }; 5233 | Object.defineProperty(exports, "__esModule", { value: true }); 5234 | const tr = __importStar(__webpack_require__(9)); 5235 | /** 5236 | * Exec a command. 5237 | * Output will be streamed to the live console. 5238 | * Returns promise with return code 5239 | * 5240 | * @param commandLine command to execute (can include additional args). Must be correctly escaped. 5241 | * @param args optional arguments for tool. Escaping is handled by the lib. 5242 | * @param options optional exec options. See ExecOptions 5243 | * @returns Promise exit code 5244 | */ 5245 | function exec(commandLine, args, options) { 5246 | return __awaiter(this, void 0, void 0, function* () { 5247 | const commandArgs = tr.argStringToArray(commandLine); 5248 | if (commandArgs.length === 0) { 5249 | throw new Error(`Parameter 'commandLine' cannot be null or empty.`); 5250 | } 5251 | // Path to tool to execute should be first arg 5252 | const toolPath = commandArgs[0]; 5253 | args = commandArgs.slice(1).concat(args || []); 5254 | const runner = new tr.ToolRunner(toolPath, args, options); 5255 | return runner.exec(); 5256 | }); 5257 | } 5258 | exports.exec = exec; 5259 | //# sourceMappingURL=exec.js.map 5260 | 5261 | /***/ }) 5262 | 5263 | /******/ }, 5264 | /******/ function(__webpack_require__) { // webpackRuntimeModules 5265 | /******/ "use strict"; 5266 | /******/ 5267 | /******/ /* webpack/runtime/make namespace object */ 5268 | /******/ !function() { 5269 | /******/ // define __esModule on exports 5270 | /******/ __webpack_require__.r = function(exports) { 5271 | /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 5272 | /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 5273 | /******/ } 5274 | /******/ Object.defineProperty(exports, '__esModule', { value: true }); 5275 | /******/ }; 5276 | /******/ }(); 5277 | /******/ 5278 | /******/ /* webpack/runtime/define property getter */ 5279 | /******/ !function() { 5280 | /******/ // define getter function for harmony exports 5281 | /******/ var hasOwnProperty = Object.prototype.hasOwnProperty; 5282 | /******/ __webpack_require__.d = function(exports, name, getter) { 5283 | /******/ if(!hasOwnProperty.call(exports, name)) { 5284 | /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); 5285 | /******/ } 5286 | /******/ }; 5287 | /******/ }(); 5288 | /******/ 5289 | /******/ /* webpack/runtime/create fake namespace object */ 5290 | /******/ !function() { 5291 | /******/ // create a fake namespace object 5292 | /******/ // mode & 1: value is a module id, require it 5293 | /******/ // mode & 2: merge all properties of value into the ns 5294 | /******/ // mode & 4: return value when already ns object 5295 | /******/ // mode & 8|1: behave like require 5296 | /******/ __webpack_require__.t = function(value, mode) { 5297 | /******/ if(mode & 1) value = this(value); 5298 | /******/ if(mode & 8) return value; 5299 | /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; 5300 | /******/ var ns = Object.create(null); 5301 | /******/ __webpack_require__.r(ns); 5302 | /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); 5303 | /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); 5304 | /******/ return ns; 5305 | /******/ }; 5306 | /******/ }(); 5307 | /******/ 5308 | /******/ /* webpack/runtime/compat get default export */ 5309 | /******/ !function() { 5310 | /******/ // getDefaultExport function for compatibility with non-harmony modules 5311 | /******/ __webpack_require__.n = function(module) { 5312 | /******/ var getter = module && module.__esModule ? 5313 | /******/ function getDefault() { return module['default']; } : 5314 | /******/ function getModuleExports() { return module; }; 5315 | /******/ __webpack_require__.d(getter, 'a', getter); 5316 | /******/ return getter; 5317 | /******/ }; 5318 | /******/ }(); 5319 | /******/ 5320 | /******/ } 5321 | ); --------------------------------------------------------------------------------