diff --git a/.circleci/config.yml b/.circleci/config.yml index ad6a2c45bc..feb008a008 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1410,7 +1410,6 @@ commands: - run: name: Preserve vendor dirs for release command: | - mv src/electron/vendor/boto . mv src/electron/vendor/requests . - run: name: Wipe Electron @@ -1423,9 +1422,7 @@ commands: - run: name: Preserve vendor dirs for release command: | - rm -rf src/electron/vendor/boto rm -rf src/electron/vendor/requests - mv boto src/electron/vendor mv requests src/electron/vendor/requests - *step-generate-deps-hash-cleanly - *step-mark-sync-done @@ -1621,7 +1618,7 @@ jobs: <<: *machine-linux-2xlarge environment: <<: *env-linux-2xlarge - GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True --custom-var=checkout_boto=True --custom-var=checkout_requests=True' + GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True --custom-var=checkout_requests=True' steps: - electron-build: persist: false @@ -1680,7 +1677,7 @@ jobs: <<: *env-linux-2xlarge <<: *env-testing-build <<: *env-macos-build - GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac --custom-var=checkout_boto=True --custom-var=checkout_requests=True' + GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac --custom-var=checkout_requests=True' steps: - electron-build: persist: false @@ -1773,7 +1770,7 @@ jobs: <<: *machine-linux-2xlarge environment: <<: *env-linux-2xlarge-release - GCLIENT_EXTRA_ARGS: '--custom-var=checkout_boto=True --custom-var=checkout_requests=True' + GCLIENT_EXTRA_ARGS: '--custom-var=checkout_requests=True' <<: *env-release-build <<: *env-enable-sccache UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >> @@ -1835,7 +1832,7 @@ jobs: <<: *machine-linux-2xlarge environment: <<: *env-linux-2xlarge-release - GCLIENT_EXTRA_ARGS: '--custom-var=checkout_boto=True --custom-var=checkout_requests=True' + GCLIENT_EXTRA_ARGS: '--custom-var=checkout_requests=True' <<: *env-ia32 <<: *env-release-build <<: *env-enable-sccache @@ -1906,7 +1903,7 @@ jobs: <<: *env-release-build <<: *env-enable-sccache <<: *env-32bit-release - GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_boto=True --custom-var=checkout_requests=True' + GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_requests=True' UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >> steps: - electron-publish: @@ -1980,7 +1977,7 @@ jobs: <<: *env-arm64 <<: *env-release-build <<: *env-enable-sccache - GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm64=True --custom-var=checkout_boto=True --custom-var=checkout_requests=True' + GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm64=True --custom-var=checkout_requests=True' UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >> steps: - electron-publish: @@ -2042,7 +2039,7 @@ jobs: <<: *env-mac-large-release <<: *env-release-build <<: *env-enable-sccache - GCLIENT_EXTRA_ARGS: '--custom-var=checkout_boto=True --custom-var=checkout_requests=True' + GCLIENT_EXTRA_ARGS: '--custom-var=checkout_requests=True' UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >> steps: - electron-publish: @@ -2056,7 +2053,7 @@ jobs: <<: *env-release-build <<: *env-enable-sccache <<: *env-apple-silicon - GCLIENT_EXTRA_ARGS: '--custom-var=checkout_boto=True --custom-var=checkout_requests=True' + GCLIENT_EXTRA_ARGS: '--custom-var=checkout_requests=True' UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >> steps: - electron-publish: @@ -2150,7 +2147,7 @@ jobs: <<: *env-mas <<: *env-release-build <<: *env-enable-sccache - GCLIENT_EXTRA_ARGS: '--custom-var=checkout_boto=True --custom-var=checkout_requests=True' + GCLIENT_EXTRA_ARGS: '--custom-var=checkout_requests=True' UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >> steps: - electron-publish: @@ -2164,7 +2161,7 @@ jobs: <<: *env-mas-apple-silicon <<: *env-release-build <<: *env-enable-sccache - GCLIENT_EXTRA_ARGS: '--custom-var=checkout_boto=True --custom-var=checkout_requests=True' + GCLIENT_EXTRA_ARGS: '--custom-var=checkout_requests=True' UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >> steps: - electron-publish: diff --git a/DEPS b/DEPS index 0db89c9b3e..d8141cfe97 100644 --- a/DEPS +++ b/DEPS @@ -22,11 +22,9 @@ vars = { 'squirrel.mac_version': '44468f858ce0d25c27bd5e674abfa104e0119738', - 'boto_version': 'f7574aa6cc2c819430c1f05e9a1a1a666ef8169b', 'pyyaml_version': '3.12', 'requests_version': 'e4d59bedfd3c7f4f254f4f5d036587bcd8152458', - 'boto_git': 'https://github.com/boto', 'chromium_git': 'https://chromium.googlesource.com', 'electron_git': 'https://github.com/electron', 'nodejs_git': 'https://github.com/nodejs', @@ -40,9 +38,6 @@ vars = { # To be able to build clean Chromium from sources. 'apply_patches': True, - # Python interface to Amazon Web Services. Is used for releases only. - 'checkout_boto': False, - # To allow in-house builds to checkout those manually. 'checkout_chromium': True, 'checkout_node': True, @@ -99,10 +94,6 @@ deps = { 'url': (Var("yaml_git")) + '/pyyaml.git@' + (Var("pyyaml_version")), 'condition': 'checkout_pyyaml and process_deps', }, - 'src/electron/vendor/boto': { - 'url': Var('boto_git') + '/boto.git' + '@' + Var('boto_version'), - 'condition': 'checkout_boto and process_deps', - }, 'src/electron/vendor/requests': { 'url': Var('requests_git') + '/requests.git' + '@' + Var('requests_version'), 'condition': 'checkout_requests and process_deps', @@ -150,16 +141,6 @@ hooks = [ 'import os, subprocess; os.chdir(os.path.join("src", "electron")); subprocess.check_call(["python", "script/lib/npx.py", "yarn@' + (Var("yarn_version")) + '", "install", "--frozen-lockfile"]);', ], }, - { - 'name': 'setup_boto', - 'pattern': 'src/electron', - 'condition': 'checkout_boto and process_deps', - 'action': [ - 'python3', - '-c', - 'import os, subprocess; os.chdir(os.path.join("src", "electron", "vendor", "boto")); subprocess.check_call(["python", "setup.py", "build"]);', - ], - }, { 'name': 'setup_requests', 'pattern': 'src/electron', diff --git a/appveyor.yml b/appveyor.yml index 40b8ee196b..e71018e9a8 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -67,7 +67,7 @@ build_script: - ps: $env:SCCACHE_PATH="$pwd\src\electron\external_binaries\sccache.exe" - ps: >- if ($env:GN_CONFIG -eq 'release') { - $env:GCLIENT_EXTRA_ARGS="$env:GCLIENT_EXTRA_ARGS --custom-var=checkout_boto=True --custom-var=checkout_requests=True" + $env:GCLIENT_EXTRA_ARGS="$env:GCLIENT_EXTRA_ARGS --custom-var=checkout_requests=True" } else { $env:NINJA_STATUS="[%r processes, %f/%t @ %o/s : %es] " } diff --git a/docs/development/source-code-directory-structure.md b/docs/development/source-code-directory-structure.md index 59cf6323a2..877081f0bb 100644 --- a/docs/development/source-code-directory-structure.md +++ b/docs/development/source-code-directory-structure.md @@ -101,33 +101,5 @@ script/ - The set of all scripts Electron runs for a variety of purposes. * **tools** - Helper scripts used by GN files. * Scripts put here should never be invoked by users directly, unlike those in `script`. * **typings** - TypeScript typings for Electron's internal code. -* **vendor** - Source code for some third party dependencies, including `boto` and `requests`. +* **vendor** - Source code for some third party dependencies. -## Keeping Git Submodules Up to Date - -The Electron repository has a few vendored dependencies, found in the -[/vendor][vendor] directory. Occasionally you might see a message like this -when running `git status`: - -```sh -$ git status - - modified: vendor/depot_tools (new commits) - modified: vendor/boto (new commits) -``` - -To update these vendored dependencies, run the following command: - -```sh -git submodule update --init --recursive -``` - -If you find yourself running this command often, you can create an alias for it -in your `~/.gitconfig` file: - -```sh -[alias] - su = submodule update --init --recursive -``` - -[vendor]: https://github.com/electron/electron/tree/master/vendor diff --git a/package.json b/package.json index 15b21d805b..62a22176f0 100644 --- a/package.json +++ b/package.json @@ -137,6 +137,7 @@ ] }, "dependencies": { - "@types/temp": "^0.8.34" + "@types/temp": "^0.8.34", + "aws-sdk": "^2.727.1" } -} \ No newline at end of file +} diff --git a/script/lib/s3put.js b/script/lib/s3put.js new file mode 100644 index 0000000000..89a801ef1b --- /dev/null +++ b/script/lib/s3put.js @@ -0,0 +1,38 @@ +/* eslint-disable camelcase */ +const AWS = require('aws-sdk'); +const fs = require('fs'); +const path = require('path'); +AWS.config.update({ region: 'us-west-2' }); +const s3 = new AWS.S3({ apiVersion: '2006-03-01' }); + +const args = require('minimist')(process.argv.slice(2)); + +let { bucket, prefix = '/', key_prefix = '', grant, _: files } = args; +if (prefix && !prefix.endsWith(path.sep)) prefix = path.resolve(prefix) + path.sep; + +function filenameToKey (file) { + file = path.resolve(file); + if (file.startsWith(prefix)) file = file.substr(prefix.length); + return key_prefix + file.replace(path.sep, '/'); +} + +let anErrorOccurred = false; +function next (done) { + const file = files.shift(); + if (!file) return done(); + s3.upload({ + Bucket: bucket, + Key: filenameToKey(file), + Body: fs.createReadStream(file), + ACL: grant + }, (err, data) => { + if (err) { + console.error(err); + anErrorOccurred = true; + } + next(done); + }); +} +next(() => { + process.exit(anErrorOccurred ? 1 : 0); +}); diff --git a/script/lib/util.py b/script/lib/util.py index c717ab989d..6212eca47d 100644 --- a/script/lib/util.py +++ b/script/lib/util.py @@ -30,8 +30,6 @@ ELECTRON_DIR = os.path.abspath( os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ) SRC_DIR = os.path.abspath(os.path.join(__file__, '..', '..', '..', '..')) -BOTO_DIR = os.path.abspath(os.path.join(__file__, '..', '..', '..', 'vendor', - 'boto')) NPM = 'npm' if sys.platform in ['win32', 'cygwin']: @@ -199,33 +197,18 @@ def get_electron_version(): with open(version_file) as f: return 'v' + f.read().strip() -def boto_path_dirs(): - return [ - os.path.join(BOTO_DIR, 'build', 'lib'), - os.path.join(BOTO_DIR, 'build', 'lib.linux-x86_64-2.7') - ] - - -def run_boto_script(access_key, secret_key, script_name, *args): +def s3put(bucket, access_key, secret_key, prefix, key_prefix, files): env = os.environ.copy() env['AWS_ACCESS_KEY_ID'] = access_key env['AWS_SECRET_ACCESS_KEY'] = secret_key - env['PYTHONPATH'] = os.path.pathsep.join( - [env.get('PYTHONPATH', '')] + boto_path_dirs()) - - boto = os.path.join(BOTO_DIR, 'bin', script_name) - execute([sys.executable, boto] + list(args), env) - - -def s3put(bucket, access_key, secret_key, prefix, key_prefix, files): - args = [ + execute([ + 'node', + os.path.join(os.path.dirname(__file__), 's3put.js'), '--bucket', bucket, '--prefix', prefix, '--key_prefix', key_prefix, - '--grant', 'public-read' - ] + files - - run_boto_script(access_key, secret_key, 's3put', *args) + '--grant', 'public-read', + ] + files, env) def add_exec_bit(filename): diff --git a/script/release/merge-electron-checksums.py b/script/release/merge-electron-checksums.py deleted file mode 100755 index 291426d2cb..0000000000 --- a/script/release/merge-electron-checksums.py +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env python - -# Download individual checksum files for Electron zip files from S3, -# concatenate them, and upload to GitHub. - -from __future__ import print_function - -import argparse -import os -import sys - -sys.path.append(os.path.dirname(os.path.abspath(__file__)) + "/..") - -from lib.config import s3_config -from lib.util import boto_path_dirs - -sys.path.extend(boto_path_dirs()) -from boto.s3.connection import S3Connection - - -def main(): - args = parse_args() - - bucket_name, access_key, secret_key = s3_config() - s3 = S3Connection(access_key, secret_key) - bucket = s3.get_bucket(bucket_name) - if bucket is None: - print('S3 bucket "{}" does not exist!'.format(bucket_name), file=sys.stderr) - return 1 - - prefix = 'atom-shell/tmp/{0}/'.format(args.version) - shasums = [s3_object.get_contents_as_string().strip() - for s3_object in bucket.list(prefix, delimiter='/') - if s3_object.key.endswith('.sha256sum')] - print('\n'.join(shasums)) - return 0 - - -def parse_args(): - parser = argparse.ArgumentParser(description='Upload SHASUMS files to GitHub') - parser.add_argument('-v', '--version', help='Specify the version', - required=True) - return parser.parse_args() - - -if __name__ == '__main__': - sys.exit(main()) diff --git a/script/release/release.js b/script/release/release.js index 5785403a7b..cfa0f7411a 100755 --- a/script/release/release.js +++ b/script/release/release.js @@ -22,6 +22,7 @@ const sumchecker = require('sumchecker'); const temp = require('temp').track(); const { URL } = require('url'); const { Octokit } = require('@octokit/rest'); +const AWS = require('aws-sdk'); require('colors'); const pass = '✓'.green; @@ -218,6 +219,41 @@ function uploadIndexJson () { console.log(`${pass} Done uploading index.json to S3.`); } +async function mergeShasums (pkgVersion) { + // Download individual checksum files for Electron zip files from S3, + // concatenate them, and upload to GitHub. + + const bucket = process.env.ELECTRON_S3_BUCKET; + const accessKeyId = process.env.ELECTRON_S3_ACCESS_KEY; + const secretAccessKey = process.env.ELECTRON_S3_SECRET_KEY; + if (!bucket || !accessKeyId || !secretAccessKey) { + throw new Error('Please set the $ELECTRON_S3_BUCKET, $ELECTRON_S3_ACCESS_KEY, and $ELECTRON_S3_SECRET_KEY environment variables'); + } + + const s3 = new AWS.S3({ + apiVersion: '2006-03-01', + accessKeyId, + secretAccessKey, + region: 'us-west-2' + }); + const objects = await s3.listObjectsV2({ + Bucket: bucket, + Prefix: `atom-shell/tmp/${pkgVersion}/`, + Delimiter: '/' + }).promise(); + const shasums = []; + for (const obj of objects.Contents) { + if (obj.Key.endsWith('.sha256sum')) { + const data = await s3.getObject({ + Bucket: bucket, + Key: obj.Key + }).promise(); + shasums.push(data.toString('ascii').trim()); + } + } + return shasums.join('\n'); +} + async function createReleaseShasums (release) { const fileName = 'SHASUMS256.txt'; const existingAssets = release.assets.filter(asset => asset.name === fileName); @@ -232,8 +268,7 @@ async function createReleaseShasums (release) { }); } console.log(`Creating and uploading the release ${fileName}.`); - const scriptPath = path.join(ELECTRON_DIR, 'script', 'release', 'merge-electron-checksums.py'); - const checksums = runScript(scriptPath, ['-v', pkgVersion]); + const checksums = await mergeShasums(pkgVersion); console.log(`${pass} Generated release SHASUMS.`); const filePath = await saveShaSumFile(checksums, fileName); diff --git a/yarn.lock b/yarn.lock index 90d73cec98..9127ed2a90 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1037,6 +1037,21 @@ atob@^2.1.1: resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== +aws-sdk@^2.727.1: + version "2.727.1" + resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.727.1.tgz#bde7a4b57b6c5b34370ad20963472ea7d24a9351" + integrity sha512-K+XdN11os6hvI9DgWEK9m/fPKHuDDVZalFWPouwqSk0phEdDCJ/K8InHUFL9DMvE4bxyWRuqI9dzNfdmxX0sxQ== + dependencies: + buffer "4.9.2" + events "1.1.1" + ieee754 "1.1.13" + jmespath "0.15.0" + querystring "0.2.0" + sax "1.2.1" + url "0.10.3" + uuid "3.3.2" + xml2js "0.4.19" + aws-sign2@~0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" @@ -1275,6 +1290,15 @@ buffer-xor@^1.0.3: resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= +buffer@4.9.2: + version "4.9.2" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" + integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + buffer@^4.3.0: version "4.9.1" resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" @@ -2708,6 +2732,11 @@ events-to-array@^1.0.1: resolved "https://registry.yarnpkg.com/events-to-array/-/events-to-array-1.1.2.tgz#2d41f563e1fe400ed4962fe1a4d5c6a7539df7f6" integrity sha1-LUH1Y+H+QA7Uli/hpNXGp1Od9/Y= +events@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" + integrity sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ= + events@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/events/-/events-3.0.0.tgz#9a0a0dfaf62893d92b875b8f2698ca4114973e88" @@ -3643,7 +3672,7 @@ iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4: dependencies: safer-buffer ">= 2.1.2 < 3" -ieee754@^1.1.4: +ieee754@1.1.13, ieee754@^1.1.4: version "1.1.13" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== @@ -4199,6 +4228,11 @@ isstream@~0.1.2: resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= +jmespath@0.15.0: + version "0.15.0" + resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.15.0.tgz#a3f222a9aae9f966f5d27c796510e28091764217" + integrity sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc= + "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -6904,7 +6938,12 @@ safe-regex@^1.1.0: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -sax@^1.2.4: +sax@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a" + integrity sha1-e45lYZCyKOgaZq6nSEgNgozS03o= + +sax@>=0.6.0, sax@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== @@ -8155,6 +8194,14 @@ url-parse-lax@^1.0.0: dependencies: prepend-http "^1.0.1" +url@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/url/-/url-0.10.3.tgz#021e4d9c7705f21bbf37d03ceb58767402774c64" + integrity sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ= + dependencies: + punycode "1.3.2" + querystring "0.2.0" + url@^0.11.0: version "0.11.0" resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" @@ -8192,7 +8239,7 @@ utils-merge@1.0.1: resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= -uuid@^3.3.2: +uuid@3.3.2, uuid@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== @@ -8445,6 +8492,14 @@ x-is-string@^0.1.0: resolved "https://registry.yarnpkg.com/x-is-string/-/x-is-string-0.1.0.tgz#474b50865af3a49a9c4657f05acd145458f77d82" integrity sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI= +xml2js@0.4.19: + version "0.4.19" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7" + integrity sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q== + dependencies: + sax ">=0.6.0" + xmlbuilder "~9.0.1" + xmlbuilder@~4.2.0: version "4.2.1" resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-4.2.1.tgz#aa58a3041a066f90eaa16c2f5389ff19f3f461a5" @@ -8452,6 +8507,11 @@ xmlbuilder@~4.2.0: dependencies: lodash "^4.0.0" +xmlbuilder@~9.0.1: + version "9.0.7" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" + integrity sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0= + xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.0, xtend@~4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"