chore: remove @appium/gulp-plugins

Closes #17907
This commit is contained in:
Christopher Hiller
2022-12-15 14:04:18 -08:00
parent feeaac4713
commit 9842e231c5
65 changed files with 71 additions and 10078 deletions
-2
View File
@@ -29,8 +29,6 @@ targets:
path: ./packages/eslint-config-appium
- type: npm
path: ./packages/fake-driver
- type: npm
path: ./packages/gulp-plugins
- type: npm
path: ./packages/support
- type: npm
+71 -7617
View File
File diff suppressed because it is too large Load Diff
-1
View File
@@ -99,7 +99,6 @@
"fancy-log": "2.0.0",
"finalhandler": "1.2.0",
"get-port": "5.1.1",
"gulp": "4.0.2",
"handlebars": "4.7.7",
"husky": "8.0.2",
"json-schema-to-typescript": "11.0.2",
-32
View File
@@ -1,32 +0,0 @@
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"node": "12"
},
"shippedProposals": true
}
]
],
"plugins": ["source-map-support"],
"comments": false,
"sourceMaps": "both",
"env": {
"coverage": {
"plugins": [
[
"istanbul",
{
"exclude": ["test", "build"]
}
]
]
},
"test": {
"retainLines": true,
"comments": true
}
}
}
-11
View File
@@ -1,11 +0,0 @@
// @ts-check
'use strict';
module.exports = {
require: [require.resolve('./test/setup.js')],
// forbids use of .only() in CI
forbidOnly: Boolean(process.env.CI),
// increase default timeout for CI since it can be slow
timeout: process.env.CI ? '5s' : '2s',
};
-151
View File
@@ -1,151 +0,0 @@
# Change Log
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [8.0.0](https://github.com/appium/appium/compare/@appium/gulp-plugins@7.0.8...@appium/gulp-plugins@8.0.0) (2022-12-14)
### Bug Fixes
- **gulp-plugins:** update babel monorepo to v7.20.2 ([6e3bfb8](https://github.com/appium/appium/commit/6e3bfb8847db8fc906c09ba01a5dc11636ba3ab1))
- **gulp-plugins:** update definitelytyped ([0ca2bde](https://github.com/appium/appium/commit/0ca2bdecf23965c5d454f47289983f4d52568eaa))
- **gulp-plugins:** update dependency @babel/core to v7.20.5 ([02ad17b](https://github.com/appium/appium/commit/02ad17bce626c7c308b835804209818a9e9a0880))
- **gulp-plugins:** update dependency eslint to v8.27.0 ([e70e672](https://github.com/appium/appium/commit/e70e6727964e2fb5f46f6085e59d38cfd21b9839))
- **gulp-plugins:** update dependency eslint to v8.28.0 ([e054f58](https://github.com/appium/appium/commit/e054f58c5056369d3e311f4102444db68be1dc57))
- **gulp-plugins:** update dependency eslint to v8.29.0 ([cf34e4c](https://github.com/appium/appium/commit/cf34e4c17ac8867a3614124016817dc0060c99b0))
- **gulp-plugins:** update dependency mocha to v10.2.0 ([c787bd6](https://github.com/appium/appium/commit/c787bd6fb5fb18a37cc9a4a5be1b2aa65eaa114a))
- **gulp-plugins:** update dependency plugin-error to v2.0.1 ([37ec293](https://github.com/appium/appium/commit/37ec2938d6ce42cf12a4217e5273f1e55a290553))
- **gulp-plugins:** update dependency yargs to v17.6.1 ([ea1b6a3](https://github.com/appium/appium/commit/ea1b6a3334ee5330abd456a7d4467fc92d94270d))
- **gulp-plugins:** update dependency yargs to v17.6.2 ([a95b2e0](https://github.com/appium/appium/commit/a95b2e0fe6fc646ad5e1fb3479b448ad3a66c880))
- **support:** update dependency axios to v1.2.0 ([b80b88b](https://github.com/appium/appium/commit/b80b88bd9cf2d6325ea6104449170b8339bf23e0))
- **support:** update dependency axios to v1.2.1 ([07d6ef6](https://github.com/appium/appium/commit/07d6ef6b8cc1608da8860f601a80ec0f6a7a7598))
- chore!: set engines to minimum Node.js v14.17.0 ([a1dbe6c](https://github.com/appium/appium/commit/a1dbe6c43efe76604943a607d402f4c8b864d652))
### BREAKING CHANGES
- Appium now supports version range `^14.17.0 || ^16.13.0 || >=18.0.0`
## [7.0.8](https://github.com/appium/appium/compare/@appium/gulp-plugins@7.0.7...@appium/gulp-plugins@7.0.8) (2022-10-14)
**Note:** Version bump only for package @appium/gulp-plugins
## [7.0.7](https://github.com/appium/appium/compare/@appium/gulp-plugins@7.0.6...@appium/gulp-plugins@7.0.7) (2022-10-13)
**Note:** Version bump only for package @appium/gulp-plugins
## [7.0.6](https://github.com/appium/appium/compare/@appium/gulp-plugins@7.0.5...@appium/gulp-plugins@7.0.6) (2022-09-07)
**Note:** Version bump only for package @appium/gulp-plugins
## [7.0.5](https://github.com/appium/appium/compare/@appium/gulp-plugins@7.0.4...@appium/gulp-plugins@7.0.5) (2022-08-10)
**Note:** Version bump only for package @appium/gulp-plugins
## [7.0.4](https://github.com/appium/appium/compare/@appium/gulp-plugins@7.0.3...@appium/gulp-plugins@7.0.4) (2022-08-03)
### Bug Fixes
- **appium,base-driver,base-plugin,doctor,docutils,eslint-config-appium,execute-driver-plugin,fake-driver,fake-plugin,gulp-plugins,images-plugin,opencv,relaxed-caps-plugin,schema,support,test-support,types,universal-xml-plugin:** update engines ([d8d2382](https://github.com/appium/appium/commit/d8d2382327ba7b7db8a4d1cad987c0e60184c92d))
## [7.0.3](https://github.com/appium/appium/compare/@appium/gulp-plugins@7.0.2...@appium/gulp-plugins@7.0.3) (2022-07-28)
### Bug Fixes
- moved type packages to deps of specific packages ([f9129df](https://github.com/appium/appium/commit/f9129dfee32fcc3f89ffcfa69fb83b7c2419c24f))
## [7.0.2](https://github.com/appium/appium/compare/@appium/gulp-plugins@7.0.1...@appium/gulp-plugins@7.0.2) (2022-05-31)
**Note:** Version bump only for package @appium/gulp-plugins
## [7.0.1](https://github.com/appium/appium/compare/@appium/gulp-plugins@7.0.0...@appium/gulp-plugins@7.0.1) (2022-05-31)
### Bug Fixes
- **appium:** fix extension autoinstall postinstall script ([3e2c05d](https://github.com/appium/appium/commit/3e2c05d8a290072484afde34fe5fd968618f6359)), closes [#16924](https://github.com/appium/appium/issues/16924)
# [7.0.0](https://github.com/appium/appium/compare/@appium/gulp-plugins@6.0.10...@appium/gulp-plugins@7.0.0) (2022-05-03)
### Features
- **eslint-config-appium,gulp-plugins:** add prettier ([878bb6a](https://github.com/appium/appium/commit/878bb6a44f85fd43e0f3678b95cddb8d7cbba69a))
### BREAKING CHANGES
- **eslint-config-appium,gulp-plugins:** `@appium/eslint-config-appium` now requires peer dependency `eslint-config-prettier`. Because `@appium/gulp-plugins` always uses the latest development version of `@appium/eslint-config-appium`, the dependency needs to be added there, too.
In addition, this disables some rules, so _may_ cause code which previously passed lint checks _not_ to pass lint checks.
## [6.0.10](https://github.com/appium/appium/compare/@appium/gulp-plugins@6.0.9...@appium/gulp-plugins@6.0.10) (2022-05-03)
**Note:** Version bump only for package @appium/gulp-plugins
## [6.0.9](https://github.com/appium/appium/compare/@appium/gulp-plugins@6.0.8...@appium/gulp-plugins@6.0.9) (2022-05-02)
**Note:** Version bump only for package @appium/gulp-plugins
## [6.0.8](https://github.com/appium/appium/compare/@appium/gulp-plugins@6.0.7...@appium/gulp-plugins@6.0.8) (2022-04-20)
**Note:** Version bump only for package @appium/gulp-plugins
## [6.0.7](https://github.com/appium/appium/compare/@appium/gulp-plugins@6.0.6...@appium/gulp-plugins@6.0.7) (2022-04-20)
**Note:** Version bump only for package @appium/gulp-plugins
## [6.0.6](https://github.com/appium/appium/compare/@appium/gulp-plugins@6.0.5...@appium/gulp-plugins@6.0.6) (2022-04-20)
**Note:** Version bump only for package @appium/gulp-plugins
## [6.0.5](https://github.com/appium/appium/compare/@appium/gulp-plugins@6.0.4...@appium/gulp-plugins@6.0.5) (2022-04-12)
**Note:** Version bump only for package @appium/gulp-plugins
## [6.0.4](https://github.com/appium/appium/compare/@appium/gulp-plugins@6.0.3...@appium/gulp-plugins@6.0.4) (2022-04-12)
**Note:** Version bump only for package @appium/gulp-plugins
## [6.0.3](https://github.com/appium/appium/compare/@appium/gulp-plugins@6.0.2...@appium/gulp-plugins@6.0.3) (2022-04-07)
**Note:** Version bump only for package @appium/gulp-plugins
## [6.0.2](https://github.com/appium/appium/compare/@appium/gulp-plugins@6.0.1...@appium/gulp-plugins@6.0.2) (2022-03-22)
**Note:** Version bump only for package @appium/gulp-plugins
## [6.0.1](https://github.com/appium/appium/compare/@appium/gulp-plugins@6.0.0...@appium/gulp-plugins@6.0.1) (2022-01-11)
**Note:** Version bump only for package @appium/gulp-plugins
# [6.0.0](https://github.com/appium/appium/compare/@appium/gulp-plugins@5.5.5...@appium/gulp-plugins@6.0.0) (2021-11-19)
### Bug Fixes
- **gulp-plugins:** do not transpile pkg root .js files by default ([b3771b0](https://github.com/appium/appium/commit/b3771b00421669a96a830400d97561a15ff74632))
### BREAKING CHANGES
- **gulp-plugins:** Package-root `.js` files (typically `index.js`) are now (typically) cjs wrappers. These files needn't be transpiled, and in fact, doing so will create an invalid module because it will attempt to reference `build/whatever` but the resulting artifact would live in `build/index.js`. `build/index.js` will no longer exist.
## [5.5.5](https://github.com/appium/appium/compare/@appium/gulp-plugins@5.5.4...@appium/gulp-plugins@5.5.5) (2021-11-15)
### Bug Fixes
- **gulp-plugins:** fix potential race condition re: gulpfile.js ([0ef53d4](https://github.com/appium/appium/commit/0ef53d4e9907cdb6d66364890073c3ba8b900bc1))
## [5.5.4](https://github.com/appium/appium/compare/@appium/gulp-plugins@5.5.3...@appium/gulp-plugins@5.5.4) (2021-11-09)
**Note:** Version bump only for package @appium/gulp-plugins
## [5.5.3](https://github.com/appium/appium/compare/@appium/gulp-plugins@5.5.2...@appium/gulp-plugins@5.5.3) (2021-09-14)
**Note:** Version bump only for package @appium/gulp-plugins
## [5.5.2](https://github.com/appium/appium/compare/@appium/gulp-plugins@5.5.1...@appium/gulp-plugins@5.5.2) (2021-09-14)
**Note:** Version bump only for package @appium/gulp-plugins
## [5.5.1](https://github.com/appium/appium/compare/@appium/gulp-plugins@5.5.1-rc.0...@appium/gulp-plugins@5.5.1) (2021-08-16)
# 2.0.0-beta (2021-08-13)
**Note:** Version bump only for package @appium/gulp-plugins
-199
View File
@@ -1,199 +0,0 @@
appium-gulp-plugins
===================
Custom plugins used across appium modules
## status
[![Build Status](https://travis-ci.org/appium/appium-gulp-plugins.svg?branch=master)](https://travis-ci.org/appium/appium-gulp-plugins)
## boilerplate plugin
This plugin sets up all the other typical plugins we use with a simple
configuration object.
### usage
Basically just set up the `boilerplate` plugin as follows:
```js
let gulp = require('gulp'),
boilerplate = require('@appium/gulp-plugins').boilerplate.use(gulp);
boilerplate({build: "My Project Name"});
```
You can pass a lot of options to configure `boilerplate`. Here are the options
along with their defaults (from `lib/boilerplate.js`):
```js
const DEFAULT_OPTS = {
files: ['*.js', 'lib/**/*.js', 'test/**/*.js', '!gulpfile.js'],
transpile: true,
transpileOut: 'build',
babelOpts: {},
linkBabelRuntime: true,
watch: true,
watchE2E: false,
test: {
files: ['${testDir}/**/*-specs.js', '!${testDir}/**/*-e2e-specs.js'],
traceWarnings: false,
},
coverage: {
files: ['./build/test/**/*-specs.js', '!./build/test/**/*-e2e-specs.js'],
verbose: true,
},
'coverage-e2e': {
files: ['./build/test/**/*-e2e-specs.js'],
verbose: true,
},
e2eTest: {
files: ['${testDir}/**/*-e2e-specs.js'],
forceExit: false,
traceWarnings: false,
},
testReporter: (process.env.TRAVIS || process.env.CI) ? 'spec' : 'nyan',
testTimeout: 20000,
build: 'Appium',
extraPrepublishTasks: [],
eslint: true,
eslintOnWatch: false, // deprecated, move to lintOnWatch
lintOnWatch: false,
ci: {
interval: 60000,
owner: 'appium',
repo: 'appium-build-store',
},
};
```
As you can see, it defaults to transpiling with Babel, running `eslint`
running tests, and with the default task being `gulp watch`.
## transpile plugin
Babel compilation, sourcemaps and file renaming functionality in
one plugin. `.es7.js` and `.es6.js` files will be automatically renamed to `.js
files`. The necessary sourcemaps, comments and imports are also
automatically added.
### usage
1/ Configure gulp as below:
``` js
let gulp = require('gulp'),
Transpiler = require('appium-gulp-plugins').Transpiler;
gulp.task('transpile', function () {
let transpiler = new Transpiler();
// babel options are configurable in transpiler.babelOpts
return gulp.src('test/fixtures/es7/**/*.js')
.pipe(transpiler.stream())
.pipe(gulp.dest('build'));
});
```
2/ in your code you need to mark the main and mocha files as below:
- main: add `// transpile:main` at the beginning of the file ([example here](https://github.com/appium/appium-gulp-plugins/blob/master/test/fixtures/es7/lib/run.es7.js)) .
- mocha: add `// transpile:mocha` at the beginning of the file ([example here](https://github.com/appium/appium-gulp-plugins/blob/master/test/fixtures/es7/test/a-specs.es7.js))
Regular lib files do not need any extra comments.
## watch plugin
There are some issues with Gulp 3.x error handling which cause the default
gulp-watch to hang. This plugin is a small hack which solves that by respawning
the whole process on error. This should not be needed in gulp 4.0.
Files in the `/test` directory that are named `.*-specs.js` are run. Tests which end in `.*-e2e-specs.js` are *not* run when watching. To run end-to-end tests, run `gulp e2e-test:run`.
### usage
```js
const gulp = require('gulp');
const spawnWatcher = require('./index').spawnWatcher.use(gulp, opts);
spawnWatcher.configure('watch', ['lib/**/*.js','test/**/*.js','!test/fixtures'], function () {
// this is the watch action
return runSequence('test');
});
```
The test function in `spawnWatcher.configure` should return a promise.
### error handling
The spawn needs to catch error as soon as they happen. To do so use the
`spawnWatcher.handleError` method, for instance:
```js
// add error handling where needed
gulp.task('transpile', function () {
return gulp.src('test/es7/**/*.js')
.pipe(transpile())
.on('error', spawnWatcher.handleError)
.pipe(gulp.dest('build'));
});
gulp.task('test', ['transpile'] , function () {
return gulp.src('build/test/a-specs.js')
.pipe(mocha())
.on('error', spawnWatcher.handleError);
});
```
### notification
Native notification is enabled by default. To disable it use the
`--no-notif` option.
### collate logging and tests
Set the environment variable `_FORCE_LOGS`
## iOS app building
This package can create `gulp` tasks for building and cleaning iOS apps. By
providing an `iosApps` property in the options sent to `boilerplate()` with the
following:
```js
iosApps: {
relativeLocations: {
iphoneos: 'relative/path/to/device/app.app',
iphonesimulator: 'relative/path/to/sim/app.app',
},
appName: 'AppName.app',
},
```
This will create a number of `gulp` tasks, centrally one named
`ios-apps:install`, which will go through the process of cleaning the build,
building, and putting the products into deterministic places.
The simulator app will be build in `build/Release-iphonesimulator/<appName>`,
and the real device app will be in `build/Release-iphoneos/<appName>`.
To build for real devices, set the environment variable `IOS_REAL_DEVICE` or
`REAL_DEVICE`. To specify an `xcconfig` file, set its location in the
`XCCONFIG_FILE` environment variable.
## hacking this package
###
Since this package is used to build and test all the Appium packages, it should
not _use_ any of those packages.
### watch
```
npm run watch
```
### test
```
npm test
```
-25
View File
@@ -1,25 +0,0 @@
'use strict';
const boilerplate = require('./index').boilerplate.use(require('gulp'));
require('./test/gulpfile-js');
boilerplate({
transpile: true,
files: ['index.js', 'lib/**/*.js', 'test/**/*.js', '!test/fixtures/**', '!test/generated/**'],
test: {
files: ['${testDir}/**/*-specs.js', '!${testDir}/fixtures', '!${testDir}/**/*-e2e-specs.js'],
},
coverage: {
files: [
'./build/test/**/*-specs.js',
'!./build/test/fixtures',
'!./build/test/**/*-e2e-specs.js',
'!./build/test/generated',
],
verbose: true,
},
build: 'Appium Gulp Plugins',
extraDefaultTasks: ['e2e-test', 'test-transpile-lots-of-files'],
testReporter: 'dot',
});
-4
View File
@@ -1,4 +0,0 @@
exports.Transpiler = require('./lib/transpiler');
exports.spawnWatcher = require('./lib/spawn-watcher');
exports.boilerplate = require('./lib/boilerplate');
exports.isVerbose = require('./lib/utils').isVerbose;
-132
View File
@@ -1,132 +0,0 @@
'use strict';
const _ = require('lodash');
const tasks = require('./tasks/');
const log = require('fancy-log');
if (process.env.TRAVIS || process.env.CI) {
process.env.REAL_DEVICE = 0;
}
const DEFAULT_OPTS = {
files: ['lib/**/*.js', 'test/**/*.js', '!gulpfile.js'],
transpile: true,
transpileOut: 'build',
babelOpts: {},
linkBabelRuntime: true,
watch: true,
watchE2E: false,
test: {
files: ['${testDir}/**/*-specs.js', '!${testDir}/**/*-e2e-specs.js'],
traceWarnings: false,
},
coverage: {
files: ['./build/test/**/*-specs.js', '!./build/test/**/*-e2e-specs.js'],
verbose: true,
},
'coverage-e2e': {
files: ['./build/test/**/*-e2e-specs.js'],
verbose: true,
},
e2eTest: {
files: ['${testDir}/**/*-e2e-specs.js'],
forceExit: false,
traceWarnings: false,
},
testReporter: 'spec',
testTimeout: 20000,
build: 'Appium',
extraPrepublishTasks: [],
eslint: true,
eslintOnWatch: false, // deprecated, move to lintOnWatch
lintOnWatch: false,
ci: {
interval: 60000,
owner: 'appium',
repo: 'appium-build-store',
},
yamllint: true,
yaml: {
files: [
'**/.*.yml',
'**/*.yml',
'**/.*.yaml',
'**/*.yaml',
'!test/**',
'!node_modules/**',
'!**/node_modules/**',
],
safe: false,
},
};
const boilerplate = function (gulp, opts) {
opts = _.merge({}, DEFAULT_OPTS, opts);
if (!_.isEmpty(opts.buildName)) {
log.warn(`The 'buildName' option is deprecated. Use 'build' instead`);
opts.build = opts.buildName = opts.build || opts.buildName;
}
const spawnWatcher = require('./spawn-watcher').use(gulp, opts);
const rootDir = opts.transpile ? opts.transpileOut : '.';
const fileAliases = {
rootDir,
testDir: `${rootDir}/test`,
libDir: `${rootDir}/lib`,
};
// configure the individual tasks
tasks.configure(gulp, opts, {
fileAliases,
spawnWatcher,
});
// conpute and define the default sequence of tasks
let defaultSequence = [];
if (opts.transpile) {
defaultSequence.push('clean');
}
if (opts.eslint || opts.lint) {
defaultSequence.push('lint');
}
if (opts.transpile && !opts.test) {
defaultSequence.push('transpile');
}
if (opts.test) {
if (opts.watchE2E) {
defaultSequence.push('test');
} else {
defaultSequence.push('unit-test');
}
}
if (opts.extraDefaultTasks) {
defaultSequence.push(...opts.extraDefaultTasks);
}
if (opts.watch) {
if (opts.eslintOnWatch) {
log.warn(`The 'eslintOnWatch' option is deprecated. Use 'lintOnWatch' instead`);
opts.lintOnWatch = true;
}
const watchSequence = opts.lintOnWatch
? defaultSequence
: defaultSequence.filter(function filterLintTasks(step) {
return step !== 'lint';
});
spawnWatcher.configure('watch', opts.files, watchSequence);
}
spawnWatcher.configure('dev', opts.files, ['transpile']);
gulp.task('once', gulp.series(...defaultSequence));
gulp.task('default', gulp.series(opts.watch ? 'watch' : 'once'));
};
module.exports = {
DEFAULTS: _.cloneDeep(DEFAULT_OPTS),
use(gulp) {
return function callBoilerplate(opts) {
boilerplate(gulp, opts);
};
},
};
-26
View File
@@ -1,26 +0,0 @@
'use strict';
const path = require('path');
const sourcemaps = require('gulp-sourcemaps');
const replace = require('gulp-replace');
const {EOL} = require('os');
const SOURCEMAP_OPTS = {
sourceRoot(file) {
// Point to source root relative to the transpiled file
return path.relative(path.join(file.cwd, file.path), file.base);
},
includeContent: true,
};
const HEADER = `require('source-map-support').install();${EOL + EOL}`;
module.exports = function getSourceMapFns(opts = {}) {
const sourceMapOpts = Object.assign({}, SOURCEMAP_OPTS, opts);
return {
sourceMapInit: sourcemaps.init(),
sourceMapHeader: replace(/$/, HEADER),
sourceMapWrite: sourcemaps.write(sourceMapOpts),
};
};
@@ -1,79 +0,0 @@
'use strict';
const log = require('fancy-log');
const red = require('ansi-red');
const notifier = require('node-notifier');
const moment = require('moment');
const COLOR_CODE_REGEXP = /\u001b\[(\d+(;\d+)*)?m/g; // eslint-disable-line no-control-regex
module.exports = {
use(gulp, opts = {}) {
this.gulp = gulp;
this.title = opts.build || 'Appium';
this.exitOnError = true;
this.errored = false;
return this;
},
notify(subtitle, message) {
if (process.argv.includes('--no-notif')) {
return;
}
try {
notifier.notify({
title: this.title,
subtitle: `${subtitle} ${moment().format('h:mm:ss')}`,
message,
});
} catch (ign) {
log(`Notifier: [${this.title}] ${message}`);
}
},
notifyOK() {
this.notify('Build success!', 'All Good!');
},
handleError(err) {
this.errored = true;
// log the error
const strErr = `${err}`;
for (const line of strErr.split('\n')) {
log.error(red(line));
}
// use the system notifier
const notifyErr = strErr.replace(COLOR_CODE_REGEXP, '');
this.notify('Build failure!', notifyErr);
if (this.exitOnError) {
process.exit(1);
}
},
configure(taskName, filePattern, sequence) {
const notifyWatch = (done) => {
if (!this.errored) {
this.notifyOK();
}
this.errored = false;
done();
};
this.gulp.task(taskName, () => {
this.exitOnError = false;
return this.gulp.watch(
filePattern,
{
ignoreInitial: false,
ignored: '**/gulpfile.js',
},
this.gulp.series(sequence, notifyWatch)
);
});
},
};
@@ -1,18 +0,0 @@
'use strict';
const through = require('through2');
const EE = require('events').EventEmitter;
module.exports = function combine(pipeFn) {
const inStream = through.obj();
const outStream = pipeFn(inStream);
const combinedStream = new EE(); // not a real stream, just pretending
combinedStream.on('pipe', function onPipe(source) {
source.unpipe(this);
source.pipe(inStream);
});
combinedStream.pipe = function pipeFn(dest, options) {
return outStream.pipe(dest, options);
};
return combinedStream;
};
-215
View File
@@ -1,215 +0,0 @@
'use strict';
const fs = require('fs');
const path = require('path');
const log = require('fancy-log');
const {sync: findRoot} = require('pkg-dir');
const axios = require('axios');
const B = require('bluebird');
const os = require('os');
const {Octokit} = require('@octokit/rest');
const _ = require('lodash');
const FormData = require('form-data');
const readFile = B.promisify(fs.readFile, {context: fs});
const writeFile = B.promisify(fs.writeFile, {context: fs});
const ASSET_NAME_REGEXP = /^appium-\S+.zip$/;
const GITHUB_OWNER = 'appium';
const GITHUB_REPO = 'appium-build-store';
const OUTPUT_INTERVAL = 60000;
const MOCHA_PARALLEL_TEST_BROKEN_LINE = `if (value.type === 'test') {`;
const MOCHA_PARALLEL_TEST_FIXED_LINE = `if (value.type === 'test') {\n delete value.fn;`;
const configure = function configure(gulp, opts) {
const owner = opts.ci.owner || GITHUB_OWNER;
const repo = opts.ci.repo || GITHUB_REPO;
const root = opts.projectRoot ? opts.projectRoot : findRoot(__dirname);
/**
* `mocha-parallel-tests` is broken at the moment, so skipped describe blocks fail
* the fix is simple, and this patches the error until they fix the package
**/
gulp.task('fix-mocha-parallel-tests', async function fixMochaParallelTests() {
log(`Updating 'mocha-parallel-tests'`);
const filePath = path.resolve(
root,
'node_modules',
'mocha-parallel-tests',
'dist',
'main',
'util.js'
);
log(`File: '${filePath}'`);
try {
let script = await readFile(filePath, {encoding: 'utf8'});
script = await script.replace(
MOCHA_PARALLEL_TEST_BROKEN_LINE,
MOCHA_PARALLEL_TEST_FIXED_LINE
);
await writeFile(filePath, script);
} catch (err) {
const msg = err.message.includes('ENOENT')
? `File '${filePath}' does not exist`
: err.message;
log.error(`Unable to fix: ${msg}`);
}
});
gulp.task('github:upload', async function githubUpload() {
const githubToken = process.env.GITHUB_TOKEN;
if (_.isEmpty(githubToken)) {
log.warn('No GitHub token found in GITHUB_TOKEN environment variable');
return;
}
const octokit = new Octokit({auth: githubToken});
const buildName = process.env.BUILD_NAME || `${Date.now()}`;
const commitMessage = process.env.COMMIT_MESSAGE || 'No commit message provided';
const releaseTag = `appium-build-${buildName}`;
const releaseFile = `appium-${buildName}.zip`;
let releaseId;
try {
log(`Creating release on '${owner}/${repo}'`);
const res = await octokit.repos.createRelease({
owner,
repo,
tag_name: releaseTag,
name: `Appium build ${buildName}`,
body: `Appium build for commit ${buildName}\n'${commitMessage}'`,
});
releaseId = res.data.id;
log(`Created release '${releaseTag}' (id: ${releaseId})`);
const url = res.data.upload_url;
const file = path.resolve(root, 'appium.zip');
log(`Uploading file '${file}'`);
await octokit.repos.uploadReleaseAsset({
headers: {
'content-length': fs.statSync(file).size,
'content-type': 'application/zip',
},
url,
file: fs.createReadStream(file),
name: releaseFile,
});
log(`Uploaded release file '${releaseFile}'`);
} catch (err) {
log.error(`Error uploading release asset: ${err.message}`);
if (err.errors) {
log.error(JSON.stringify(err.errors, 2));
}
if (releaseId) {
log('Deleting release with no asset');
await octokit.repos.deleteRelease({
owner,
repo,
release_id: releaseId,
});
log('Release deleted');
}
throw new Error(`Error uploading release: ${err.message}`);
}
});
gulp.task('github-upload', gulp.series(['github:upload']));
gulp.task('github:download', async function githubDownload() {
const githubToken = process.env.GITHUB_TOKEN;
if (_.isEmpty(githubToken)) {
log.warn('No GitHub token found in GITHUB_TOKEN environment variable');
return;
}
const octokit = new Octokit({auth: githubToken});
log.info('Downloading GitHub asset');
const tempDir = os.tmpdir();
log.info(`Temporary directory for download: '${tempDir}'`);
log.info(`Downloading repository: '${owner}/${repo}'`);
const res = await octokit.repos.getLatestRelease({owner, repo});
// go through the assets and find the correct one
for (const asset of res.data.assets) {
if (ASSET_NAME_REGEXP.test(asset.name)) {
log.info(`Downloading asset from '${asset.browser_download_url}'`);
const url = asset.browser_download_url;
const writer = fs.createWriteStream(`${tempDir}/appium.zip`);
const responseStream = (
await axios({
url,
responseType: 'stream',
})
).data;
responseStream.pipe(writer);
return await new B((resolve, reject) => {
responseStream.once('error', reject);
writer.once('finish', resolve);
writer.once('error', (e) => {
responseStream.unpipe(writer);
reject(e);
});
});
}
}
throw new Error(`Unable to find Appium build asset`);
});
gulp.task('saucelabs:upload', async function sauceLabsUpload() {
// Find the latest bundle
log.info('Uploading to Sauce Storage');
const tempDir = os.tmpdir();
log.info(`Temporary directory for upload: '${tempDir}'`);
const form = new FormData();
form.append('file', fs.createReadStream(`${tempDir}/appium.zip`));
const options = {
method: 'POST',
url: `https://saucelabs.com/rest/v1/storage/${process.env.SAUCE_USERNAME}/appium.zip?overwrite=true`,
headers: form.getHeaders(),
auth: {
username: process.env.SAUCE_USERNAME,
password: process.env.SAUCE_ACCESS_KEY,
},
data: form,
};
const body = (await axios(options)).data;
// username should not end up in the logs
body.username = '*'.repeat((body.username || '').length);
log.info(`File uploaded: ${JSON.stringify(body)}`);
});
gulp.task('sauce-storage-upload', gulp.series(['github:download', 'saucelabs:upload']));
/**
* This task is meant to be backgrounded, and killed using OS tools, so it
* never finishes.
* $ $(npm bin)/gulp periodic-output &
* [1] 38060
* [08:56:53] Using gulpfile ~/code/appium-xcuitest-driver/gulpfile.js
* [08:56:53] Starting 'periodic-output'...
* $ kill 38060
* [1] + 38060 terminated $(npm bin)/gulp periodic-output
*/
gulp.task('periodic-output', function periodicOutput() {
const interval = opts.ci.interval || OUTPUT_INTERVAL;
return new B(function writeToStdout() {
setInterval(function print() {
process.stdout.write('.');
}, interval);
});
});
};
module.exports = {
configure,
};
-28
View File
@@ -1,28 +0,0 @@
'use strict';
const B = require('bluebird');
const vinylPaths = require('vinyl-paths');
const del = require('del');
const debug = require('gulp-debug');
const gulpIf = require('gulp-if');
const {isVerbose} = require('../utils');
const configure = function configure(gulp, opts) {
gulp.task('clean', function clean() {
if (opts.transpile) {
return gulp
.src(opts.transpileOut, {
read: false,
allowEmpty: true,
})
.pipe(gulpIf(isVerbose(), debug()))
.pipe(vinylPaths(del));
} else {
return B.resolve();
}
});
};
module.exports = {
configure,
};
@@ -1,91 +0,0 @@
'use strict';
const B = require('bluebird');
const globby = require('globby');
const _ = require('lodash');
const cp = require('child_process');
const spawn = cp.spawn;
const exec = B.promisify(cp.exec);
const path = require('path');
const utils = require('../utils');
const log = require('fancy-log');
const configure = function configure(gulp, opts, env) {
let npmBin;
gulp.task('npm-bin', async function getNpmBin() {
if (npmBin) {
return B.resolve();
}
let bin = await exec('npm bin');
if (Array.isArray(bin)) {
bin = bin[0];
}
npmBin = bin.trim(); // eslint-disable-line require-atomic-updates
log(`Determined npm bin: ${npmBin}`);
});
const doCoverage = function doCoverage(taskName, filePatterns, targetDir) {
const subTaskName = `${taskName}:run`;
const covTestFiles = utils.translatePaths([filePatterns], env.fileAliases);
gulp.task(subTaskName, async function doSubTask() {
const files = await globby(covTestFiles);
const bins = ['nyc', '_mocha'].reduce(function getFullPaths(bins, item) {
bins[item] = path.resolve(npmBin, item);
return bins;
}, {});
const args = [
'--reporter=lcov',
'--reporter=text-lcov', // Coveralls consumes lcov and text-lcov reports
'--reporter=cobertura', // MS Azure consumes Cobertura coverage reports
`--report-dir=${targetDir}`,
'--exclude-after-remap=false',
bins._mocha,
'--reporter=dot',
...files,
'--exit',
];
let env = _.clone(process.env);
env.NO_PRECOMPILE = 1;
env._TESTING = 1;
env.NODE_ENV = 'coverage';
log(`Running command: ${bins.nyc} ${args.join(' ')}`);
return new B(function runCmd(resolve, reject) {
const proc = spawn(bins.nyc, args, {
env,
stdio: opts.coverage.verbose ? 'inherit' : 'ignore',
});
proc.on('close', function onClose(code) {
if (code === 0) {
resolve();
} else {
reject(new Error(`Coverage command exit code: ${code}`));
}
});
proc.on('error', function onError(err) {
reject(new Error(`Coverage error: ${err}`));
});
});
});
gulp.task(taskName, gulp.series('clean', 'transpile', 'npm-bin', subTaskName));
};
if (opts.coverage) {
doCoverage('coverage', opts.coverage.files, 'coverage');
['coveralls:run', 'coveralls'].map((taskName) =>
gulp.task(taskName, function reportDeprecatedCoveralls() {
log(
`Coveralls integration has been removed as per ` +
`https://github.com/appium/appium/issues/14648. ` +
`Nothing will be done in scope of '${taskName}' task`
);
})
);
}
if (opts['coverage-e2e']) {
doCoverage('coverage-e2e', opts['coverage-e2e'].files, 'coverage-e2e');
}
};
module.exports = {
configure,
};
@@ -1,66 +0,0 @@
'use strict';
const mocha = require('gulp-mocha');
const B = require('bluebird');
const globby = require('globby');
const debug = require('gulp-debug');
const gulpIf = require('gulp-if');
const log = require('fancy-log');
const utils = require('../utils');
const {isVerbose} = utils;
const configure = function configure(gulp, opts, env) {
const e2eTestFiles = utils.translatePaths(
[opts.e2eTest.files || opts.e2eTestFiles],
env.fileAliases
);
gulp.task('e2e-test:run', async function e2eTestRun() {
const mochaOpts = {
reporter: utils.getTestReporter(opts),
timeout: opts.testTimeout,
require: opts.testRequire || [],
exit: true,
color: true,
traceWarnings: opts.e2eTest.traceWarnings,
traceDeprecation: opts.e2eTest.traceWarnings,
};
// set env so our code knows when it's being run in a test env
process.env._TESTING = 1;
const mochaCmd = function () {
return new B(function runCmd(resolve, reject) {
gulp
.src(e2eTestFiles, {read: true, allowEmpty: true})
.pipe(gulpIf(isVerbose(), debug()))
.pipe(mocha(mochaOpts))
.on('error', function onError(err) {
reject(err);
})
.once('_result', function onResult(...args) {
resolve(...args);
});
});
};
try {
const files = await globby(e2eTestFiles);
// gulp-mocha has an issue where, if there are no files passed from gulp.src,
// it will just run everything it finds
if (!files.length) {
log(`No e2e test files found using '${e2eTestFiles}'`);
return;
}
await mochaCmd();
} finally {
if (opts.e2eTest.forceExit) {
process.exit(0);
}
}
});
gulp.task('e2e-test', gulp.series(env.testDeps, 'e2e-test:run'));
};
module.exports = {
configure,
};
-65
View File
@@ -1,65 +0,0 @@
'use strict';
const argv = require('yargs').argv;
const replace = require('replace-in-file');
const log = require('fancy-log');
const semver = require('semver');
const globby = require('globby');
function logFileChanges(changes = []) {
// `changes` will have entries like
// { file: "app/build.gradle", hasChanged: true }
changes = changes.filter((entry) => entry.hasChanged).map((entry) => entry.file);
log(`Updated files: ${changes.join(', ')}`);
}
const configure = function configure(gulp) {
gulp.task('gradle-version-update', async function gradleVersionUpdate() {
const files = await globby(['app/build.gradle']);
if (!files.length) {
throw new Error('No app/build.gradle file found');
}
const gradleFile = files[0];
const version = argv['package-version'];
if (!version) {
throw new Error('No package version argument (use `--package-version=xxx`)');
}
if (!semver.valid(version)) {
throw new Error(
`Invalid version specified '${version}'. Version should be in the form '1.2.3'`
);
}
let changedFiles = await replace({
files: gradleFile,
from: /^\s*versionName\s+['"](.+)['"]$/gm,
to: (match) => {
log(`Updating gradle build file to version name '${version}'`);
// match will be like `versionName '1.2.3'`
return match.replace(/\d+\.\d+\.\d+/, version);
},
});
logFileChanges(changedFiles);
changedFiles = await replace({
files: gradleFile,
from: /^\s*versionCode\s+(.+)$/gm,
to: (match) => {
// match will be like `versionCode 42`
const codeMatch = /\d+/.exec(match.trim());
if (!codeMatch) {
throw new Error('Unable to find existing version code');
}
const code = parseInt(codeMatch[0], 10) + 1;
log(`Updating gradle build file to version code '${code}'`);
return match.replace(/\d+/, code);
},
});
logFileChanges(changedFiles);
});
};
module.exports = {
configure,
};
-48
View File
@@ -1,48 +0,0 @@
'use strict';
const coverage = require('./coverage');
const lint = require('./lint');
const test = require('./test');
const e2eTest = require('./e2e-test');
const unitTest = require('./unit-test');
const clean = require('./clean');
const transpile = require('./transpile');
const gradle = require('./gradle');
const ci = require('./ci');
const iosApps = require('./ios-apps');
const prepublish = require('./prepublish');
const configure = function configure(gulp, opts, env) {
clean.configure(gulp, opts);
transpile.configure(gulp, opts, env);
test.configure(gulp, opts, env);
coverage.configure(gulp, opts, env);
lint.configure(gulp, opts);
gradle.configure(gulp, opts);
ci.configure(gulp, opts);
iosApps.configure(gulp, opts);
// make sure this is last, os that all the tasks are available as extra
// prepublish tasks with the `extraPrepublishTasks` option
prepublish.configure(gulp, opts);
};
module.exports = {
configure,
coverage,
lint,
e2eTest,
unitTest,
clean,
transpile,
gradle,
ci,
prepublish,
};
-162
View File
@@ -1,162 +0,0 @@
'use strict';
const path = require('path');
const log = require('fancy-log');
const _ = require('lodash');
const {exec} = require('../utils');
const B = require('bluebird');
const fs = require('fs');
const rimraf = B.promisify(require('rimraf'));
const renameFile = B.promisify(fs.rename, {context: fs});
const MAX_BUFFER_SIZE = 524288;
const REAL_DEVICE_FLAGS = ['IOS_REAL_DEVICE', 'REAL_DEVICE'];
function configure(gulp, opts) {
if (_.isEmpty(opts.iosApps)) {
// nothing to do
return;
}
// extract the paths from the enclosing package configuration
const relativeLocations = opts.iosApps.relativeLocations;
// figure out where things will go in the end
const SDKS = {
iphonesimulator: {
name: 'iphonesimulator',
buildPath: path.resolve('build', 'Release-iphonesimulator', opts.iosApps.appName),
finalPath: relativeLocations.iphonesimulator,
},
iphoneos: {
name: 'iphoneos',
buildPath: path.resolve('build', 'Release-iphoneos', opts.iosApps.appName),
finalPath: relativeLocations.iphoneos,
},
};
// the sdks against which we will build
let sdks = ['iphonesimulator'];
let sdkVer;
async function getIOSSDK() {
if (!sdkVer) {
try {
const {stdout} = await exec('xcrun', ['--sdk', 'iphonesimulator', '--show-sdk-version']);
sdkVer = stdout.trim(); // eslint-disable-line require-atomic-updates
} catch (err) {
log(`Unable to get max iOS SDK: ${err.message}`);
throw err;
}
}
return sdkVer;
}
function logErrorLines(str = '') {
str = `${str}`;
for (const line of str.split('\n')) {
log.error(` ${line}`);
}
}
function logError(err, prefix = 'Failed:') {
log.error(`${prefix}: ${err.message}`);
log.error('Stdout:');
logErrorLines(err.stdout);
log.error('Stderr:');
logErrorLines(err.stderr);
}
async function cleanApp(appRoot, sdk) {
log(`Cleaning app for ${sdk} at app root '${appRoot}'`);
try {
const cmd = 'xcodebuild';
const args = ['-sdk', sdk, 'clean'];
log(` Executing command '${cmd} ${args.join(' ')}'`);
await exec(cmd, args, {cwd: appRoot, maxBuffer: MAX_BUFFER_SIZE});
} catch (err) {
logError(err, 'Failed cleaning app');
throw err;
}
}
gulp.task('ios-apps:sdks', function findSDKs(done) {
// determine if the real device sdk should be used, too
for (const flag of REAL_DEVICE_FLAGS) {
const value = process.env[flag];
if (!_.isEmpty(value) && !!parseInt(value, 10)) {
log(
`Enabling real device build because '${flag}' environment variable set (value is '${value}')`
);
sdks.push('iphoneos');
}
}
log(`SDKs to process: ${sdks.map((sdk) => `'${sdk}'`).join(', ')}`);
done();
});
gulp.task('ios-apps:clean', async function cleanAll() {
log('Cleaning all sdks');
const sdkVer = await getIOSSDK();
for (const sdk of sdks) {
await cleanApp('.', sdk + sdkVer);
}
log('Deleting all apps');
const apps = [
SDKS.iphonesimulator.buildPath,
SDKS.iphonesimulator.finalPath,
SDKS.iphoneos.buildPath,
SDKS.iphoneos.finalPath,
];
for (const app of apps) {
log(` Deleting app '${app}'`);
await rimraf(app);
}
});
async function buildApp(appRoot, sdk) {
log(`Building app for ${sdk} at app root '${appRoot}'`);
try {
const cmd = 'xcodebuild';
let args = ['-sdk', sdk];
if (process.env.XCCONFIG_FILE) {
args.push('-xcconfig', process.env.XCCONFIG_FILE);
}
log(` Executing command '${cmd} ${args.join(' ')}'`);
await exec(cmd, args, {cwd: appRoot, maxBuffer: MAX_BUFFER_SIZE});
} catch (err) {
logError(err, 'Failed building app');
throw err;
}
}
gulp.task('ios-apps:build', async function buildAll() {
log('Building all apps');
const sdkVer = await getIOSSDK();
for (const sdk of sdks) {
await buildApp('.', sdk + sdkVer);
}
});
gulp.task('ios-apps:rename', async function iosAppsRename() {
log('Renaming apps');
for (const sdk of sdks) {
log(` Renaming for ${sdk}`);
log(` '${SDKS[sdk].buildPath}' => '${SDKS[sdk].finalPath}'`);
await renameFile(SDKS[sdk].buildPath, SDKS[sdk].finalPath);
}
});
gulp.task(
'ios-apps:install',
gulp.series('ios-apps:sdks', 'ios-apps:clean', 'ios-apps:build', 'ios-apps:rename')
);
}
module.exports = {
configure,
};
-54
View File
@@ -1,54 +0,0 @@
'use strict';
const eslint = require('gulp-eslint');
const debug = require('gulp-debug');
const gulpIf = require('gulp-if');
const {isVerbose} = require('../utils');
const yamlLint = require('../yaml-lint');
const configure = function configure(gulp, opts) {
const verbose = isVerbose();
gulp.task('eslint', function eslintTask() {
let opts = {
fix: process.argv.includes('--fix'),
};
if (process.argv.includes('--lax-lint') || process.argv.includes('-ll')) {
// when running tests, we want to be able to use exclusive tests
// and console logging
opts.rules = {
'no-console': 0,
'mocha/no-exclusive-tests': 0,
};
}
return gulp
.src(['**/*.js', '!node_modules/**', '!**/node_modules/**', '!build/**', '!**/*.min.js'])
.pipe(gulpIf(verbose, debug()))
.pipe(eslint(opts))
.pipe(eslint.format())
.pipe(eslint.failAfterError())
.pipe(gulpIf((file) => file.eslint && file.eslint.fixed, gulp.dest(process.cwd())));
});
gulp.task('yamllint', function yamllintTask() {
const yamlOpts = {
safe: !!opts.yaml.safe,
};
return gulp.src(opts.yaml.files).pipe(gulpIf(verbose, debug())).pipe(yamlLint(yamlOpts));
});
const lintTasks = [];
if (opts.eslint) {
lintTasks.push('eslint');
}
if (opts.yamllint) {
lintTasks.push('yamllint');
}
if (lintTasks.length) {
gulp.task('lint', gulp.series(lintTasks));
}
};
module.exports = {
configure,
};
@@ -1,9 +0,0 @@
'use strict';
const configure = function configure(gulp, opts) {
gulp.task('prepublish', gulp.series('clean', 'transpile', opts.extraPrepublishTasks || []));
};
module.exports = {
configure,
};
-30
View File
@@ -1,30 +0,0 @@
'use strict';
const e2eTest = require('./e2e-test');
const unitTest = require('./unit-test');
const configure = function configure(gulp, opts, env) {
const testEnv = {
testDeps: opts.transpile ? ['transpile'] : [],
...env,
};
let testTasks = [];
if (opts.test) {
unitTest.configure(gulp, opts, testEnv);
testTasks.push('unit-test');
}
if (opts.e2eTest) {
e2eTest.configure(gulp, opts, testEnv);
testTasks.push('e2e-test');
}
if (testTasks.length) {
gulp.task('test', gulp.series(testTasks));
}
};
module.exports = {
configure,
};
@@ -1,39 +0,0 @@
'use strict';
const Transpiler = require('../../index').Transpiler;
const debug = require('gulp-debug');
const gulpIf = require('gulp-if');
const merge = require('merge-stream');
const {isVerbose} = require('../utils');
const JSON_SOURCES = ['lib/**/*.json', 'test/**/*.json'];
/**
* @param {import('gulp').Gulp} gulp - The gulp instance.
*/
const configure = function configure(gulp, opts, env) {
const tasks = [
function transpileSources() {
// json files can be copied as is, they don't need to be transpiled
const firstPath = gulp.src(JSON_SOURCES, {base: './'}).pipe(gulp.dest(opts.transpileOut));
const secondPath = gulp
.src(opts.files, {base: './'})
.pipe(gulpIf(isVerbose(), debug()))
.pipe(new Transpiler(opts).stream())
.on('error', env.spawnWatcher.handleError.bind(env.spawnWatcher))
.pipe(gulp.dest(opts.transpileOut));
return merge(firstPath, secondPath);
},
];
if (opts.postTranspile && opts.postTranspile.length) {
gulp.task('post-transpile', gulp.parallel(opts.postTranspile));
tasks.push('post-transpile');
}
gulp.task('transpile', gulp.series(tasks));
};
module.exports = {
configure,
};
@@ -1,32 +0,0 @@
'use strict';
const mocha = require('gulp-mocha');
const debug = require('gulp-debug');
const gulpIf = require('gulp-if');
const utils = require('../utils');
const configure = function configure(gulp, opts, env) {
const testFiles = utils.translatePaths([opts.test.files || opts.testFiles], env.fileAliases);
gulp.task('unit-test:run', function unitTestRun() {
const mochaOpts = {
reporter: utils.getTestReporter(opts),
timeout: opts.testTimeout,
traceWarnings: opts.test.traceWarnings,
traceDeprecation: opts.test.traceWarnings,
color: true,
exit: Boolean(opts.test.exit),
};
// set env so our code knows when it's being run in a test env
process.env._TESTING = 1;
return gulp
.src(testFiles, {read: false})
.pipe(gulpIf(utils.isVerbose(), debug()))
.pipe(mocha(mochaOpts))
.once('error', env.spawnWatcher.handleError.bind(env.spawnWatcher));
});
gulp.task('unit-test', gulp.series(env.testDeps, 'unit-test:run'));
};
module.exports = {
configure,
};
-32
View File
@@ -1,32 +0,0 @@
'use strict';
const babel = require('gulp-babel');
const rename = require('gulp-rename');
const streamCombiner = require('./stream-combiner');
const path = require('path');
const sourcemaps = require('./sourcemaps');
const BABEL_OPTS = {
configFile: path.resolve(__dirname, '..', '.babelrc'),
};
const renameEsX = function () {
return rename(function renameEs(path) {
path.basename = path.basename.replace(/\.es[67]$/, '');
});
};
module.exports = function transpiler(opts = {}) {
const {sourceMapInit, sourceMapHeader, sourceMapWrite} = sourcemaps(opts.sourceMapOpts);
this.stream = function stream() {
return streamCombiner(function combine(source) {
return source
.pipe(sourceMapInit)
.pipe(babel(Object.assign({}, BABEL_OPTS, opts.babelOpts)))
.pipe(sourceMapHeader)
.pipe(renameEsX())
.pipe(sourceMapWrite);
});
};
};
-56
View File
@@ -1,56 +0,0 @@
'use strict';
const _ = require('lodash');
const {exec} = require('child_process');
const B = require('bluebird');
const {quote} = require('shell-quote');
// string interpolation
const interpolate = function interpolate(s, opts) {
return _.keys(opts).reduce(function replace(s, k) {
return s.replace(new RegExp(`\\$\\{\\s*${k}\\s*\\}`, 'g'), opts[k]);
}, s);
};
const translatePaths = function translatePaths(files, fileAliases) {
if (!_.isArray(files)) {
files = [files];
}
return _.flatten(files).map(function interpolateFileAliases(f) {
return interpolate(f, fileAliases);
});
};
const isVerbose = function isVerbose() {
return process.env.VERBOSE === '1';
};
const getTestReporter = function getTestReporter(opts) {
const isForceLogMode = parseInt(process.env._FORCE_LOGS, 10) === 1;
return isForceLogMode ? 'spec' : process.env.REPORTER ? process.env.REPORTER : opts.testReporter;
};
const pExec = function pExec(cmd, args = [], opts = {}) {
return new B(function executeCmd(resolve, reject) {
exec(`${quote([cmd])} ${quote(args)}`, opts, function cb(err, stdout, stderr) {
// eslint-disable-line promise/prefer-await-to-callbacks
if (err) {
err.stdout = stdout;
err.stderr = stderr;
return reject(err);
}
resolve({
stdout,
stderr,
});
});
});
};
module.exports = {
interpolate,
translatePaths,
isVerbose,
getTestReporter,
exec: pExec,
};
-41
View File
@@ -1,41 +0,0 @@
/* eslint-disable promise/prefer-await-to-callbacks */
const {Transform} = require('stream');
const log = require('fancy-log');
const yaml = require('js-yaml');
const {EOL} = require('os');
const PluginError = require('plugin-error');
const red = require('ansi-red');
function gulpYamlLint() {
let errCount = 0;
return new Transform({
objectMode: true,
transform(file, enc, cb) {
try {
yaml.load(file.contents.toString(enc));
} catch (err) {
errCount++;
log.error(`Invalid YAML file: '${file.path}'`);
for (const line of err.message.split(EOL)) {
log.error(line);
}
}
cb();
},
flush(done) {
if (errCount > 0) {
log.error(`YAML errors found. Due to the limitations of YAML linting, the error `);
log.error(`is most likely in the line immediately ${red('before')} the line reported.`);
return done(
new PluginError('gulp-yaml-lint', {
name: 'YAMLError',
message: `Failed with ${errCount} ${errCount === 1 ? 'error' : 'errors'}`,
})
);
}
done();
},
});
}
module.exports = gulpYamlLint;
-111
View File
@@ -1,111 +0,0 @@
{
"name": "@appium/gulp-plugins",
"version": "8.0.0",
"description": "Custom gulp plugins to be used across all appium modules",
"keywords": [
"automation",
"javascript",
"selenium",
"webdriver",
"ios",
"android",
"firefoxos",
"testing"
],
"homepage": "https://appium.io",
"bugs": {
"url": "https://github.com/appium/appium/issues"
},
"repository": {
"type": "git",
"url": "https://github.com/appium/appium.git",
"directory": "packages/gulp-plugins"
},
"license": "Apache-2.0",
"author": "https://github.com/appium",
"directories": {
"lib": "lib",
"test": "test",
"build": "build"
},
"files": [
".babelrc",
"index.js",
"lib",
"build"
],
"scripts": {
"build": "gulp transpile",
"clean": "npx rimraf build",
"dev": "gulp dev --no-notif",
"prepare": "npm run build",
"test": "gulp unit-test:run",
"test:e2e": "gulp e2e-test:run",
"test:smoke": "node ./index.js"
},
"dependencies": {
"@appium/eslint-config-appium": "^8.0.0",
"@babel/core": "7.20.5",
"@babel/eslint-parser": "7.19.1",
"@babel/preset-env": "7.20.2",
"@octokit/rest": "19.0.5",
"@types/fancy-log": "2.0.0",
"@types/gulp": "4.0.10",
"@types/semver": "7.3.13",
"@types/through2": "2.0.38",
"ansi-red": "0.1.1",
"axios": "1.2.1",
"babel-plugin-istanbul": "6.1.1",
"babel-plugin-source-map-support": "2.2.0",
"bluebird": "3.7.2",
"del": "6.1.1",
"eslint": "8.29.0",
"eslint-config-prettier": "8.5.0",
"eslint-plugin-import": "2.26.0",
"eslint-plugin-mocha": "10.1.0",
"eslint-plugin-promise": "6.1.1",
"fancy-log": "2.0.0",
"form-data": "4.0.0",
"glob": "8.0.3",
"globby": "11.1.0",
"gulp-babel": "8.0.0",
"gulp-debug": "4.0.0",
"gulp-eslint": "6.0.0",
"gulp-if": "3.0.0",
"gulp-mocha": "8.0.0",
"gulp-rename": "2.0.0",
"gulp-replace": "1.1.3",
"gulp-sourcemaps": "3.0.0",
"js-yaml": "4.1.0",
"lodash": "4.17.21",
"merge-stream": "2.0.0",
"mocha": "10.2.0",
"moment": "2.29.4",
"node-notifier": "10.0.1",
"nyc": "15.1.0",
"pkg-dir": "5.0.0",
"plugin-error": "2.0.1",
"replace-in-file": "6.3.5",
"rimraf": "3.0.2",
"semver": "7.3.8",
"shell-quote": "1.7.4",
"source-map-support": "0.5.21",
"through2": "4.0.2",
"vinyl-paths": "3.0.1",
"yargs": "17.6.2"
},
"devDependencies": {
"@babel/register": "7.18.9"
},
"peerDependencies": {
"gulp": "^4.0.2"
},
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0",
"npm": ">=8"
},
"publishConfig": {
"access": "public"
},
"gitHead": "5c7af8ee73078018e4ec52fccf19fe3f77249d72"
}
@@ -1,9 +0,0 @@
/* eslint-disable import/no-unresolved */
/* eslint-disable no-console */
import { A } from './a';
// A expects a string, we pass an integer
let a = new A(123);
console.log(a.getText());
@@ -1,8 +0,0 @@
/* eslint-disable import/no-unresolved */
/* eslint-disable no-console */
import { A } from './a';
let a = new A('hello world!');
console.log(a.getText());
@@ -1,7 +0,0 @@
/* eslint-disable import/no-unresolved */
import { A } from './a';
let a = new A('hello world!');
a.throwError('This is really bad!');
-15
View File
@@ -1,15 +0,0 @@
class A {
constructor (text/*:string*/) {
this.text = text;
}
getText ()/*:string*/ {
return this.text;
}
throwError (mess) {
throw new Error(mess);
}
}
export { A };
@@ -1,11 +0,0 @@
/* eslint-disable import/no-unresolved */
import { A } from '../lib/a';
describe('a e2e', function () {
it('should be able to get text', function () {
let a = new A('hello world!');
a.getText().should.equal('hello world!');
});
});
@@ -1,11 +0,0 @@
/* eslint-disable import/no-unresolved */
import { A } from '../lib/a';
describe('a', function () {
it('should be able to get text', function () {
let a = new A('hello world!');
a.getText().should.equal('hello world!');
});
});
@@ -1,10 +0,0 @@
/* eslint-disable import/no-unresolved */
import { A } from '../lib/a';
describe('a-throw', function () {
it('should throw', function () {
let a = new A('hello world!');
a.throwError('This is really bad!');
});
});
@@ -1,15 +0,0 @@
class A {
constructor (text/*:string*/) {
this.text = text;
}
getText ()/*:string*/ {
return this.text;
}
throwError (mess) {
throw new Error(mess);
}
}
export { A };
@@ -1,15 +0,0 @@
class A {
constructor (text/*:string*/) {
this.text = text;
}
getText ()/*:string*/ {
return this.text;
}
throwError (mess) {
throw new Error(mess);
}
}
export { A };
@@ -1,15 +0,0 @@
class A {
constructor (text/*:string*/) {
this.text = text;
}
getText ()/*:string*/ {
return this.text;
}
throwError (mess) {
throw new Error(mess);
}
}
export { A };
@@ -1,15 +0,0 @@
class A {
constructor (text/*:string*/) {
this.text = text;
}
getText ()/*:string*/ {
return this.text;
}
throwError (mess) {
throw new Error(mess);
}
}
export { A };
@@ -1,15 +0,0 @@
class A {
constructor (text/*:string*/) {
this.text = text;
}
getText ()/*:string*/ {
return this.text;
}
throwError (mess) {
throw new Error(mess);
}
}
export { A };
@@ -1,15 +0,0 @@
class A {
constructor (text/*:string*/) {
this.text = text;
}
getText ()/*:string*/ {
return this.text;
}
throwError (mess) {
throw new Error(mess);
}
}
export { A };
@@ -1,15 +0,0 @@
class A {
constructor (text/*:string*/) {
this.text = text;
}
getText ()/*:string*/ {
return this.text;
}
throwError (mess) {
throw new Error(mess);
}
}
export { A };
@@ -1,15 +0,0 @@
class A {
constructor (text/*:string*/) {
this.text = text;
}
getText ()/*:string*/ {
return this.text;
}
throwError (mess) {
throw new Error(mess);
}
}
export { A };
@@ -1,15 +0,0 @@
class A {
constructor (text/*:string*/) {
this.text = text;
}
getText ()/*:string*/ {
return this.text;
}
throwError (mess) {
throw new Error(mess);
}
}
export { A };
@@ -1,15 +0,0 @@
class A {
constructor (text/*:string*/) {
this.text = text;
}
getText ()/*:string*/ {
return this.text;
}
throwError (mess) {
throw new Error(mess);
}
}
export { A };
@@ -1,15 +0,0 @@
class A {
constructor (text/*:string*/) {
this.text = text;
}
getText ()/*:string*/ {
return this.text;
}
throwError (mess) {
throw new Error(mess);
}
}
export { A };
@@ -1,15 +0,0 @@
class A {
constructor (text/*:string*/) {
this.text = text;
}
getText ()/*:string*/ {
return this.text;
}
throwError (mess) {
throw new Error(mess);
}
}
export { A };
@@ -1,15 +0,0 @@
class A {
constructor (text/*:string*/) {
this.text = text;
}
getText ()/*:string*/ {
return this.text;
}
throwError (mess) {
throw new Error(mess);
}
}
export { A };
@@ -1,15 +0,0 @@
class A {
constructor (text/*:string*/) {
this.text = text;
}
getText ()/*:string*/ {
return this.text;
}
throwError (mess) {
throw new Error(mess);
}
}
export { A };
@@ -1,15 +0,0 @@
class A {
constructor (text/*:string*/) {
this.text = text;
}
getText ()/*:string*/ {
return this.text;
}
throwError (mess) {
throw new Error(mess);
}
}
export { A };
@@ -1,15 +0,0 @@
class A {
constructor (text/*:string*/) {
this.text = text;
}
getText ()/*:string*/ {
return this.text;
}
throwError (mess) {
throw new Error(mess);
}
}
export { A };
@@ -1,15 +0,0 @@
class A {
constructor (text/*:string*/) {
this.text = text;
}
getText ()/*:string*/ {
return this.text;
}
throwError (mess) {
throw new Error(mess);
}
}
export { A };
@@ -1,15 +0,0 @@
class A {
constructor (text/*:string*/) {
this.text = text;
}
getText ()/*:string*/ {
return this.text;
}
throwError (mess) {
throw new Error(mess);
}
}
export { A };
@@ -1,15 +0,0 @@
class A {
constructor (text/*:string*/) {
this.text = text;
}
getText ()/*:string*/ {
return this.text;
}
throwError (mess) {
throw new Error(mess);
}
}
export { A };
@@ -1,15 +0,0 @@
class A {
constructor (text/*:string*/) {
this.text = text;
}
getText ()/*:string*/ {
return this.text;
}
throwError (mess) {
throw new Error(mess);
}
}
export { A };
@@ -1,15 +0,0 @@
class A {
constructor (text/*:string*/) {
this.text = text;
}
getText ()/*:string*/ {
return this.text;
}
throwError (mess) {
throw new Error(mess);
}
}
export { A };
@@ -1,15 +0,0 @@
class A {
constructor (text/*:string*/) {
this.text = text;
}
getText ()/*:string*/ {
return this.text;
}
throwError (mess) {
throw new Error(mess);
}
}
export { A };
@@ -1,15 +0,0 @@
class A {
constructor (text/*:string*/) {
this.text = text;
}
getText ()/*:string*/ {
return this.text;
}
throwError (mess) {
throw new Error(mess);
}
}
export { A };
@@ -1,15 +0,0 @@
class A {
constructor (text/*:string*/) {
this.text = text;
}
getText ()/*:string*/ {
return this.text;
}
throwError (mess) {
throw new Error(mess);
}
}
export { A };
@@ -1,56 +0,0 @@
'use strict';
const gulp = require('gulp');
const {Transpiler, spawnWatcher, isVerbose} = require('../..');
const _ = require('lodash');
const B = require('bluebird');
const {exec} = require('../../lib/utils');
const assert = require('assert');
const debug = require('gulp-debug');
const gulpIf = require('gulp-if');
const globby = require('globby');
const rimraf = B.promisify(require('rimraf'));
spawnWatcher.use(gulp);
gulp.task('generate-lots-of-files', async function () {
await rimraf('test/generated/es7 build/generated');
await exec('mkdir', ['-p', 'test/generated/es7']);
await B.all([
..._.times(24).map(function (i) {
return exec('cp', ['test/fixtures/es7/lib/a.es7.js', `test/generated/es7/a${i + 1}.es7.js`]);
}),
]);
});
gulp.task('transpile-lots-of-es7-files', function () {
const transpiler = new Transpiler();
return gulp
.src('test/generated/es7/**/*.js')
.pipe(gulpIf(isVerbose(), debug()))
.pipe(transpiler.stream())
.on('error', spawnWatcher.handleError)
.pipe(gulp.dest('build/generated'));
});
gulp.task(
'transpile-lots-of-files',
gulp.series('generate-lots-of-files', 'transpile-lots-of-es7-files')
);
gulp.task('test-transpile-lots-of-es7-files', async function testTranspileLotsOfFiles() {
let files = await globby('test/generated/es7/**/*.js');
const numOfFiles = files.length;
assert(numOfFiles > 16);
files = await globby('build/generated/a*.js');
assert(files.length === numOfFiles);
files = await globby('build/generated/*.es7.js');
assert(files.length === 0);
});
gulp.task(
'test-transpile-lots-of-files',
gulp.series('transpile-lots-of-files', 'test-transpile-lots-of-es7-files')
);
@@ -1,27 +0,0 @@
'use strict';
const gulp = require('gulp');
const {Transpiler, isVerbose, spawnWatcher} = require('../..');
const vinylPaths = require('vinyl-paths');
const del = require('del');
const debug = require('gulp-debug');
const gulpIf = require('gulp-if');
gulp.task('clean-fixtures', function () {
return gulp.src('build-fixtures', {read: false, allowEmpty: true}).pipe(vinylPaths(del));
});
gulp.task('transpile-es7-fixtures', function () {
let transpiler = new Transpiler();
return gulp
.src('test/fixtures/es7/**/*.js')
.pipe(gulpIf(isVerbose(), debug()))
.pipe(transpiler.stream())
.on('error', spawnWatcher.handleError)
.pipe(gulp.dest('build-fixtures'));
});
gulp.task('transpile-fixtures', gulp.series('clean-fixtures', 'transpile-es7-fixtures'));
require('./test-es7');
require('./generate');
@@ -1,30 +0,0 @@
'use strict';
const gulp = require('gulp');
const mocha = require('gulp-mocha');
const {isVerbose, spawnWatcher} = require('../..');
const debug = require('gulp-debug');
const gulpIf = require('gulp-if');
gulp.task('test-es7-mocha:run', function () {
return gulp
.src('build-fixtures/test/a-specs.js')
.pipe(gulpIf(isVerbose(), debug()))
.pipe(mocha())
.on('error', spawnWatcher.handleError);
});
gulp.task('test-es7-mocha', gulp.series('transpile-es7-fixtures', 'test-es7-mocha:run'));
gulp.task('test-es7-mocha-throw:run', function () {
return gulp
.src('build-fixtures/test/a-throw-specs.js')
.pipe(gulpIf(isVerbose(), debug()))
.pipe(mocha())
.on('error', spawnWatcher.handleError);
});
gulp.task(
'test-es7-mocha-throw',
gulp.series('transpile-es7-fixtures', 'test-es7-mocha-throw:run')
);
-32
View File
@@ -1,32 +0,0 @@
'use strict';
/**
* Mocha will load this file to configure the environment to use Chai as the
* assertion library. Since Chai is a singleton, we can run into problems when
* running files individually, if we have not carefully configured Chai in every
* single test file. This file means less boilerplate and less random test
* failures when running single test files.
*
* For simplicity, this file is _not_ transpiled. If it were, Mocha would need
* to load different versions of this file depending on the test context (are we
* running tests against the distfiles, or the source files?).
*
*/
// This configures @babel/register to look for a babel config in parent dir(s) of
// wherever the tests are run. This is required if running tests via `mocha` in a package dir
// instead of the monorepo root. This does not affect `gulp-mocha`, since it has its own `.babelrc`.
// This file is required _in addition to_ the monorepo root's `test/setup.js`.
require('@babel/register')();
const chai = require('chai');
const chaiAsPromised = require('chai-as-promised');
const sinonChai = require('sinon-chai');
// The `chai` global is set if a test needs something special.
// Most tests won't need this.
global.chai = chai.use(chaiAsPromised).use(sinonChai);
// `should()` is only necessary when working with some `null` or `undefined` values.
global.should = chai.should();
@@ -1,126 +0,0 @@
'use strict';
import B from 'bluebird';
import cp from 'child_process';
import fs from 'fs';
import _ from 'lodash';
import log from 'fancy-log';
// XXX: this behavior is unsupported by Node.js (but is supported by Babel).
// fix if dropping babel
const GULP = require.resolve('gulp/bin/gulp');
const MOCHA = require.resolve('mocha/bin/mocha');
const readFile = B.promisify(fs.readFile);
// we do not care about exec errors
async function exec(...args) {
return await new B(function (resolve) {
// eslint-disable-next-line promise/prefer-await-to-callbacks
cp.exec(args.join(' '), function (err, stdout, stderr) {
resolve([stdout, stderr]);
});
});
}
// some debug
function print(stdout, stderr) {
if (process.env.VERBOSE) {
if ((stdout || '').length) {
log(`stdout --> '${stdout}'`);
}
if ((stderr || '').length) {
log(`stderr --> '${stderr}'`);
}
}
}
describe('transpile-specs', function () {
this.timeout(60000);
this.retries(0);
const tests = {
es7: {
classFile: 'a',
throwFile: 'a-throw.es7.js:7',
throwTestFile: 'a-throw-specs.es7.js:8',
},
};
for (const [name, files] of _.toPairs(tests)) {
it(`should transpile ${name} fixtures`, async function () {
const [stdout, stderr] = await exec(`${GULP} transpile-${name}-fixtures`);
print(stdout, stderr);
stderr.should.eql('');
stdout.should.include('Finished');
const content = await readFile(`build-fixtures/lib/${files.classFile}.js`, 'utf8');
content.should.have.length.above(0);
content.should.include('sourceMapping');
});
describe('check transpiled', function () {
before(async function () {
await exec(`${GULP} transpile-fixtures`);
});
it(`should be able to run transpiled ${name} code`, async function () {
const [stdout, stderr] = await exec(`node build-fixtures/lib/${files.classFile}-run.js`);
print(stdout, stderr);
stderr.should.equal('');
stdout.should.include('hello world!');
});
it(`should be able to run transpiled ${name} tests`, async function () {
const [stdout, stderr] = await exec(
`${MOCHA} build-fixtures/test/${files.classFile}-specs.js`
);
print(stdout, stderr);
stderr.should.equal('');
stdout.should.include('1 passing');
});
it(`should use sourcemap when throwing (${name})`, async function () {
const [stdout, stderr] = await exec(`node build-fixtures/lib/${files.classFile}-throw.js`);
print(stdout, stderr);
let output = stdout + stderr;
output.should.include('This is really bad!');
output.should.include(files.throwFile);
});
it(`should use sourcemap when throwing within mocha (${name})`, async function () {
const [stdout, stderr] = await exec(
`${MOCHA} --no-color build-fixtures/test/${files.classFile}-throw-specs.js`
);
print(stdout, stderr);
let output = stdout + stderr;
output.should.include('This is really bad!');
output.should.include(files.throwTestFile);
});
it(`should be able to use gulp-mocha (${name})`, async function () {
const [stdout, stderr] = await exec(`${GULP} test-${name}-mocha`);
print(stdout, stderr);
stderr.should.eql('');
stdout.should.include('Finished');
});
it(`should use sourcemap when throwing within gulp-mocha (${name})`, async function () {
const [stdout, stderr] = await exec(`${GULP} --no-notif test-${name}-mocha-throw`);
print(stdout, stderr);
let output = stdout + stderr;
output.should.include('This is really bad!');
output.should.include(files.throwTestFile);
});
});
}
// TypeScript will not compile such errors, so no need to test
it('should not detect a rtts-assert error', async function () {
const [stdout, stderr] = await exec('node build-fixtures/lib/a-rtts-assert-error.js');
print(stdout, stderr);
stderr.should.equal('');
stdout.should.include('123');
stdout.should.not.include('Invalid arguments given!');
});
});