From e408d6f6d0d12711c8c3b3c873ec6b6937e5b430 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Thu, 23 May 2019 10:40:35 +0200 Subject: [PATCH 01/45] Scaffold: Add FUNDING.yml with Tidelift integration --- .github/FUNDING.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 000000000..b77a5a015 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +tidelift: npm/gulp From 3bb4ddcf3a86f69c70e98ce3de645db9c104ec98 Mon Sep 17 00:00:00 2001 From: contra Date: Mon, 3 Jun 2019 03:32:37 -0400 Subject: [PATCH 02/45] Docs: Update README plugin count (#2336) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index aac4230e1..2139f8f03 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ - **Automation** - gulp is a toolkit that helps you automate painful or time-consuming tasks in your development workflow. - **Platform-agnostic** - Integrations are built into all major IDEs and people are using gulp with PHP, .NET, Node.js, Java, and other platforms. -- **Strong Ecosystem** - Use npm modules to do anything you want + over 2000 curated plugins for streaming file transformations +- **Strong Ecosystem** - Use npm modules to do anything you want + over 3000 curated plugins for streaming file transformations - **Simple** - By providing only a minimal API surface, gulp is easy to learn and simple to use ## What's new in 4.0?! From 876fed9d8efd4acda88274aedd6a566e8de352f2 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Fri, 14 Jun 2019 15:21:14 +0900 Subject: [PATCH 03/45] Scaffold: Add security disclosure policy --- .github/SECURITY.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .github/SECURITY.md diff --git a/.github/SECURITY.md b/.github/SECURITY.md new file mode 100644 index 000000000..1a362ffae --- /dev/null +++ b/.github/SECURITY.md @@ -0,0 +1,14 @@ +# Security Policy + +## Supported Versions + +| Version | Supported | +| ------- | ------------------ | +| 4.x.x | :white_check_mark: | +| < 4.0 | :x: | + +## Reporting a Vulnerability + +To report a security vulnerability, please use the +[Tidelift security contact](https://tidelift.com/security). +Tidelift will coordinate the fix and disclosure. From 2a844299c45b15896fd70de83e6a63886895e648 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Fri, 14 Jun 2019 15:26:44 +0900 Subject: [PATCH 04/45] Scaffold: Add OpenCollective to funding platforms --- .github/FUNDING.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index b77a5a015..9ff36c3de 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1 +1,2 @@ tidelift: npm/gulp +open_collective: gulpjs From dff3c1e5161d09c1fb4f553ed75c60c5463f9486 Mon Sep 17 00:00:00 2001 From: Bryan Stoner Date: Sun, 25 Aug 2019 15:09:02 -0400 Subject: [PATCH 05/45] Docs: Ensure "Inline plugins" example is runnable (#2365) --- docs/getting-started/7-using-plugins.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/7-using-plugins.md b/docs/getting-started/7-using-plugins.md index fda305530..5f009217f 100644 --- a/docs/getting-started/7-using-plugins.md +++ b/docs/getting-started/7-using-plugins.md @@ -101,7 +101,7 @@ exports.default = function() { .pipe(through2.obj(function(file, _, cb) { if (file.isBuffer()) { const code = uglify.minify(file.contents.toString()) - file.contents = Buffer.from(code) + file.contents = Buffer.from(code.code) } cb(null, file); })) From 467530f4596dd3f3d7d35f76de307a8709085728 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Wed, 4 Sep 2019 09:17:59 -0700 Subject: [PATCH 06/45] Docs: Help users understand fake values better --- docs/recipes/automate-release-workflow.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/recipes/automate-release-workflow.md b/docs/recipes/automate-release-workflow.md index 0f18006a9..e12646c7b 100644 --- a/docs/recipes/automate-release-workflow.md +++ b/docs/recipes/automate-release-workflow.md @@ -26,7 +26,7 @@ gulp.task('changelog', function () { gulp.task('github-release', function(done) { conventionalGithubReleaser({ type: "oauth", - token: '0126af95c0e2d9b0a7c78738c4c00a860b04acc8' // change this to your own GitHub token or use an environment variable + token: 'abcdefghijklmnopqrstuvwxyz1234567890' // change this to your own GitHub token or use an environment variable }, { preset: 'angular' // Or to any other commit message convention you use. }, done); From 6b92e9225d20584a4ea3b7fea6b2d9d3fe159e5e Mon Sep 17 00:00:00 2001 From: Robert Ninness Date: Tue, 1 Oct 2019 14:10:29 +1000 Subject: [PATCH 07/45] Docs: Fix typo in last line of Vinyl usage example (#2382) --- docs/api/vinyl.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/vinyl.md b/docs/api/vinyl.md index 771a6c2e3..a11ad0f08 100644 --- a/docs/api/vinyl.md +++ b/docs/api/vinyl.md @@ -40,7 +40,7 @@ file.stem = 'foo'; file.path === '/specs/foo.txt'; file.extname === '.txt'; file.extname = '.js'; -file.path === '/specs/file.js'; +file.path === '/specs/foo.js'; ``` ## Signature From be5906b5a20b967e4508aa426223cef4dbc1683d Mon Sep 17 00:00:00 2001 From: Takayuki Sato Date: Sat, 23 Nov 2019 13:39:20 +0900 Subject: [PATCH 08/45] Docs: Add enterprise language --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 2139f8f03..1a039d6c7 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,14 @@ * Custom registries were designed, allowing for shared tasks or augmented functionality * Stream implementations were improved, allowing for better conditional and phased builds + +## gulp for enterprise + +Available as part of the Tidelift Subscription + +The maintainers of gulp and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/npm-gulp?utm_source=npm-gulp&utm_medium=referral&utm_campaign=enterprise&utm_term=repo) + + ## Installation Follow our [Quick Start guide][quick-start]. From 7672b045a651ab582cb6a0cbbf392481bfaebf80 Mon Sep 17 00:00:00 2001 From: Aaron Hooper Date: Mon, 20 Jan 2020 18:39:51 +0000 Subject: [PATCH 09/45] Docs: Correct typo in rollup example (#2406) Rollup is imported by name, so it should be called like `rollup()`. --- docs/getting-started/7-using-plugins.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/7-using-plugins.md b/docs/getting-started/7-using-plugins.md index 5f009217f..20864827a 100644 --- a/docs/getting-started/7-using-plugins.md +++ b/docs/getting-started/7-using-plugins.md @@ -37,7 +37,7 @@ const { rollup } = require('rollup'); // Rollup's promise API works great in an `async` task exports.default = async function() { - const bundle = await rollup.rollup({ + const bundle = await rollup({ input: 'src/index.js' }); From 25c1a28b19c174bef10d24e3e8fd3992364d28b0 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sat, 7 Mar 2020 12:05:04 -0700 Subject: [PATCH 10/45] Docs: Fix ESM link --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 1a039d6c7..eaa0250dc 100644 --- a/README.md +++ b/README.md @@ -290,3 +290,4 @@ Become a sponsor to get your logo on our README on Github. [quick-start]: https://gulpjs.com/docs/en/getting-started/quick-start [getting-started-guide]: https://gulpjs.com/docs/en/getting-started/quick-start [api-docs]: https://gulpjs.com/docs/en/api/concepts +[esm-module]: https://github.com/standard-things/esm From f15e9de2d302cc167ff936b15a22cb9872cfa2de Mon Sep 17 00:00:00 2001 From: Chinh Do Date: Thu, 2 Apr 2020 18:02:35 -0400 Subject: [PATCH 11/45] Docs: Fix "Async Completion" code example [ci skip] (#2428) --- docs/getting-started/4-async-completion.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/4-async-completion.md b/docs/getting-started/4-async-completion.md index 908fcc06b..0fa262cd0 100644 --- a/docs/getting-started/4-async-completion.md +++ b/docs/getting-started/4-async-completion.md @@ -127,7 +127,7 @@ When not using any of the previous options, you can define your task as an [`asy const fs = require('fs'); async function asyncAwaitTask() { - const { version } = fs.readFileSync('package.json'); + const { version } = JSON.parse(fs.readFileSync('package.json', 'utf8')); console.log(version); await Promise.resolve('some result'); } From 29cb96917824bc47349bbf68d458a2bd00716f8e Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sat, 4 Apr 2020 19:25:39 -0700 Subject: [PATCH 12/45] Docs: Fix MDX compatibility --- docs/api/dest.md | 18 ++++++------ docs/api/last-run.md | 2 +- docs/api/parallel.md | 2 +- docs/api/series.md | 2 +- docs/api/src.md | 68 ++++++++++++++++++++++---------------------- docs/api/symlink.md | 14 ++++----- docs/api/task.md | 4 +-- docs/api/vinyl.md | 4 +-- docs/api/watch.md | 40 +++++++++++++------------- 9 files changed, 77 insertions(+), 77 deletions(-) diff --git a/docs/api/dest.md b/docs/api/dest.md index d4b6fe429..e9d8bb355 100644 --- a/docs/api/dest.md +++ b/docs/api/dest.md @@ -32,7 +32,7 @@ dest(directory, [options]) | parameter | type | note | |:--------------:|:-----:|--------| -| directory
**(required)** | string
function | The path of the output directory where files will be written. If a function is used, the function will be called with each Vinyl object and must return a string directory path. | +| directory
**(required)** | string
function | The path of the output directory where files will be written. If a function is used, the function will be called with each Vinyl object and must return a string directory path. | | options | object | Detailed in [Options][options-section] below. | ### Returns @@ -60,14 +60,14 @@ When `directory` is a function that returns an empty string or `undefined`, emit | name | type | default | note | |:-------:|:------:|-----------|-------| -| cwd | string
function | `process.cwd()` | The directory that will be combined with any relative path to form an absolute path. Is ignored for absolute paths. Use to avoid combining `directory` with `path.join()`. | -| mode | number
function | `stat.mode` of the Vinyl object | The mode used when creating files. If not set and `stat.mode` is missing, the process' mode will be used instead. | -| dirMode | number
function | | The mode used when creating directories. If not set, the process' mode will be used. | -| overwrite | boolean
function | true | When true, overwrites existing files with the same path. | -| append | boolean
function | false | If true, adds contents to the end of the file, instead of replacing existing contents. | -| sourcemaps | boolean
string
function | false | If true, writes inline sourcemaps to the output file. Specifying a `string` path will write external [sourcemaps][sourcemaps-section] at the given path. | -| relativeSymlinks | boolean
function | false | When false, any symbolic links created will be absolute.
**Note**: Ignored if a junction is being created, as they must be absolute. | -| useJunctions | boolean
function | true | This option is only relevant on Windows and ignored elsewhere. When true, creates directory symbolic link as a junction. Detailed in [Symbolic links on Windows][symbolic-links-section] below. | +| cwd | string
function | `process.cwd()` | The directory that will be combined with any relative path to form an absolute path. Is ignored for absolute paths. Use to avoid combining `directory` with `path.join()`. | +| mode | number
function | `stat.mode` of the Vinyl object | The mode used when creating files. If not set and `stat.mode` is missing, the process' mode will be used instead. | +| dirMode | number
function | | The mode used when creating directories. If not set, the process' mode will be used. | +| overwrite | boolean
function | true | When true, overwrites existing files with the same path. | +| append | boolean
function | false | If true, adds contents to the end of the file, instead of replacing existing contents. | +| sourcemaps | boolean
string
function | false | If true, writes inline sourcemaps to the output file. Specifying a `string` path will write external [sourcemaps][sourcemaps-section] at the given path. | +| relativeSymlinks | boolean
function | false | When false, any symbolic links created will be absolute.
**Note**: Ignored if a junction is being created, as they must be absolute. | +| useJunctions | boolean
function | true | This option is only relevant on Windows and ignored elsewhere. When true, creates directory symbolic link as a junction. Detailed in [Symbolic links on Windows][symbolic-links-section] below. | ## Metadata updates diff --git a/docs/api/last-run.md b/docs/api/last-run.md index f1bb581e8..4e9707215 100644 --- a/docs/api/last-run.md +++ b/docs/api/last-run.md @@ -39,7 +39,7 @@ lastRun(task, [precision]) | parameter | type | note | |:--------------:|:------:|-------| -| task
**(required)** | function
string | The task function or the string alias of a registered task. | +| task
**(required)** | function
string | The task function or the string alias of a registered task. | | precision | number | Default: `1000` on Node v0.10, `0` on Node v0.12+. Detailed in [Timestamp precision][timestamp-precision-section] section below. | ### Returns diff --git a/docs/api/parallel.md b/docs/api/parallel.md index c349a8803..2df316406 100644 --- a/docs/api/parallel.md +++ b/docs/api/parallel.md @@ -37,7 +37,7 @@ parallel(...tasks) | parameter | type | note | |:--------------:|:------:|-------| -| tasks
**(required)** | function
string | Any number of task functions can be passed as individual arguments. Strings can be used if you've registered tasks previously, but this is not recommended. | +| tasks
**(required)** | function
string | Any number of task functions can be passed as individual arguments. Strings can be used if you've registered tasks previously, but this is not recommended. | ### Returns diff --git a/docs/api/series.md b/docs/api/series.md index 0d59a8caf..a04951759 100644 --- a/docs/api/series.md +++ b/docs/api/series.md @@ -37,7 +37,7 @@ series(...tasks) | parameter | type | note | |:--------------:|:------:|-------| -| tasks
**(required)** | function
string | Any number of task functions can be passed as individual arguments. Strings can be used if you've registered tasks previously, but this is not recommended. | +| tasks
**(required)** | function
string | Any number of task functions can be passed as individual arguments. Strings can be used if you've registered tasks previously, but this is not recommended. | ### Returns diff --git a/docs/api/src.md b/docs/api/src.md index 243fd9fd9..b6c69009a 100644 --- a/docs/api/src.md +++ b/docs/api/src.md @@ -35,7 +35,7 @@ src(globs, [options]) | parameter | type | note | |:--------------:|:------:|-------| -| globs | string
array | [Globs][globs-concepts] to watch on the file system. | +| globs | string
array | [Globs][globs-concepts] to watch on the file system. | | options | object | Detailed in [Options][options-section] below. | ### Returns @@ -55,39 +55,39 @@ When an invalid glob is given in `globs`, throws an error with the message, "Inv | name | type | default | note | |:--------:|:------:|------------|--------| -| buffer | boolean
function | true | When true, file contents are buffered into memory. If false, the Vinyl object's `contents` property will be a paused stream. It may not be possible to buffer the contents of large files.
**Note:** Plugins may not implement support for streaming contents. | -| read | boolean
function | true | If false, files will be not be read and their Vinyl objects won't be writable to disk via `.dest()`. | -| since | date
timestamp
function | | When set, only creates Vinyl objects for files modified since the specified time. | -| removeBOM | boolean
function | true | When true, removes the BOM from UTF-8 encoded files. If false, ignores a BOM. | -| sourcemaps | boolean
function | false | If true, enables [sourcemaps][sourcemaps-section] support on Vinyl objects created. Loads inline sourcemaps and resolves external sourcemap links. | -| resolveSymlinks | boolean
function | true | When true, recursively resolves symbolic links to their targets. If false, preserves the symbolic links and sets the Vinyl object's `symlink` property to the original file's path. | -| cwd | string | `process.cwd()` | The directory that will be combined with any relative path to form an absolute path. Is ignored for absolute paths. Use to avoid combining `globs` with `path.join()`.
_This option is passed directly to [glob-stream][glob-stream-external]._ | -| base | string | | Explicitly set the `base` property on created Vinyl objects. Detailed in [API Concepts][glob-base-concepts].
_This option is passed directly to [glob-stream][glob-stream-external]._ | -| cwdbase | boolean | false | If true, `cwd` and `base` options should be aligned.
_This option is passed directly to [glob-stream][glob-stream-external]._ | -| root | string | | The root path that `globs` are resolved against.
_This option is passed directly to [glob-stream][glob-stream-external]._ | -| allowEmpty | boolean | false | When false, `globs` which can only match one file (such as `foo/bar.js`) causes an error to be thrown if they don't find a match. If true, suppresses glob failures.
_This option is passed directly to [glob-stream][glob-stream-external]._ | -| uniqueBy | string
function | `'path'` | Remove duplicates from the stream by comparing the string property name or the result of the function.
**Note:** When using a function, the function receives the streamed data (objects containing `cwd`, `base`, `path` properties). | -| dot | boolean | false | If true, compare globs against dot files, like `.gitignore`.
_This option is passed directly to [node-glob][node-glob-external]._ | -| silent | boolean | true | When true, suppresses warnings from printing on `stderr`.
**Note:** This option is passed directly to [node-glob][node-glob-external] but defaulted to `true` instead of `false`. | -| mark | boolean | false | If true, a `/` character will be appended to directory matches. Generally not needed because paths are normalized within the pipeline.
_This option is passed directly to [node-glob][node-glob-external]._ | -| nosort | boolean | false | If true, disables sorting the glob results.
_This option is passed directly to [node-glob][node-glob-external]._ | -| stat | boolean | false | If true, `fs.stat()` is called on all results. This adds extra overhead and generally should not be used.
_This option is passed directly to [node-glob][node-glob-external]._ | -| strict | boolean | false | If true, an error will be thrown if an unexpected problem is encountered while attempting to read a directory.
_This option is passed directly to [node-glob][node-glob-external]._ | -| nounique | boolean | false | When false, prevents duplicate files in the result set.
_This option is passed directly to [node-glob][node-glob-external]._ | -| debug | boolean | false | If true, debugging information will be logged to the command line.
_This option is passed directly to [node-glob][node-glob-external]._ | -| nobrace | boolean | false | If true, avoids expanding brace sets - e.g. `{a,b}` or `{1..3}`.
_This option is passed directly to [node-glob][node-glob-external]._ | -| noglobstar | boolean | false | If true, treats double-star glob character as single-star glob character.
_This option is passed directly to [node-glob][node-glob-external]._ | -| noext | boolean | false | If true, avoids matching [extglob][extglob-docs] patterns - e.g. `+(ab)`.
_This option is passed directly to [node-glob][node-glob-external]._ | -| nocase | boolean | false | If true, performs a case-insensitive match.
**Note:** On case-insensitive file systems, non-magic patterns will match by default.
_This option is passed directly to [node-glob][node-glob-external]._ | -| matchBase | boolean | false | If true and globs don't contain any `/` characters, traverses all directories and matches that glob - e.g. `*.js` would be treated as equivalent to `**/*.js`.
_This option is passed directly to [node-glob][node-glob-external]._ | -| nodir | boolean | false | If true, only matches files, not directories.
**Note:** To match only directories, end your glob with a `/`.
_This option is passed directly to [node-glob][node-glob-external]._ | -| ignore | string
array | | Globs to exclude from matches. This option is combined with negated `globs`.
**Note:** These globs are always matched against dot files, regardless of any other settings.
_This option is passed directly to [node-glob][node-glob-external]._ | -| follow | boolean | false | If true, symlinked directories will be traversed when expanding `**` globs.
**Note:** This can cause problems with cyclical links.
_This option is passed directly to [node-glob][node-glob-external]._ | -| realpath | boolean | false | If true, `fs.realpath()` is called on all results. This may result in dangling links.
_This option is passed directly to [node-glob][node-glob-external]._ | -| cache | object | | A previously generated cache object - avoids some file system calls.
_This option is passed directly to [node-glob][node-glob-external]._ | -| statCache | object | | A previously generated cache of `fs.Stat` results - avoids some file system calls.
_This option is passed directly to [node-glob][node-glob-external]._ | -| symlinks | object | | A previously generated cache of symbolic links - avoids some file system calls.
_This option is passed directly to [node-glob][node-glob-external]._ | -| nocomment | boolean | false | When false, treat a `#` character at the start of a glob as a comment.
_This option is passed directly to [node-glob][node-glob-external]._ | +| buffer | boolean
function | true | When true, file contents are buffered into memory. If false, the Vinyl object's `contents` property will be a paused stream. It may not be possible to buffer the contents of large files.
**Note:** Plugins may not implement support for streaming contents. | +| read | boolean
function | true | If false, files will be not be read and their Vinyl objects won't be writable to disk via `.dest()`. | +| since | date
timestamp
function | | When set, only creates Vinyl objects for files modified since the specified time. | +| removeBOM | boolean
function | true | When true, removes the BOM from UTF-8 encoded files. If false, ignores a BOM. | +| sourcemaps | boolean
function | false | If true, enables [sourcemaps][sourcemaps-section] support on Vinyl objects created. Loads inline sourcemaps and resolves external sourcemap links. | +| resolveSymlinks | boolean
function | true | When true, recursively resolves symbolic links to their targets. If false, preserves the symbolic links and sets the Vinyl object's `symlink` property to the original file's path. | +| cwd | string | `process.cwd()` | The directory that will be combined with any relative path to form an absolute path. Is ignored for absolute paths. Use to avoid combining `globs` with `path.join()`.
_This option is passed directly to [glob-stream][glob-stream-external]._ | +| base | string | | Explicitly set the `base` property on created Vinyl objects. Detailed in [API Concepts][glob-base-concepts].
_This option is passed directly to [glob-stream][glob-stream-external]._ | +| cwdbase | boolean | false | If true, `cwd` and `base` options should be aligned.
_This option is passed directly to [glob-stream][glob-stream-external]._ | +| root | string | | The root path that `globs` are resolved against.
_This option is passed directly to [glob-stream][glob-stream-external]._ | +| allowEmpty | boolean | false | When false, `globs` which can only match one file (such as `foo/bar.js`) causes an error to be thrown if they don't find a match. If true, suppresses glob failures.
_This option is passed directly to [glob-stream][glob-stream-external]._ | +| uniqueBy | string
function | `'path'` | Remove duplicates from the stream by comparing the string property name or the result of the function.
**Note:** When using a function, the function receives the streamed data (objects containing `cwd`, `base`, `path` properties). | +| dot | boolean | false | If true, compare globs against dot files, like `.gitignore`.
_This option is passed directly to [node-glob][node-glob-external]._ | +| silent | boolean | true | When true, suppresses warnings from printing on `stderr`.
**Note:** This option is passed directly to [node-glob][node-glob-external] but defaulted to `true` instead of `false`. | +| mark | boolean | false | If true, a `/` character will be appended to directory matches. Generally not needed because paths are normalized within the pipeline.
_This option is passed directly to [node-glob][node-glob-external]._ | +| nosort | boolean | false | If true, disables sorting the glob results.
_This option is passed directly to [node-glob][node-glob-external]._ | +| stat | boolean | false | If true, `fs.stat()` is called on all results. This adds extra overhead and generally should not be used.
_This option is passed directly to [node-glob][node-glob-external]._ | +| strict | boolean | false | If true, an error will be thrown if an unexpected problem is encountered while attempting to read a directory.
_This option is passed directly to [node-glob][node-glob-external]._ | +| nounique | boolean | false | When false, prevents duplicate files in the result set.
_This option is passed directly to [node-glob][node-glob-external]._ | +| debug | boolean | false | If true, debugging information will be logged to the command line.
_This option is passed directly to [node-glob][node-glob-external]._ | +| nobrace | boolean | false | If true, avoids expanding brace sets - e.g. `{a,b}` or `{1..3}`.
_This option is passed directly to [node-glob][node-glob-external]._ | +| noglobstar | boolean | false | If true, treats double-star glob character as single-star glob character.
_This option is passed directly to [node-glob][node-glob-external]._ | +| noext | boolean | false | If true, avoids matching [extglob][extglob-docs] patterns - e.g. `+(ab)`.
_This option is passed directly to [node-glob][node-glob-external]._ | +| nocase | boolean | false | If true, performs a case-insensitive match.
**Note:** On case-insensitive file systems, non-magic patterns will match by default.
_This option is passed directly to [node-glob][node-glob-external]._ | +| matchBase | boolean | false | If true and globs don't contain any `/` characters, traverses all directories and matches that glob - e.g. `*.js` would be treated as equivalent to `**/*.js`.
_This option is passed directly to [node-glob][node-glob-external]._ | +| nodir | boolean | false | If true, only matches files, not directories.
**Note:** To match only directories, end your glob with a `/`.
_This option is passed directly to [node-glob][node-glob-external]._ | +| ignore | string
array | | Globs to exclude from matches. This option is combined with negated `globs`.
**Note:** These globs are always matched against dot files, regardless of any other settings.
_This option is passed directly to [node-glob][node-glob-external]._ | +| follow | boolean | false | If true, symlinked directories will be traversed when expanding `**` globs.
**Note:** This can cause problems with cyclical links.
_This option is passed directly to [node-glob][node-glob-external]._ | +| realpath | boolean | false | If true, `fs.realpath()` is called on all results. This may result in dangling links.
_This option is passed directly to [node-glob][node-glob-external]._ | +| cache | object | | A previously generated cache object - avoids some file system calls.
_This option is passed directly to [node-glob][node-glob-external]._ | +| statCache | object | | A previously generated cache of `fs.Stat` results - avoids some file system calls.
_This option is passed directly to [node-glob][node-glob-external]._ | +| symlinks | object | | A previously generated cache of symbolic links - avoids some file system calls.
_This option is passed directly to [node-glob][node-glob-external]._ | +| nocomment | boolean | false | When false, treat a `#` character at the start of a glob as a comment.
_This option is passed directly to [node-glob][node-glob-external]._ | ## Sourcemaps diff --git a/docs/api/symlink.md b/docs/api/symlink.md index a84665ed4..4080a3441 100644 --- a/docs/api/symlink.md +++ b/docs/api/symlink.md @@ -32,7 +32,7 @@ symlink(directory, [options]) | parameter | type | note | |:--------------:|:-----:|--------| -| directory
**(required)** | string
function | The path of the output directory where symbolic links will be created. If a function is used, the function will be called with each Vinyl object and must return a string directory path. | +| directory
**(required)** | string
function | The path of the output directory where symbolic links will be created. If a function is used, the function will be called with each Vinyl object and must return a string directory path. | | options | object | Detailed in [Options][options-section] below. | ### Returns @@ -63,15 +63,15 @@ When `directory` is a function that returns an empty string or `undefined`, emit | name | type | default | note | |:-------:|:------:|-----------|-------| -| cwd | string
function | `process.cwd()` |The directory that will be combined with any relative path to form an absolute path. Is ignored for absolute paths. Use to avoid combining `directory` with `path.join()`. | -| dirMode | number
function | | The mode used when creating directories. If not set, the process' mode will be used. | -| overwrite | boolean
function | true | When true, overwrites existing files with the same path. | -| relativeSymlinks | boolean
function | false | When false, any symbolic links created will be absolute.
**Note**: Ignored if a junction is being created, as they must be absolute. | -| useJunctions | boolean
function | true | This option is only relevant on Windows and ignored elsewhere. When true, creates directory symbolic link as a junction. Detailed in [Symbolic links on Windows][symbolic-links-section] below. | +| cwd | string
function | `process.cwd()` |The directory that will be combined with any relative path to form an absolute path. Is ignored for absolute paths. Use to avoid combining `directory` with `path.join()`. | +| dirMode | number
function | | The mode used when creating directories. If not set, the process' mode will be used. | +| overwrite | boolean
function | true | When true, overwrites existing files with the same path. | +| relativeSymlinks | boolean
function | false | When false, any symbolic links created will be absolute.
**Note**: Ignored if a junction is being created, as they must be absolute. | +| useJunctions | boolean
function | true | This option is only relevant on Windows and ignored elsewhere. When true, creates directory symbolic link as a junction. Detailed in [Symbolic links on Windows][symbolic-links-section] below. | ## Symbolic links on Windows -When creating symbolic links on Windows, a `type` argument is passed to Node's `fs.symlink()` method which specifies the type of target being linked. The link type is set to: +When creating symbolic links on Windows, a `type` argument is passed to Node's `fs.symlink()` method which specifies the type of target being linked. The link type is set to: * `'file'` when the target is a regular file * `'junction'` when the target is a directory * `'dir'` when the target is a directory and the user disables the `useJunctions` option diff --git a/docs/api/task.md b/docs/api/task.md index 12919b06e..21aaec404 100644 --- a/docs/api/task.md +++ b/docs/api/task.md @@ -62,7 +62,7 @@ Since any registered task can be run from the command line, avoid using spaces i | parameter | type | note | |:--------------:|:------:|-------| | taskName | string | An alias for the task function within the the task system. Not needed when using named functions for `taskFunction`. | -| taskFunction
**(required)** | function | A [task function][task-concepts] or composed task - generated by `series()` and `parallel()`. Ideally a named function. [Task metadata][task-metadata-section] can be attached to provide extra information to the command line. | +| taskFunction
**(required)** | function | A [task function][task-concepts] or composed task - generated by `series()` and `parallel()`. Ideally a named function. [Task metadata][task-metadata-section] can be attached to provide extra information to the command line. | ### Returns @@ -78,7 +78,7 @@ When registering a task where `taskName` is missing and `taskFunction` is anonym | property | type | note | |:--------------:|:------:|-------| -| name | string | A special property of named functions. Used to register the task.
**Note:** [`name`][function-name-external] is not writable; it cannot be set or changed. | +| name | string | A special property of named functions. Used to register the task.
**Note:** [`name`][function-name-external] is not writable; it cannot be set or changed. | | displayName | string | When attached to a `taskFunction` creates an alias for the task. If using characters that aren't allowed in function names, use this property. | | description | string | When attached to a `taskFunction` provides a description to be printed by the command line when listing tasks. | | flags | object | When attached to a `taskFunction` provides flags to be printed by the command line when listing tasks. The keys of the object represent the flags and the values are their descriptions. | diff --git a/docs/api/vinyl.md b/docs/api/vinyl.md index a11ad0f08..da8418f79 100644 --- a/docs/api/vinyl.md +++ b/docs/api/vinyl.md @@ -72,7 +72,7 @@ When any passed options don't conform to the [instance property definitions][ins | path | string | | The full, absolute file path. Will be [normalized][normalization-and-concatenation-section] and have trailing separators removed. | | history | array | `[ ]` | An array of paths to pre-populate the `history` of a Vinyl instance. Usually comes from deriving a new Vinyl object from a previous Vinyl object. If `path` and `history` are both passed, `path` is appended to `history`. Each item will be [normalized][normalization-and-concatenation-section] and have trailing separators removed. | | stat | object | | An instance of `fs.Stats`, usually the result of calling `fs.stat()` on a file. Used to determine if a Vinyl object represents a directory or symbolic link. | -| contents | ReadableStream
Buffer
`null` | `null` | The contents of the file. If `contents` is a ReadableStream, it is wrapped in a [cloneable-readable][cloneable-readable-external] stream. | +| contents | ReadableStream
Buffer
`null` | `null` | The contents of the file. If `contents` is a ReadableStream, it is wrapped in a [cloneable-readable][cloneable-readable-external] stream. | Any other properties on `options` will be directly assigned to the Vinyl instance. @@ -93,7 +93,7 @@ All internally managed paths - any instance property except `contents` and `stat | property | type | description | throws | |:-----------:|:------:|----------------|----------| -| contents | ReadableStream
Buffer
`null` | Gets and sets the contents of the virtual file. If set to a ReadableStream, it is wrapped in a [cloneable-readable][cloneable-readable-external] stream. | If set to any value other than a ReadableStream, a Buffer, or `null`. | +| contents | ReadableStream
Buffer
`null` | Gets and sets the contents of the virtual file. If set to a ReadableStream, it is wrapped in a [cloneable-readable][cloneable-readable-external] stream. | If set to any value other than a ReadableStream, a Buffer, or `null`. | | stat | object | Gets and sets an instance of [`fs.Stats`][fs-stats-concepts]. Used when determining if a Vinyl object represents a directory or symbolic link. | | | cwd | string | Gets and sets the current working directory. Used for deriving relative paths. | If set to an empty string or any non-string value. | | base | string | Gets and sets the base directory. Used to calculate the `relative` instance property. On a Vinyl object generated by `src()` will be set to the [glob base][glob-base-concepts]. If set to `null` or `undefined`, falls back to the value of the `cwd` instance property. | If set to an empty string or any non-string value (except `null` or `undefined`). | diff --git a/docs/api/watch.md b/docs/api/watch.md index 2b9dde27b..bc9d601e5 100644 --- a/docs/api/watch.md +++ b/docs/api/watch.md @@ -30,9 +30,9 @@ watch(globs, [options], [task]) | parameter | type | note | |:--------------:|:-----:|--------| -| globs
**(required)** | string
array | [Globs][globs-concepts] to watch on the file system. | +| globs
**(required)** | string
array | [Globs][globs-concepts] to watch on the file system. | | options | object | Detailed in [Options][options-section] below. | -| task | function
string | A [task function][tasks-concepts] or composed task - generated by `series()` and `parallel()`. | +| task | function
string | A [task function][tasks-concepts] or composed task - generated by `series()` and `parallel()`. | ### Returns @@ -48,24 +48,24 @@ When a string or array is passed as `task`, throws an error with the message, "w | name | type | default | note | |:-------:|:------:|-----------|--------| -| ignoreInitial | boolean | true | If false, the task is called during instantiation as file paths are discovered. Use to trigger the task during startup.
**Note:** This option is passed to [chokidar][chokidar-external] but is defaulted to `true` instead of `false`. | +| ignoreInitial | boolean | true | If false, the task is called during instantiation as file paths are discovered. Use to trigger the task during startup.
**Note:** This option is passed to [chokidar][chokidar-external] but is defaulted to `true` instead of `false`. | | delay | number | 200 | The millisecond delay between a file change and task execution. Allows for waiting on many changes before executing a task, e.g. find-and-replace on many files. | | queue | boolean | true | When true and the task is already running, any file changes will queue a single task execution. Keeps long running tasks from overlapping. | -| events | string
array | [ 'add',
'change',
'unlink' ] | The events being watched to trigger task execution. Can be `'add'`, `'addDir'`, `'change'`, `'unlink'`, `'unlinkDir'`, `'ready'`, and/or `'error'`. Additionally `'all'` is available, which represents all events other than `'ready'` and `'error'`.
_This option is passed directly to [chokidar][chokidar-external]._ | -| persistent | boolean | true | If false, the watcher will not keep the Node process running. Disabling this option is not recommended.
_This option is passed directly to [chokidar][chokidar-external]._ | -| ignored | array
string
RegExp
function | | Defines globs to be ignored. If a function is provided, it will be called twice per path - once with just the path, then with the path and the `fs.Stats` object of that file.
_This option is passed directly to [chokidar][chokidar-external]._ | -| followSymlinks | boolean | true | When true, changes to both symbolic links and the linked files trigger events. If false, only changes to the symbolic links trigger events.
_This option is passed directly to [chokidar][chokidar-external]._ | -| cwd | string | | The directory that will be combined with any relative path to form an absolute path. Is ignored for absolute paths. Use to avoid combining `globs` with `path.join()`.
_This option is passed directly to [chokidar][chokidar-external]._ | -| disableGlobbing | boolean | false | If true, all `globs` are treated as literal path names, even if they have special characters.
_This option is passed directly to [chokidar][chokidar-external]._ | -| usePolling | boolean | false | When false, the watcher will use `fs.watch()` (or [fsevents][fsevents-external] on Mac) for watching. If true, use `fs.watchFile()` polling instead - needed for successfully watching files over a network or other non-standard situations. Overrides the `useFsEvents` default.
_This option is passed directly to [chokidar][chokidar-external]._ | -| interval | number | 100 | Combine with `usePolling: true`. Interval of file system polling.
_This option is passed directly to [chokidar][chokidar-external]._ | -| binaryInterval | number | 300 | Combine with `usePolling: true`. Interval of file system polling for binary files.
_This option is passed directly to [chokidar][chokidar-external]._ | -| useFsEvents | boolean | true | When true, uses fsevents for watching if available. If explicitly set to true, supersedes the `usePolling` option. If set to false, automatically sets `usePolling` to true.
_This option is passed directly to [chokidar][chokidar-external]._ | -| alwaysStat | boolean | false | If true, always calls `fs.stat()` on changed files - will slow down file watcher. The `fs.Stat` object is only available if you are using the chokidar instance directly.
_This option is passed directly to [chokidar][chokidar-external]._ | -| depth | number | | Indicates how many nested levels of directories will be watched.
_This option is passed directly to [chokidar][chokidar-external]._ | -| awaitWriteFinish | boolean | false | Do not use this option, use `delay` instead.
_This option is passed directly to [chokidar][chokidar-external]._ | -| ignorePermissionErrors | boolean | false | Set to true to watch files that don't have read permissions. Then, if watching fails due to EPERM or EACCES errors, they will be skipped silently.
_This option is passed directly to [chokidar][chokidar-external]._ | -| atomic | number | 100 | Only active if `useFsEvents` and `usePolling` are false. Automatically filters out artifacts that occur from "atomic writes" by some editors. If a file is re-added within the specified milliseconds of being deleted, a change event - instead of unlink then add - will be emitted.
_This option is passed directly to [chokidar][chokidar-external]._ | +| events | string
array | [ 'add',
'change',
'unlink' ] | The events being watched to trigger task execution. Can be `'add'`, `'addDir'`, `'change'`, `'unlink'`, `'unlinkDir'`, `'ready'`, and/or `'error'`. Additionally `'all'` is available, which represents all events other than `'ready'` and `'error'`.
_This option is passed directly to [chokidar][chokidar-external]._ | +| persistent | boolean | true | If false, the watcher will not keep the Node process running. Disabling this option is not recommended.
_This option is passed directly to [chokidar][chokidar-external]._ | +| ignored | array
string
RegExp
function | | Defines globs to be ignored. If a function is provided, it will be called twice per path - once with just the path, then with the path and the `fs.Stats` object of that file.
_This option is passed directly to [chokidar][chokidar-external]._ | +| followSymlinks | boolean | true | When true, changes to both symbolic links and the linked files trigger events. If false, only changes to the symbolic links trigger events.
_This option is passed directly to [chokidar][chokidar-external]._ | +| cwd | string | | The directory that will be combined with any relative path to form an absolute path. Is ignored for absolute paths. Use to avoid combining `globs` with `path.join()`.
_This option is passed directly to [chokidar][chokidar-external]._ | +| disableGlobbing | boolean | false | If true, all `globs` are treated as literal path names, even if they have special characters.
_This option is passed directly to [chokidar][chokidar-external]._ | +| usePolling | boolean | false | When false, the watcher will use `fs.watch()` (or [fsevents][fsevents-external] on Mac) for watching. If true, use `fs.watchFile()` polling instead - needed for successfully watching files over a network or other non-standard situations. Overrides the `useFsEvents` default.
_This option is passed directly to [chokidar][chokidar-external]._ | +| interval | number | 100 | Combine with `usePolling: true`. Interval of file system polling.
_This option is passed directly to [chokidar][chokidar-external]._ | +| binaryInterval | number | 300 | Combine with `usePolling: true`. Interval of file system polling for binary files.
_This option is passed directly to [chokidar][chokidar-external]._ | +| useFsEvents | boolean | true | When true, uses fsevents for watching if available. If explicitly set to true, supersedes the `usePolling` option. If set to false, automatically sets `usePolling` to true.
_This option is passed directly to [chokidar][chokidar-external]._ | +| alwaysStat | boolean | false | If true, always calls `fs.stat()` on changed files - will slow down file watcher. The `fs.Stat` object is only available if you are using the chokidar instance directly.
_This option is passed directly to [chokidar][chokidar-external]._ | +| depth | number | | Indicates how many nested levels of directories will be watched.
_This option is passed directly to [chokidar][chokidar-external]._ | +| awaitWriteFinish | boolean | false | Do not use this option, use `delay` instead.
_This option is passed directly to [chokidar][chokidar-external]._ | +| ignorePermissionErrors | boolean | false | Set to true to watch files that don't have read permissions. Then, if watching fails due to EPERM or EACCES errors, they will be skipped silently.
_This option is passed directly to [chokidar][chokidar-external]._ | +| atomic | number | 100 | Only active if `useFsEvents` and `usePolling` are false. Automatically filters out artifacts that occur from "atomic writes" by some editors. If a file is re-added within the specified milliseconds of being deleted, a change event - instead of unlink then add - will be emitted.
_This option is passed directly to [chokidar][chokidar-external]._ | ## Chokidar instance @@ -118,7 +118,7 @@ Adds additional globs to an already-running watcher instance. | parameter | type | note | |:-------------:|:-----:|--------| -| globs | string
array | The additional globs to be watched. | +| globs | string
array | The additional globs to be watched. | `watcher.unwatch(globs)` @@ -126,7 +126,7 @@ Removes globs that are being watched, while the watcher continues with the remai | parameter | type | note | |:-------------:|:-----:|--------| -| globs | string
array | The globs to be removed. | +| globs | string
array | The globs to be removed. | [chokidar-instance-section]: #chokidar-instance [options-section]: #options From b7d9cc1825a77381f1ea424025777deaead50343 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Wed, 15 Apr 2020 21:38:01 -0700 Subject: [PATCH 13/45] Docs: Add Tidelift page --- docs/support/for-enterprise.md | 53 ++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 docs/support/for-enterprise.md diff --git a/docs/support/for-enterprise.md b/docs/support/for-enterprise.md new file mode 100644 index 000000000..2e2b26947 --- /dev/null +++ b/docs/support/for-enterprise.md @@ -0,0 +1,53 @@ + + +# Gulp for enterprise + +Available as part of the Tidelift Subscription. + +Tidelift is working with the maintainers of Gulp and thousands of other +open source projects to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. + +Learn more + +Request a demo + +## Enterprise-ready open source software—managed for you + +The Tidelift Subscription is a managed open source subscription for application dependencies covering millions of open source projects across JavaScript, Python, Java, PHP, Ruby, .NET, and more. + +Your subscription includes: + +* **Security updates** + + Tidelift’s security response team coordinates patches for new breaking security vulnerabilities and alerts immediately through a private channel, so your software supply chain is always secure. + +* **Licensing verification and indemnification** + + Tidelift verifies license information to enable easy policy enforcement and adds intellectual property indemnification to cover creators and users in case something goes wrong. You always have a 100% up-to-date bill of materials for your dependencies to share with your legal team, customers, or partners. + +* **Maintenance and code improvement** + + Tidelift ensures the software you rely on keeps working as long as you need it to work. Your managed dependencies are actively maintained and we recruit additional maintainers where required. + +* **Package selection and version guidance** + + We help you choose the best open source packages from the start—and then guide you through updates to stay on the best releases as new issues arise. + +* **Roadmap input** + + Take a seat at the table with the creators behind the software you use. Tidelift’s participating maintainers earn more income as their software is used by more subscribers, so they’re interested in knowing what you need. + +* **Tooling and cloud integration** + + Tidelift works with GitHub, GitLab, BitBucket, and more. We support every cloud platform (and other deployment targets, too). + +The end result? All of the capabilities you expect from commercial-grade software, for the full breadth of open source you use. That means less time grappling with esoteric open source trivia, and more time building your own applications—and your business. + +Learn more + +Request a demo From 27166008c54b262f8718a26378096bc6d82f21fa Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sat, 16 May 2020 15:52:12 -0700 Subject: [PATCH 14/45] Scaffold: Fallback to organization community files --- .github/FUNDING.yml | 2 -- .github/ISSUE_TEMPLATE.md | 28 ---------------------------- 2 files changed, 30 deletions(-) delete mode 100644 .github/FUNDING.yml delete mode 100644 .github/ISSUE_TEMPLATE.md diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml deleted file mode 100644 index 9ff36c3de..000000000 --- a/.github/FUNDING.yml +++ /dev/null @@ -1,2 +0,0 @@ -tidelift: npm/gulp -open_collective: gulpjs diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md deleted file mode 100644 index 1ec2c2c73..000000000 --- a/.github/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,28 +0,0 @@ -This tracker is for bug reports only. - - -Before opening an issue, please make sure you've checked the following: - -- For support requests, please use Stack Overflow (stackoverflow.com) or Gitter (see the README). - -- If the bug is in a plugin, open an issue on the plugin repository, not the gulp repository. - -- If you're getting a deprecated module warning, don't worry about it: we're aware of it and it's not an issue. To make it go away, update to Gulp 4.0. - -- If you're asking about the status of Gulp 4, please don't! You can see the remaining issues on the gulp4 label: https://github.com/gulpjs/gulp/issues?q=is%3Aissue+is%3Aopen+label%3Agulp4 - ----- - -**What were you expecting to happen?** - -**What actually happened?** - -**Please post a sample of your gulpfile (preferably reduced to just the bit that's not working)** - -```js -gulp.task(function () {}); -``` - -**What version of gulp are you using?** - -**What versions of npm and node are you using?** From 0864ee0de5282e1a07907c4e51f0fca025c6772d Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sat, 16 May 2020 17:45:55 -0700 Subject: [PATCH 15/45] Docs: Update gulp-imagemin usage (closes #2432) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index eaa0250dc..2095659ef 100644 --- a/README.md +++ b/README.md @@ -230,7 +230,7 @@ const paths = { function images() { return gulp.src(paths.images.src, {since: gulp.lastRun(images)}) - .pipe(imagemin({optimizationLevel: 5})) + .pipe(imagemin()) .pipe(gulp.dest(paths.images.dest)); } From 1ce063729714517da92310c8308d50e9541e4a47 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sat, 16 May 2020 17:56:59 -0700 Subject: [PATCH 16/45] Scaffold: Remove support template --- .github/support.yml | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 .github/support.yml diff --git a/.github/support.yml b/.github/support.yml deleted file mode 100644 index cd6325e31..000000000 --- a/.github/support.yml +++ /dev/null @@ -1,13 +0,0 @@ -# Configuration for support-requests - https://github.com/dessant/support-requests -supportLabel: support -supportComment: > - Issues are reserved for bugs and features. Here are a few places to find answers to your question: - - * For community support, use the `gulp` tag on [StackOverflow](https://stackoverflow.com/questions/tagged/gulp). - - * Participate in community chat on [Gitter](https://gitter.im/gulpjs/gulp). - - * To get paid support directly from the maintainers, sign up for [Tidelift](https://tidelift.com/subscription/pkg/npm-gulp?utm_source=npm-gulp&utm_medium=referral&utm_campaign=support). Subscribers should email support@tidelift.com, mention that it's a question for Gulp, and describe your question. Straightforward questions are answered as part of your subscription. Additional consulting hours are available for more complex help. -close: true -lock: false -setLockReason: false From 77393e18ae3c8eb439ad78734eb8dcc02e5a9ff4 Mon Sep 17 00:00:00 2001 From: Dirk Puge <67125647+dirkpuge@users.noreply.github.com> Date: Sun, 21 Jun 2020 15:48:07 -0400 Subject: [PATCH 17/45] Docs: End bullet items with a period (#2457) --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 2095659ef..162f1bee5 100644 --- a/README.md +++ b/README.md @@ -12,19 +12,19 @@ - **Automation** - gulp is a toolkit that helps you automate painful or time-consuming tasks in your development workflow. - **Platform-agnostic** - Integrations are built into all major IDEs and people are using gulp with PHP, .NET, Node.js, Java, and other platforms. -- **Strong Ecosystem** - Use npm modules to do anything you want + over 3000 curated plugins for streaming file transformations -- **Simple** - By providing only a minimal API surface, gulp is easy to learn and simple to use +- **Strong Ecosystem** - Use npm modules to do anything you want + over 3000 curated plugins for streaming file transformations. +- **Simple** - By providing only a minimal API surface, gulp is easy to learn and simple to use. ## What's new in 4.0?! -* The task system was rewritten from the ground-up, allowing task composition using `series()` and `parallel()` methods -* The watcher was updated, now using chokidar (no more need for gulp-watch!), with feature parity to our task system -* First-class support was added for incremental builds using `lastRun()` -* A `symlink()` method was exposed to create symlinks instead of copying files +* The task system was rewritten from the ground-up, allowing task composition using `series()` and `parallel()` methods. +* The watcher was updated, now using chokidar (no more need for gulp-watch!), with feature parity to our task system. +* First-class support was added for incremental builds using `lastRun()`. +* A `symlink()` method was exposed to create symlinks instead of copying files. * Built-in support for sourcemaps was added - the gulp-sourcemaps plugin is no longer necessary! -* Task registration of exported functions - using node or ES exports - is now recommended -* Custom registries were designed, allowing for shared tasks or augmented functionality -* Stream implementations were improved, allowing for better conditional and phased builds +* Task registration of exported functions - using node or ES exports - is now recommended. +* Custom registries were designed, allowing for shared tasks or augmented functionality. +* Stream implementations were improved, allowing for better conditional and phased builds. ## gulp for enterprise From e7a20a48862179192b712356ae179b1003d11b98 Mon Sep 17 00:00:00 2001 From: Ru Singh Date: Tue, 28 Jul 2020 01:44:58 +0000 Subject: [PATCH 18/45] Docs: Update rollup recipe (#2466) --- docs/recipes/rollup-with-rollup-stream.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/recipes/rollup-with-rollup-stream.md b/docs/recipes/rollup-with-rollup-stream.md index 2a8840f26..ef5dd4b4c 100644 --- a/docs/recipes/rollup-with-rollup-stream.md +++ b/docs/recipes/rollup-with-rollup-stream.md @@ -4,14 +4,14 @@ Like Browserify, [Rollup](https://rollupjs.org/) is a bundler and thus only fits ## Basic usage ```js -// npm install --save-dev gulp rollup-stream vinyl-source-stream +// npm install --save-dev gulp @rollup/stream@1 vinyl-source-stream var gulp = require('gulp'); var rollup = require('rollup-stream'); var source = require('vinyl-source-stream'); gulp.task('rollup', function() { return rollup({ - entry: './src/main.js' + input: './src/main.js' }) // give the file the name you want to output with @@ -24,7 +24,7 @@ gulp.task('rollup', function() { ## Usage with sourcemaps ```js -// npm install --save-dev gulp rollup-stream gulp-sourcemaps vinyl-source-stream vinyl-buffer +// npm install --save-dev gulp @rollup/stream@1 gulp-sourcemaps vinyl-source-stream vinyl-buffer // optional: npm install --save-dev gulp-rename var gulp = require('gulp'); var rollup = require('rollup-stream'); @@ -35,8 +35,9 @@ var buffer = require('vinyl-buffer'); gulp.task('rollup', function() { return rollup({ - entry: './src/main.js', - sourceMap: true + input: './src/main.js', + sourcemap: true, + format: 'umd' }) // point to the entry file. From 9f12c2d25a50f175b6bfe47c5485ab93782b1f7f Mon Sep 17 00:00:00 2001 From: Michal Date: Tue, 28 Jul 2020 19:12:28 +0200 Subject: [PATCH 19/45] Docs: Begin adding Polish translations (#2456) --- docs/README.md | 1 + docs/locale/pl_PL/README.md | 66 ++++++++++++++ docs/locale/pl_PL/api/concepts.md | 77 +++++++++++++++++ .../pl_PL/getting-started/1-quick-start.md | 85 +++++++++++++++++++ .../2-javascript-and-gulpfiles.md | 31 +++++++ 5 files changed, 260 insertions(+) create mode 100644 docs/locale/pl_PL/README.md create mode 100644 docs/locale/pl_PL/api/concepts.md create mode 100644 docs/locale/pl_PL/getting-started/1-quick-start.md create mode 100644 docs/locale/pl_PL/getting-started/2-javascript-and-gulpfiles.md diff --git a/docs/README.md b/docs/README.md index 9b5955ac5..939c82857 100644 --- a/docs/README.md +++ b/docs/README.md @@ -7,6 +7,7 @@ * [Why Use Pump?](why-use-pump/README.md) - Why to use the `pump` module instead of calling `.pipe` yourself * [Simplified Chinese documentation][SimplifiedChineseDocs] - gulp 简体中文文档 * [Korean documentation][KoreanDocs] - gulp 한국어 참조 문서 +* [Polish documentation](/docs/locale/pl_PL/README.md) - gulp Dokumentacja ## FAQ diff --git a/docs/locale/pl_PL/README.md b/docs/locale/pl_PL/README.md new file mode 100644 index 000000000..ced801441 --- /dev/null +++ b/docs/locale/pl_PL/README.md @@ -0,0 +1,66 @@ +# Dokumentacja gulp + +* [Pierwsze kroki](getting-started/) - Pierwsze kroki z gulp +* [Dokumentacja API](/docs/api/) - Interfejs programowania, zdefiniowany +* [Dokumentacja CLI](/docs/CLI.md) - Dowiedz się, jak wywoływać taski i korzystać z kompilatorów +* [Pisanie wtyczki](/docs/writing-a-plugin/) - Podstawy pisania wtyczki gulp +* [Czemu używać Pump?](/docs/why-use-pump/README.md) - Dlaczego używać modułu `pump` zamiast wywoływać `.pipe` yourself +* [Dokumentacja język chiński uproszczony][SimplifiedChineseDocs] - gulp 简体中文文档 +* [Dokumentacja język koreański][KoreanDocs] - gulp 한국어 참조 문서 +* [Dokumentacja język polski][PolishDocs] - gulp Dokumentacja + + +## FAQ + +Zobacz [FAQ](/docs/FAQ.md) aby uzyskać odpowiedzi na najczęściej zadawane pytania. + + +## Receptury + +Społeczność napisała [receptury](/docs/recipes#recipes) dla typowych przypadków użycia gulp. + + +## Nadal masz pytania? + +Napisz post na [StackOverflow z tagiem #gulp](https://stackoverflow.com/questions/tagged/gulp) lub wpadnij z nami na czat [#gulpjs](https://webchat.freenode.net/?channels=gulpjs) na [Freenode](https://freenode.net/). + +## Wideo +* [Wstęp do Gulp 4](https://youtu.be/N42LQ2dLoA8) prezentowany przez @addyosmani oraz @gauntface + +## Książki +* [Developing a gulp Edge](http://shop.oreilly.com/product/9781939902146.do) +* [Getting Started with Gulp – Second Edition](https://www.packtpub.com/application-development/getting-started-gulp-%E2%80%93-second-edition) - Travis Maynard, Packt (April 2017) + + +## Artykuły +* [Tagtree intro to gulp video](http://tagtree.io/gulp) +* [Introduction to node.js streams](https://github.com/substack/stream-handbook) +* [Video introduction to node.js streams](https://www.youtube.com/watch?v=QgEuZ52OZtU) +* [Getting started with gulp (by @markgdyr)](https://markgoodyear.com/2014/01/getting-started-with-gulp/) +* [A cheatsheet for gulp](https://github.com/osscafe/gulp-cheatsheet) +* [Why you shouldn’t create a gulp plugin (or, how to stop worrying and learn to love existing node packages)](http://blog.overzealous.com/post/74121048393/why-you-shouldnt-create-a-gulp-plugin-or-how-to-stop) +* [Inspiration (slides) about why gulp was made](http://slid.es/contra/gulp) +* [Building With Gulp](http://www.smashingmagazine.com/2014/06/11/building-with-gulp/) +* [Gulp - The Basics (screencast)](https://www.youtube.com/watch?v=dwSLFai8ovQ) +* [Get started with gulp (video series)](https://www.youtube.com/playlist?list=PLRk95HPmOM6PN-G1xyKj9q6ap_dc9Yckm) +* [Optimize your web code with gulp](http://www.linuxuser.co.uk/tutorials/optimise-your-web-code-with-gulp-js) +* [Automate Your Tasks Easily with Gulp.js ](https://scotch.io/tutorials/automate-your-tasks-easily-with-gulp-js) +* [How to upgrade to Gulp v4](https://www.liquidlight.co.uk/blog/article/how-do-i-update-to-gulp-4/) + +## Przykłady + +- [Web Starter Kit gulpfile](https://github.com/google/web-starter-kit/blob/master/gulpfile.babel.js) + + +## Licencja + +Cała dokumentacja objęta jest licencją CC0 *(rób co chcesz - domena publiczna)*. + +[![CC0](https://i.creativecommons.org/p/zero/1.0/88x31.png)](https://creativecommons.org/publicdomain/zero/1.0/) + +W zakresie, w jakim jest to możliwe na mocy prawa, [Fractal](http://wearefractal.com) zrzekł się wszelkich praw autorskich i pokrewnych lub powiązanych do tego dzieła. + +[SpanishDocs]: https://github.com/bucaran/gulp-docs-es +[SimplifiedChineseDocs]: https://github.com/lisposter/gulp-docs-zh-cn +[KoreanDocs]: https://github.com/preco21/gulp-docs-ko +[PolishDocs]: /docs/locale/pl_PL/README.md diff --git a/docs/locale/pl_PL/api/concepts.md b/docs/locale/pl_PL/api/concepts.md new file mode 100644 index 000000000..d23325bc9 --- /dev/null +++ b/docs/locale/pl_PL/api/concepts.md @@ -0,0 +1,77 @@ +# Pojęcia + +Poniższe pojęcia są niezbędne do zrozumienia dokumentacji API. Będą się do nich odwoływać w całości, wróć do tej strony, aby uzyskać szczegółowe wyjaśnienia. + +Jeśli jesteś tu nowy, zacznij od [Poradnik wprowadzający][quick-start-docs]. + +## Vinyl + +Vinyl to obiekt metadanych opisujący plik. Główne właściwości instancji Vinyl to `path` i `contents` - podstawowe aspekty pliku w systemie plików. Obiekty Vinyl mogą być używane do opisywania plików z wielu źródeł - w lokalnym systemie plików lub dowolnej opcji zdalnego przechowywania. + +## Adaptery Vinyl + +Chociaż Vinyl zapewnia sposób na opisanie pliku, potrzebny jest sposób na dostęp do tych plików. Każde źródło pliku jest dostępne za pomocą adaptera Vinyl. + +Adapter udostępnia: +* Metoda z podpisem `src (globs, [opcje])` i zwraca strumień, który produkuje obiekty Vinyl. +* Metoda z podpisem `dest (folder, [opcje])` i zwraca strumień, który zużywa obiekty Vinyl. +* Wszelkie dodatkowe metody specyficzne dla ich nośnika wejścia / wyjścia - takie jak metoda `symlink`, którą zapewnia `winyl-fs`. Powinny zawsze zwracać strumienie, które produkują i / lub zużywają obiekty Vinyl. + +## Zadania + +Każde zadanie gulp to asynchroniczna funkcja JavaScript, która albo przyjmuje wywołanie zwrotne z pierwszym błędem, albo zwraca strumień, obietnicę, emiter zdarzeń, proces podrzędny lub observable. Z powodu pewnych ograniczeń platformy zadania synchroniczne nie są obsługiwane. + +Aby uzyskać bardziej szczegółowe wyjaśnienie, patrz [Tworzenie zadań][creating-tasks-doc]. + +## Globs + +Glob jest ciągiem literałów i / lub symboli wieloznacznych, takich jak `*`, `**` lub `!`, używanych do dopasowania ścieżek plików. Globbing to czynność polegająca na lokalizowaniu plików w systemie plików przy użyciu co najmniej jednego globu. + +Jeśli nie masz doświadczenia z globami, zobacz [Wyjaśnianie Globs][explaining-globs-docs]. + +## Glob base + +Glob base - czasami nazywany globem parent - to segment ścieżki przed znakami specjalnymi w ciągu globu. Jako taka, globalną bazą `/src /js/**. Js` jest `/src/js/`. Wszystkie ścieżki pasujące do globu mają tę samą bazę globalną - ten segment ścieżki nie może być zmienny. + +Instancje Vinyl generowane przez `src ()` są konstruowane z ustawieniem glob base jako ich właściwości `base`. Po zapisaniu do systemu plików za pomocą `dest ()`, `base` zostanie usunięte ze ścieżki wyjściowej, aby zachować struktury katalogów. + +Aby uzyskać więcej szczegółowych informacji, zobacz [glob-parent][glob-parent-external] repository. + +## File system stats + +Metadane pliku są dostarczane jako instancja węzła [`fs.Stats`][fs-stats-external]. Jest dostępny jako właściwość `stat` w twoich instancjach Vinyl i używany wewnętrznie do ustalenia, czy obiekt Vinyl reprezentuje katalog lub dowiązanie symboliczne. Po zapisaniu w systemie plików uprawnienia i wartości czasu są synchronizowane z właściwością `stat` obiektu Vinyl. + +## File system modes + +Tryby systemu plików określają, jakie uprawnienia istnieją dla pliku. Większość plików i katalogów w twoim systemie plików będzie miała dość permisywny tryb, pozwalający gulpowi na odczyt / zapis / aktualizację plików w twoim imieniu. Domyślnie gulp tworzy pliki z tymi samymi uprawnieniami, co uruchomiony proces, ale możesz skonfigurować tryby za pomocą opcji w `src ()`, `dest ()` itp. Jeśli masz problemy z uprawnieniami (EPERM), sprawdź tryby plików. + +## Moduły + +Gulp składa się z wielu małych modułów połączonych ze sobą w celu zapewnienia spójnej pracy. Używając [semver][semver-external] w małych modułach, możemy wydać poprawki błędów i funkcje bez publikowania nowych wersji gulp. Często, gdy nie widać postępu w głównym repozytorium, praca jest wykonywana w jednym z tych modułów. + +Jeśli masz problemy, sprawdź, czy bieżące moduły zostały zaktualizowane za pomocą polecenia `npm update`. Jeśli problem będzie się powtarzał, otwórz problem w indywidualnym repozytorium projektu. + +* [undertaker][undertaker-external] - the task registration system +* [vinyl][vinyl-external] - the virtual file objects +* [vinyl-fs][vinyl-fs-external] - a vinyl adapter to your local file system +* [glob-watcher][glob-watcher-external] - the file watcher +* [bach][bach-external] - task orchestration using `series()` and `parallel()` +* [last-run][last-run-external] - tracks the last run time of a task +* [vinyl-sourcemap][vinyl-sourcemap-external] - built-in sourcemap support +* [gulp-cli][gulp-cli-external] - the command line interface for interacting with gulp + + +[quick-start-docs]: ../getting-started/1-quick-start.md +[creating-tasks-doc]: ../getting-started/3-creating-tasks.md +[explaining-globs-docs]: ../getting-started/6-explaining-globs.md +[undertaker-external]: https://github.com/gulpjs/undertaker +[vinyl-external]: https://github.com/gulpjs/vinyl +[vinyl-fs-external]: https://github.com/gulpjs/vinyl-fs +[glob-watcher-external]: https://github.com/gulpjs/glob-watcher +[bach-external]: https://github.com/gulpjs/bach +[last-run-external]: https://github.com/gulpjs/last-run +[vinyl-sourcemap-external]: https://github.com/gulpjs/vinyl-sourcemap +[gulp-cli-external]: https://github.com/gulpjs/gulp-cli +[semver-external]: https://semver.org +[fs-stats-external]: https://nodejs.org/api/fs.html#fs_class_fs_stats +[glob-parent-external]: https://github.com/es128/glob-parent diff --git a/docs/locale/pl_PL/getting-started/1-quick-start.md b/docs/locale/pl_PL/getting-started/1-quick-start.md new file mode 100644 index 000000000..3d1b54df8 --- /dev/null +++ b/docs/locale/pl_PL/getting-started/1-quick-start.md @@ -0,0 +1,85 @@ +# Szybki start + +Jeśli wcześniej instalowałeś gulp globalnie, uruchom `npm rm --global gulp` przed wykonaniem tych instrukcji. Aby uzyskać więcej informacji, przeczytaj to [Sip][sip-article]. + +## Sprawdź dla node, npm, oraz npx +```sh +node --version +``` +![Output: v8.11.1][img-node-version-command] +```sh +npm --version +``` +![Output: 5.6.0][img-npm-version-command] +```sh +npx --version +``` +![Output: 9.7.1][img-npx-version-command] + +If they are not installed, follow the instructions [here][node-install]. + +## Zainstaluj narzędzie wiersza poleceń gulp +```sh +npm install --global gulp-cli +``` + + +## Utwórz katalog projektu i przejdź do niego +```sh +npx mkdirp my-project +``` +```sh +cd my-project +``` + +## Utwórz plik package.json w katalogu projektu +```sh +npm init +``` + +To poprowadzi cię przez nadanie projektowi nazwy, wersji, opisu itp. + +## Zainstaluj pakiet gulp w swoich devDependencies +```sh +npm install --save-dev gulp +``` + +## Sprawdź swoje wersje gulp + +```sh +gulp --version +``` + +Upewnij się, że dane wyjściowe odpowiadają zrzutowi ekranu poniżej, w przeciwnym razie może być konieczne ponowne uruchomienie kroków opisanych w tym przewodniku. + +![Output: CLI version 2.0.1 & Local version 4.0.0][img-gulp-version-command] + +## Stwórz gulpfile +Za pomocą edytora tekstu utwórz plik o nazwie gulpfile.js w katalogu głównym projektu z następującymi treściami: +```js +function defaultTask(cb) { + // place code for your default task here + cb(); +} + +exports.default = defaultTask +``` + +## Przetestuj to +Uruchom polecenie gulp w katalogu projektu: +```sh +gulp +``` +Aby uruchomić wiele zadań, możesz użyć `gulp `. + +## Wynik +Zadanie domyślne zostanie uruchomione i nic nie zrobi. +![Output: Starting default & Finished default][img-gulp-command] + +[sip-article]: https://medium.com/gulpjs/gulp-sips-command-line-interface-e53411d4467 +[node-install]: https://nodejs.org/en/ +[img-node-version-command]: https://gulpjs.com/img/docs-node-version-command.png +[img-npm-version-command]: https://gulpjs.com/img/docs-npm-version-command.png +[img-npx-version-command]: https://gulpjs.com/img/docs-npx-version-command.png +[img-gulp-version-command]: https://gulpjs.com/img/docs-gulp-version-command.png +[img-gulp-command]: https://gulpjs.com/img/docs-gulp-command.png diff --git a/docs/locale/pl_PL/getting-started/2-javascript-and-gulpfiles.md b/docs/locale/pl_PL/getting-started/2-javascript-and-gulpfiles.md new file mode 100644 index 000000000..989ea9175 --- /dev/null +++ b/docs/locale/pl_PL/getting-started/2-javascript-and-gulpfiles.md @@ -0,0 +1,31 @@ +# JavaScript oraz Gulpfiles + +Gulp umożliwia wykorzystanie istniejącej wiedzy o języku JavaScript do pisania plików gulpfiles lub wykorzystanie doświadczenia z plikami gulpfiles do pisania zwykłego kodu JavaScript. Chociaż dostępnych jest kilka narzędzi upraszczających pracę z systemem plików i wierszem poleceń, wszystko, co piszesz, to czysty JavaScript. + +## Gulpfile wytłumaczony + +Plik gulpfile to plik w katalogu projektu o nazwie `gulpfile.js` (lub pisany wielkimi literami jako `Gulpfile.js`, jak Makefile), który automatycznie ładuje się po uruchomieniu polecenia `gulp`. W tym pliku często zobaczysz interfejsy API gulp, takie jak `src ()`, `dest ()`, `series ()` lub `parallel ()`, ale można użyć dowolnego standardowego modułu JavaScript lub Node. Wszelkie wyeksportowane funkcje zostaną zarejestrowane w systemie zadań gulp. + +## Transpilacja + +Możesz napisać plik gulpfile przy użyciu języka wymagającego transpilacji, takiego jak TypeScript lub Babel, zmieniając rozszerzenie w swoim `gulpfile.js` aby wskazać język i zainstalować odpowiedni moduł transpilatora. + +* Dla TypeScript, zmień nazwę `gulpfile.ts` i zaintaluj moduł [ts-node][ts-node-module]. +* Dla Babel, zmień nazwę na `gulpfile.babel.js` i zainstaluj moduł [@babel/register][babel-register-module]. + +__Większość nowych wersji node obsługuje większość funkcji udostępnianych przez TypeScript lub Babel, z wyjątkiem składni `import`/`export`. Jeśli pożądana jest tylko ta składnia, zmień nazwę na `gulpfile.esm.js` i zainstaluj moduł [esm][esm-module].__ + +Aby uzyskać bardziej zaawansowane informacje na ten temat i pełną listę obsługiwanych rozszerzeń, zobacz naszą dokumentację [gulpfile transpilation][gulpfile-transpilation-advanced]. + +## Dzielenie pliku gulpfile + +Wielu użytkowników zaczyna od dodania całej logiki do pliku gulpfile. Jeśli kiedykolwiek stanie się zbyt duży, można go przekształcić w osobne pliki. + +Każde zadanie można podzielić na własny plik, a następnie zaimportować do pliku gulp w celu złożenia. Pozwala to nie tylko utrzymać porządek, ale umożliwia testowanie każdego zadania niezależnie lub różnicowanie składu w zależności od warunków. + +Moduł Node'a pozwala zastąpić twój plik `gulpfile.js` z katalogiem o nazwie `gulpfile.js` który zawiera plik `index.js` który jest traktowany jako `gulpfile.js`. Ten katalog może następnie zawierać poszczególne moduły zadań. Jeśli używasz transpilatora, odpowiednio nazwij folder i plik. + +[gulpfile-transpilation-advanced]: ../documentation-missing.md +[ts-node-module]: https://www.npmjs.com/package/ts-node +[babel-register-module]: https://www.npmjs.com/package/@babel/register +[esm-module]: https://www.npmjs.com/package/esm From 208d6df797b08d0f288ca62ee254ca22fdcd85e7 Mon Sep 17 00:00:00 2001 From: Marouane R Date: Tue, 28 Jul 2020 18:17:22 +0100 Subject: [PATCH 20/45] Docs: Add gulp-cli answer to FAQ (#2212) --- docs/FAQ.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/FAQ.md b/docs/FAQ.md index f8a649ead..80729961f 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -30,6 +30,10 @@ Probably. Ask yourself: Always use `\n` to prevent diff issues between operating systems. +## I installed gulp as a dependency from package.json file by running `npm install` but I keep getting `command not found` whenever I try running a gulp command, why doesn't it work? + +Upon installing gulp as a project dependency, you need to add that to your PATH environment variable so that when you run a command, the system can find it. An easy solution is to install gulp globally, so that its binaries end up in your PATH environment variable. To install gulp globally, use the command `npm install gulp-cli -g` + ## Where can I get updates on gulp? gulp updates can be found on the following twitters: From 22ce5f58bb1637e800508cb1ed3e2d82320f63cf Mon Sep 17 00:00:00 2001 From: Takashi Fujita Date: Mon, 24 Aug 2020 06:41:52 +0900 Subject: [PATCH 21/45] Docs: Fix link to gulp source (#2482) --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 15e8baa31..3eff64bbc 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -30,7 +30,7 @@ of the content # Project structure -Gulp itself is tiny: index.js contains [very few lines of code](https://github.com/gulpjs/gulp/blob/4.0/index.js). +Gulp itself is tiny: index.js contains [very few lines of code](https://github.com/gulpjs/gulp/blob/master/index.js). It is powered by a few other libraries which each handle a few specific tasks each. From 93564bd7b71b953e442babff7cc22d7f91e3c392 Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Mon, 24 Aug 2020 00:13:45 +0000 Subject: [PATCH 22/45] Docs: Add advanced section for creation of custom registries (#2479) Co-authored-by: Blaine Bublitz --- docs/advanced/creating-custom-registries.md | 199 ++++++++++++++++++++ docs/api/registry.md | 2 +- 2 files changed, 200 insertions(+), 1 deletion(-) create mode 100644 docs/advanced/creating-custom-registries.md diff --git a/docs/advanced/creating-custom-registries.md b/docs/advanced/creating-custom-registries.md new file mode 100644 index 000000000..8125b6a19 --- /dev/null +++ b/docs/advanced/creating-custom-registries.md @@ -0,0 +1,199 @@ + + +# Creating Custom Registries + +Allows custom registries to be plugged into the task system, which can provide shared tasks or augmented functionality. Registries are registered using [`registry()`](registry). + +## Structure + +In order to be accepted by gulp, custom registries must follow a specific format. + +```js +// as a function +function TestRegistry() {} + +TestRegistry.prototype.init = function (gulpInst) {} +TestRegistry.prototype.get = function (name) {} +TestRegistry.prototype.set = function (name, fn) {} +TestRegistry.prototype.tasks = function () {} + +// as a class +class TestRegistry { + init(gulpInst) {} + + get(name) {} + + set(name, fn) {} + + tasks() {} +} +``` + +If a registry instance passed to `registry()` doesn't have all four methods, an error will be thrown. + +## Registration + +If we want to register our example registry from above, we will need to pass an instance of it to `registry()`. + +```js +const { registry } = require('gulp'); + +// ... TestRegistry setup code + +// good! +registry(new TestRegistry()) + +// bad! +registry(TestRegistry()) +// This will trigger an error: 'Custom registries must be instantiated, but it looks like you passed a constructor' +``` + +## Methods + +### `init(gulpInst)` + +The `init()` method of a registry is called at the very end of the `registry()` function. The gulp instance passed as the only argument (`gulpInst`) can be used to pre-define tasks using +`gulpInst.task(taskName, fn)`. + +#### Parameters + +| parameter | type | note | +|:---------:|:----:|------| +| gulpInst | object | Instance of gulp. | + +### `get(name)` + +The `get()` method receives a task `name` for the custom registry to resolve and return, or `undefined` if no task with that name exists. + +#### Parameters + +| parameter | type | note | +|:---------:|:----:|------| +| name | string | Name of the task to be retrieved. | + +### `set(name, fn)` + +The `set()` method receives a task `name` and `fn`. This is called internally by `task()` to provide user-registered tasks to custom registries. + +#### Parameters + +| parameter | type | note | +|:---------:|:----:|------| +| name | string | Name of the task to be set. | +| fn | function | Task function to be set. | + +### `tasks()` + +Must return an object listing all tasks in the registry. + +## Use Cases + +### Sharing Tasks + +To share common tasks with all your projects, you can expose an `init` method on the registry and it will receive the an instance of gulp as the only argument. You can then use `gulpInst.task(name, fn)` to register pre-defined tasks. + +For example, you might want to share a `clean` task: + +```js +const fs = require('fs'); +const util = require('util'); + +const DefaultRegistry = require('undertaker-registry'); +const del = require('del'); + +function CommonRegistry(opts){ + DefaultRegistry.call(this); + + opts = opts || {}; + + this.buildDir = opts.buildDir || './build'; +} + +util.inherits(CommonRegistry, DefaultRegistry); + +CommonRegistry.prototype.init = function(gulpInst) { + const buildDir = this.buildDir; + const exists = fs.existsSync(buildDir); + + if(exists){ + throw new Error('Cannot initialize common tasks. ' + buildDir + ' directory exists.'); + } + + gulpInst.task('clean', function(){ + return del([buildDir]); + }); +} + +module.exports = CommonRegistry; +``` + +Then to use it in a project: + +```js +const { registry, series, task } = require('gulp'); +const CommonRegistry = require('myorg-common-tasks'); + +registry(new CommonRegistry({ buildDir: '/dist' })); + +task('build', series('clean', function build(cb) { + // do things + cb(); +})); +``` + +### Sharing Functionality + +By controlling how tasks are added to the registry, you can decorate them. + +For example, if you wanted all tasks to share some data, you can use a custom registry to bind them to that data. Be sure to return the altered task, as per the description of registry methods above: + +```js +const { registry, series, task } = require('gulp'); +const util = require('util'); +const DefaultRegistry = require('undertaker-registry'); + +// Some task defined somewhere else +const BuildRegistry = require('./build.js'); +const ServeRegistry = require('./serve.js'); + +function ConfigRegistry(config){ + DefaultRegistry.call(this); + this.config = config; +} + +util.inherits(ConfigRegistry, DefaultRegistry); + +ConfigRegistry.prototype.set = function set(name, fn) { + // The `DefaultRegistry` uses `this._tasks` for storage. + var task = this._tasks[name] = fn.bind(this.config); + return task; +}; + +registry(new BuildRegistry()); +registry(new ServeRegistry()); + +// `registry` will reset each task in the registry with +// `ConfigRegistry.prototype.set` which will bind them to the config object. +registry(new ConfigRegistry({ + src: './src', + build: './build', + bindTo: '0.0.0.0:8888' +})); + +task('default', series('clean', 'build', 'serve', function(cb) { + console.log('Server bind to ' + this.bindTo); + console.log('Serving' + this.build); + cb(); +})); +``` + +## Examples + +* [`undertaker-registry`](https://github.com/gulpjs/undertaker-registry): The Gulp 4 default registry. +* [`undertaker-common-tasks`](https://github.com/gulpjs/undertaker-common-tasks): Proof-of-concept custom registry that pre-defines tasks. +* [` undertaker-task-metadata`](https://github.com/gulpjs/undertaker-task-metadata): Proof-of-concept custom registry that attaches metadata to each task. diff --git a/docs/api/registry.md b/docs/api/registry.md index 415f2cd94..c25198a3d 100644 --- a/docs/api/registry.md +++ b/docs/api/registry.md @@ -60,4 +60,4 @@ When a registry without an `init` method is passed as `registryInstance`, throws When a registry without a `tasks` method is passed as `registryInstance`, throws an error with the message, "Custom registry must have `tasks` function". -[creating-custom-registries]: ../documentation-missing.md +[creating-custom-registries]: ../advanced/creating-custom-registries.md From b7b70b8a4c1ca4f0e78517f57a467b20552a992d Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sun, 23 Aug 2020 17:20:08 -0700 Subject: [PATCH 23/45] Docs: Fix some links --- docs/advanced/creating-custom-registries.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/docs/advanced/creating-custom-registries.md b/docs/advanced/creating-custom-registries.md index 8125b6a19..fdd2a94aa 100644 --- a/docs/advanced/creating-custom-registries.md +++ b/docs/advanced/creating-custom-registries.md @@ -7,7 +7,7 @@ sidebar_label: Creating Custom Registries # Creating Custom Registries -Allows custom registries to be plugged into the task system, which can provide shared tasks or augmented functionality. Registries are registered using [`registry()`](registry). +Allows custom registries to be plugged into the task system, which can provide shared tasks or augmented functionality. Registries are registered using [`registry()`][registry-api-docs]. ## Structure @@ -194,6 +194,11 @@ task('default', series('clean', 'build', 'serve', function(cb) { ## Examples -* [`undertaker-registry`](https://github.com/gulpjs/undertaker-registry): The Gulp 4 default registry. -* [`undertaker-common-tasks`](https://github.com/gulpjs/undertaker-common-tasks): Proof-of-concept custom registry that pre-defines tasks. -* [` undertaker-task-metadata`](https://github.com/gulpjs/undertaker-task-metadata): Proof-of-concept custom registry that attaches metadata to each task. +* [undertaker-registry][undertaker-registry-example]: The Gulp 4 default registry. +* [undertaker-common-tasks][undertaker-common-tasks-example]: Proof-of-concept custom registry that pre-defines tasks. +* [undertaker-task-metadata][undertaker-task-metadata-example]: Proof-of-concept custom registry that attaches metadata to each task. + +[registry-api-docs]: ../api/registry.md +[undertaker-registry-example]: https://github.com/gulpjs/undertaker-registry +[undertaker-common-tasks-example]: https://github.com/gulpjs/undertaker-common-tasks +[undertaker-task-metadata-example]: https://github.com/gulpjs/undertaker-task-metadata From 486f92750027fa016b3558c9942ed0d37ee9ac93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matija=20Marohni=C4=87?= Date: Wed, 7 Oct 2020 22:55:40 +0200 Subject: [PATCH 24/45] Docs: Remove recipes for selecting changed files gulp v4 supports this natively by combining `since` with `gulp.lastRun()`. https://gulpjs.com/docs/en/api/lastrun --- docs/recipes/README.md | 2 -- .../only-pass-through-changed-files.md | 28 ------------------- .../recipes/rebuild-only-files-that-change.md | 16 ----------- 3 files changed, 46 deletions(-) delete mode 100644 docs/recipes/only-pass-through-changed-files.md delete mode 100644 docs/recipes/rebuild-only-files-that-change.md diff --git a/docs/recipes/README.md b/docs/recipes/README.md index 3e822432a..e38f26e46 100644 --- a/docs/recipes/README.md +++ b/docs/recipes/README.md @@ -7,9 +7,7 @@ * [Incremental rebuilding, including operating on full file sets](incremental-builds-with-concatenate.md) * [Make stream from buffer (memory contents)](make-stream-from-buffer.md) * [Mocha test-runner with gulp](mocha-test-runner-with-gulp.md) -* [Only pass through changed files](only-pass-through-changed-files.md) * [Pass parameters from the command line](pass-arguments-from-cli.md) -* [Rebuild only files that change](rebuild-only-files-that-change.md) * [Generating a file per folder](running-task-steps-per-folder.md) * [Running tasks in series](running-tasks-in-series.md) * [Server with live-reloading and CSS injection](server-with-livereload-and-css-injection.md) diff --git a/docs/recipes/only-pass-through-changed-files.md b/docs/recipes/only-pass-through-changed-files.md deleted file mode 100644 index f2db59722..000000000 --- a/docs/recipes/only-pass-through-changed-files.md +++ /dev/null @@ -1,28 +0,0 @@ -# Only pass through changed files - -Files are passed through the whole pipe chain on every run by default. By using [gulp-changed](https://github.com/sindresorhus/gulp-changed) only changed files will be passed through. This can speed up consecutive runs considerably. - - -```js -// npm install --save-dev gulp gulp-changed gulp-jscs gulp-uglify - -var gulp = require('gulp'); -var changed = require('gulp-changed'); -var jscs = require('gulp-jscs'); -var uglify = require('gulp-uglify'); - -// we define some constants here so they can be reused -var SRC = 'src/*.js'; -var DEST = 'dist'; - -gulp.task('default', function() { - return gulp.src(SRC) - // the `changed` task needs to know the destination directory - // upfront to be able to figure out which files changed - .pipe(changed(DEST)) - // only files that has changed will pass through here - .pipe(jscs()) - .pipe(uglify()) - .pipe(gulp.dest(DEST)); -}); -``` diff --git a/docs/recipes/rebuild-only-files-that-change.md b/docs/recipes/rebuild-only-files-that-change.md deleted file mode 100644 index 245ddc4fb..000000000 --- a/docs/recipes/rebuild-only-files-that-change.md +++ /dev/null @@ -1,16 +0,0 @@ -# Rebuild only files that change - -With [`gulp-watch`](https://github.com/floatdrop/gulp-watch): - -```js -var gulp = require('gulp'); -var sass = require('gulp-sass'); -var watch = require('gulp-watch'); - -gulp.task('default', function() { - return gulp.src('sass/*.scss') - .pipe(watch('sass/*.scss')) - .pipe(sass()) - .pipe(gulp.dest('dist')); -}); -``` From c4305df006d8c9acc915a8ccc82495cd17ca2f04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matija=20Marohni=C4=87?= Date: Wed, 7 Oct 2020 23:09:03 +0200 Subject: [PATCH 25/45] Docs: Remove recipe for running tasks in series gulp v4 supports this natively, as explained in the recipe itself, so there is no need for it. --- docs/recipes/README.md | 1 - docs/recipes/running-tasks-in-series.md | 89 ------------------------- 2 files changed, 90 deletions(-) delete mode 100644 docs/recipes/running-tasks-in-series.md diff --git a/docs/recipes/README.md b/docs/recipes/README.md index e38f26e46..10ca6a120 100644 --- a/docs/recipes/README.md +++ b/docs/recipes/README.md @@ -9,7 +9,6 @@ * [Mocha test-runner with gulp](mocha-test-runner-with-gulp.md) * [Pass parameters from the command line](pass-arguments-from-cli.md) * [Generating a file per folder](running-task-steps-per-folder.md) -* [Running tasks in series](running-tasks-in-series.md) * [Server with live-reloading and CSS injection](server-with-livereload-and-css-injection.md) * [Sharing streams with stream factories](sharing-streams-with-stream-factories.md) * [Specifying a new cwd (current working directory)](specifying-a-cwd.md) diff --git a/docs/recipes/running-tasks-in-series.md b/docs/recipes/running-tasks-in-series.md deleted file mode 100644 index b28e692a3..000000000 --- a/docs/recipes/running-tasks-in-series.md +++ /dev/null @@ -1,89 +0,0 @@ -# Running tasks in series - -By default, gulp CLI run tasks with maximum concurrency - e.g. it launches -all the tasks at once and waits for nothing. If you want to create a series -where tasks run in a particular order, you should use `gulp.series`; - -```js -var gulp = require('gulp'); -var doAsyncStuff = require('./stuff'); - -gulp.task('one', function(done) { - doAsyncStuff(function(err){ - done(err); - }); -}); - -gulp.task('two', function(done) { - // do things - done(); -}); - -gulp.task('default', gulp.series('one', 'two')); -``` - -Another example, using a dependency pattern. It uses -[`async-once`](https://www.npmjs.com/package/async-once) to run the `clean` -task operations only once: -```js -var gulp = require('gulp'); -var del = require('del'); // rm -rf -var once = require('async-once'); - -gulp.task('clean', once(function(done) { - // run only once. - // for the next call to the clean task, once will call done with - // the same arguments as the first call. - del(['output'], done); -})); - -gulp.task('templates', gulp.series('clean', function() { - return gulp.src(['src/templates/*.hbs']) - // do some concatenation, minification, etc. - .pipe(gulp.dest('output/templates/')); -})); - -gulp.task('styles', gulp.series('clean', function() { - return gulp.src(['src/styles/app.less']) - // do some hinting, minification, etc. - .pipe(gulp.dest('output/css/app.css')); -})); - -// templates and styles will be processed in parallel. -// `clean` will be guaranteed to complete before either start. -// `clean` operations will not be run twice, -// even though it is called as a dependency twice. -gulp.task('build', gulp.parallel('templates', 'styles')); - -// an alias. -gulp.task('default', gulp.parallel('build')); -``` - -Note that it's an anti-pattern in Gulp 4 and the logs will show the clean task -running twice. Instead, `templates` and `style` should use dedicated `clean:*` -tasks: -```js -var gulp = require('gulp'); -var del = require('del'); - -gulp.task('clean:templates', function() { - return del(['output/templates/']); -}); - -gulp.task('templates', gulp.series('clean:templates', function() { - return gulp.src(['src/templates/*.hbs']) - .pipe(gulp.dest('output/templates/')); -}); - -gulp.task('clean:styles', function() { - return del(['output/css/']); -}); - -gulp.task('styles', gulp.series('clean:styles', function() { - return gulp.src(['src/styles/app.less']) - .pipe(gulp.dest('output/css/app.css')); -})); - -gulp.task('build', gulp.parallel('templates', 'styles')); -gulp.task('default', gulp.parallel('build')); -``` From e1190ea05e2eb36080bc513512190c895e0cc4b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matija=20Marohni=C4=87?= Date: Wed, 7 Oct 2020 23:13:00 +0200 Subject: [PATCH 26/45] Docs: Remove recipe for exporting tasks This is a core feature, it's not necessary to explain it in a recipe. --- docs/recipes/README.md | 1 - docs/recipes/exports-as-tasks.md | 22 ---------------------- 2 files changed, 23 deletions(-) delete mode 100644 docs/recipes/exports-as-tasks.md diff --git a/docs/recipes/README.md b/docs/recipes/README.md index 10ca6a120..55dc0f382 100644 --- a/docs/recipes/README.md +++ b/docs/recipes/README.md @@ -21,7 +21,6 @@ * [Output both a minified and non-minified version](minified-and-non-minified.md) * [Templating with Swig and YAML front-matter](templating-with-swig-and-yaml-front-matter.md) * [Run Grunt Tasks from Gulp](run-grunt-tasks-from-gulp.md) -* [Exports as tasks](exports-as-tasks.md) * [Rollup with rollup-stream](rollup-with-rollup-stream.md) * [Run gulp task via cron job](cron-task.md) * [Running shell commands](running-shell-commands.md) diff --git a/docs/recipes/exports-as-tasks.md b/docs/recipes/exports-as-tasks.md deleted file mode 100644 index 2eaea4905..000000000 --- a/docs/recipes/exports-as-tasks.md +++ /dev/null @@ -1,22 +0,0 @@ -# Exports as Tasks - -Using the ES2015 module syntax you can use your exports as tasks. - -```js -import gulp from 'gulp'; -import babel from 'gulp-babel'; - -// named task -export function build() { - return gulp.src('src/*.js') - .pipe(babel()) - .pipe(gulp.dest('lib')); -} - -// default task -export default function dev() { - gulp.watch('src/*.js', ['build']); -} -``` - -This will **not** work with the gulp-cli version bundled with gulp 3.x. You must use the latest published version. From 1a653a92b7ee567b184109c30028d99f64290458 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matija=20Marohni=C4=87?= Date: Wed, 7 Oct 2020 23:17:12 +0200 Subject: [PATCH 27/45] Docs: Remove recipe for running shell commands gulp v4 supports this natively now, tasks can return a child process. https://gulpjs.com/docs/en/getting-started/async-completion#returning-a-child-process --- docs/recipes/README.md | 1 - docs/recipes/running-shell-commands.md | 31 -------------------------- 2 files changed, 32 deletions(-) delete mode 100644 docs/recipes/running-shell-commands.md diff --git a/docs/recipes/README.md b/docs/recipes/README.md index 55dc0f382..a022bc452 100644 --- a/docs/recipes/README.md +++ b/docs/recipes/README.md @@ -23,4 +23,3 @@ * [Run Grunt Tasks from Gulp](run-grunt-tasks-from-gulp.md) * [Rollup with rollup-stream](rollup-with-rollup-stream.md) * [Run gulp task via cron job](cron-task.md) -* [Running shell commands](running-shell-commands.md) diff --git a/docs/recipes/running-shell-commands.md b/docs/recipes/running-shell-commands.md deleted file mode 100644 index 5d3447476..000000000 --- a/docs/recipes/running-shell-commands.md +++ /dev/null @@ -1,31 +0,0 @@ -# Running Shell Commands - -Sometimes it is helpful to be able to call existing command line tools from gulp. - -There are 2 ways to handle this: node's [`child_process`](https://nodejs.org/api/child_process.html) -built-in module or [`gulp-exec`](https://github.com/robrich/gulp-exec) if you need to integrate the -command with an existing pipeline. - -```js -'use strict'; - -var cp = require('child_process'); -var gulp = require('gulp'); - -gulp.task('reset', function() { - // In gulp 4, you can return a child process to signal task completion - return cp.execFile('git checkout -- .'); -}); -``` - -```js -'use strict'; - -var gulp = require('gulp'); -var exec = require('gulp-exec'); - -gulp.task('reset', function() { - return gulp.src('./**/**') - .pipe(exec('git checkout -- <%= file.path %>')); -}); -``` From 147327c4d7b14ba9ee98182cee7d377dc2194d95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matija=20Marohni=C4=87?= Date: Wed, 7 Oct 2020 23:20:03 +0200 Subject: [PATCH 28/45] Docs: Remove recipe for specifying a CWD The `cwd` option is described in the docs for `gulp.src`, and `--cwd` can be found when running `gulp --help`. Having this as a recipe seems unnecessary. --- docs/recipes/README.md | 1 - docs/recipes/specifying-a-cwd.md | 23 ----------------------- 2 files changed, 24 deletions(-) delete mode 100644 docs/recipes/specifying-a-cwd.md diff --git a/docs/recipes/README.md b/docs/recipes/README.md index a022bc452..9234b603e 100644 --- a/docs/recipes/README.md +++ b/docs/recipes/README.md @@ -11,7 +11,6 @@ * [Generating a file per folder](running-task-steps-per-folder.md) * [Server with live-reloading and CSS injection](server-with-livereload-and-css-injection.md) * [Sharing streams with stream factories](sharing-streams-with-stream-factories.md) -* [Specifying a new cwd (current working directory)](specifying-a-cwd.md) * [Split tasks across multiple files](split-tasks-across-multiple-files.md) * [Using external config file](using-external-config-file.md) * [Using multiple sources in one task](using-multiple-sources-in-one-task.md) diff --git a/docs/recipes/specifying-a-cwd.md b/docs/recipes/specifying-a-cwd.md deleted file mode 100644 index eba0ceca9..000000000 --- a/docs/recipes/specifying-a-cwd.md +++ /dev/null @@ -1,23 +0,0 @@ -# Specifying a new cwd (current working directory) - -This is helpful for projects using a nested directory structure, such as: - -``` -/project - /layer1 - /layer2 -``` - -You can use the gulp CLI option `--cwd`. - -From the `project/` directory: - -```sh -gulp --cwd layer1 -``` - -If you only need to specify a cwd for a certain glob, you can use the `cwd` option on a [glob-stream](https://github.com/gulpjs/glob-stream): - -```js -gulp.src('./some/dir/**/*.js', { cwd: 'public' }); -``` From c5ff7e06263d23ee19700a3af0478103590060eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matija=20Marohni=C4=87?= Date: Wed, 7 Oct 2020 23:22:22 +0200 Subject: [PATCH 29/45] Docs: Remove recipe for splitting tasks in files It should be very obvious that you can `require` functions from other files in `gulpfile.js` and export them as tasks, it seems unnecessary to use `gulp-hub`. --- docs/recipes/README.md | 1 - .../split-tasks-across-multiple-files.md | 38 ------------------- 2 files changed, 39 deletions(-) delete mode 100644 docs/recipes/split-tasks-across-multiple-files.md diff --git a/docs/recipes/README.md b/docs/recipes/README.md index 9234b603e..46cadd4b8 100644 --- a/docs/recipes/README.md +++ b/docs/recipes/README.md @@ -11,7 +11,6 @@ * [Generating a file per folder](running-task-steps-per-folder.md) * [Server with live-reloading and CSS injection](server-with-livereload-and-css-injection.md) * [Sharing streams with stream factories](sharing-streams-with-stream-factories.md) -* [Split tasks across multiple files](split-tasks-across-multiple-files.md) * [Using external config file](using-external-config-file.md) * [Using multiple sources in one task](using-multiple-sources-in-one-task.md) * [Browserify + Uglify with sourcemaps](browserify-uglify-sourcemap.md) diff --git a/docs/recipes/split-tasks-across-multiple-files.md b/docs/recipes/split-tasks-across-multiple-files.md deleted file mode 100644 index a93217a94..000000000 --- a/docs/recipes/split-tasks-across-multiple-files.md +++ /dev/null @@ -1,38 +0,0 @@ -# Split tasks across multiple files - -If your `gulpfile.js` is starting to grow too large, you can split the tasks -into separate files by using the [gulp-hub](https://github.com/frankwallis/gulp-hub/tree/4.0) -module as a [custom registry](https://github.com/phated/undertaker#registryregistryinstance). - -Imagine the following file structure: - -``` -gulpfile.js -tasks/ -├── dev.js -├── release.js -└── test.js -``` - -Install the `gulp-hub` module: - -```sh -npm install --save-dev gulp gulp-hub -``` - -Add the following lines to your `gulpfile.js` file: - -```js -'use strict'; - -var gulp = require('gulp'); -var HubRegistry = require('gulp-hub'); - -/* load some files into the registry */ -var hub = new HubRegistry(['tasks/*.js']); - -/* tell gulp to use the tasks just loaded */ -gulp.registry(hub); -``` - -This recipe can also be found at https://github.com/frankwallis/gulp-hub/tree/4.0/examples/recipe From 131b70288475255812e2959d0ba116f3f551fcef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matija=20Marohni=C4=87?= Date: Wed, 7 Oct 2020 23:24:40 +0200 Subject: [PATCH 30/45] Docs: Remove recipe for using a config file It seems too basic and obvious. --- docs/recipes/README.md | 1 - docs/recipes/using-external-config-file.md | 53 ---------------------- 2 files changed, 54 deletions(-) delete mode 100644 docs/recipes/using-external-config-file.md diff --git a/docs/recipes/README.md b/docs/recipes/README.md index 46cadd4b8..3433f444c 100644 --- a/docs/recipes/README.md +++ b/docs/recipes/README.md @@ -11,7 +11,6 @@ * [Generating a file per folder](running-task-steps-per-folder.md) * [Server with live-reloading and CSS injection](server-with-livereload-and-css-injection.md) * [Sharing streams with stream factories](sharing-streams-with-stream-factories.md) -* [Using external config file](using-external-config-file.md) * [Using multiple sources in one task](using-multiple-sources-in-one-task.md) * [Browserify + Uglify with sourcemaps](browserify-uglify-sourcemap.md) * [Browserify + Globs](browserify-with-globs.md) diff --git a/docs/recipes/using-external-config-file.md b/docs/recipes/using-external-config-file.md deleted file mode 100644 index 6c740761b..000000000 --- a/docs/recipes/using-external-config-file.md +++ /dev/null @@ -1,53 +0,0 @@ -# Using external config file - -Beneficial because it's keeping tasks DRY and config.json can be used by another task runner, like `grunt`. - -- - -###### `config.json` - -```json -{ - "desktop" : { - "src" : [ - "dev/desktop/js/**/*.js", - "!dev/desktop/js/vendor/**" - ], - "dest" : "build/desktop/js" - }, - "mobile" : { - "src" : [ - "dev/mobile/js/**/*.js", - "!dev/mobile/js/vendor/**" - ], - "dest" : "build/mobile/js" - } -} -``` - -- - -###### `gulpfile.js` - -```js -// npm install --save-dev gulp gulp-uglify merge-stream -var gulp = require('gulp'); -var uglify = require('gulp-uglify'); -var merge = require('merge-stream'); - -var config = require('./config.json'); - -function doStuff(cfg) { - return gulp.src(cfg.src) - .pipe(uglify()) - .pipe(gulp.dest(cfg.dest)); -} - -gulp.task('dry', function() { - // return a stream to signal completion - return merge([ - doStuff(config.desktop), - doStuff(config.mobile) - ]) -}); -``` From 6e56ed8cb5a64cee038475c05f94ea47f7c092d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matija=20Marohni=C4=87?= Date: Wed, 21 Oct 2020 20:49:01 +0200 Subject: [PATCH 31/45] Docs: Update and refactor release workflow recipe (#2498) --- docs/recipes/automate-release-workflow.md | 167 ++++++++++++---------- 1 file changed, 94 insertions(+), 73 deletions(-) diff --git a/docs/recipes/automate-release-workflow.md b/docs/recipes/automate-release-workflow.md index e12646c7b..4e64bb53c 100644 --- a/docs/recipes/automate-release-workflow.md +++ b/docs/recipes/automate-release-workflow.md @@ -1,79 +1,100 @@ -# Automate release workflow + + +# Automate Releases If your project follows a semantic versioning, it may be a good idea to automatize the steps needed to do a release. -Below you have a simple recipe that bumps the project version, commits the changes to git and creates a new tag. - -``` javascript - -var gulp = require('gulp'); -var conventionalChangelog = require('gulp-conventional-changelog'); -var conventionalGithubReleaser = require('conventional-github-releaser'); -var bump = require('gulp-bump'); -var log = require('gulplog'); -var git = require('gulp-git'); -var fs = require('fs'); - -gulp.task('changelog', function () { - return gulp.src('CHANGELOG.md', { - buffer: false - }) - .pipe(conventionalChangelog({ - preset: 'angular' // Or to any other commit message convention you use. - })) - .pipe(gulp.dest('./')); -}); - -gulp.task('github-release', function(done) { - conventionalGithubReleaser({ - type: "oauth", - token: 'abcdefghijklmnopqrstuvwxyz1234567890' // change this to your own GitHub token or use an environment variable - }, { - preset: 'angular' // Or to any other commit message convention you use. - }, done); -}); - -gulp.task('bump-version', function () { -// We hardcode the version change type to 'patch' but it may be a good idea to -// use minimist (https://www.npmjs.com/package/minimist) to determine with a -// command argument whether you are doing a 'major', 'minor' or a 'patch' change. - return gulp.src(['./bower.json', './package.json']) - .pipe(bump({type: "patch"}).on('error', log.error)) - .pipe(gulp.dest('./')); -}); - -gulp.task('commit-changes', function () { - return gulp.src('.') - .pipe(git.add()) - .pipe(git.commit('[Prerelease] Bumped version number')); -}); - -gulp.task('push-changes', function (done) { - git.push('origin', 'master', done); -}); - -gulp.task('create-new-tag', function (done) { - var version = getPackageJsonVersion(); - git.tag(version, 'Created Tag for version: ' + version, function (error) { - if (error) { - return done(error); - } - git.push('origin', 'master', {args: '--tags'}, done); +The recipe below bumps the project version, commits the changes to git and creates a new GitHub release. + +For publishing a GitHub release you'll need to [create a personal access token](https://docs.github.com/en/free-pro-team@latest/github/authenticating-to-github/creating-a-personal-access-token) and add it to your project. However, we don't want to commit it, so we'll use [`dotenv`](https://www.npmjs.com/package/dotenv) to load it from a git-ignored `.env` file: + +``` +GH_TOKEN=ff34885... +``` + +Don't forget to add `.env` to your `.gitignore`. + +Next, install all the necessary dependencies for this recipe: + +```sh +npm install --save-dev conventional-recommended-bump conventional-changelog-cli conventional-github-releaser dotenv execa +``` + +Based on your environment, setup and preferences, your release workflow might look something like this: + +``` js +const gulp = require('gulp'); +const conventionalRecommendedBump = require('conventional-recommended-bump'); +const conventionalGithubReleaser = require('conventional-github-releaser'); +const execa = require('execa'); +const fs = require('fs'); +const { promisify } = require('util'); +const dotenv = require('dotenv'); + +// load environment variables +const result = dotenv.config(); + +if (result.error) { + throw result.error; +} + +// Conventional Changelog preset +const preset = 'angular'; +// print output of commands into the terminal +const stdio = 'inherit'; + +async function bumpVersion() { + // get recommended version bump based on commits + const { releaseType } = await promisify(conventionalRecommendedBump)({ preset }); + // bump version without committing and tagging + await execa('npm', ['version', releaseType, '--no-git-tag-version'], { + stdio, }); +} + +async function changelog() { + await execa( + 'npx', + [ + 'conventional-changelog', + '--preset', + preset, + '--infile', + 'CHANGELOG.md', + '--same-file', + ], + { stdio } + ); +} + +async function commitTagPush() { + // even though we could get away with "require" in this case, we're taking the safe route + // because "require" caches the value, so if we happen to use "require" again somewhere else + // we wouldn't get the current value, but the value of the last time we called "require" + const { version } = JSON.parse(await promisify(fs.readFile)('package.json')); + const commitMsg = `chore: release ${version}`; + await execa('git', ['add', '.'], { stdio }); + await execa('git', ['commit', '--message', commitMsg], { stdio }); + await execa('git', ['tag', `v${version}`], { stdio }); + await execa('git', ['push', '--follow-tags'], { stdio }); +} - function getPackageJsonVersion () { - // We parse the json file instead of using require because require caches - // multiple calls so the version number won't be updated - return JSON.parse(fs.readFileSync('./package.json', 'utf8')).version; - }; -}); - -gulp.task('release', gulp.series( - 'bump-version', - 'changelog', - 'commit-changes', - 'push-changes', - 'create-new-tag', - 'github-release' -)); +function githubRelease(done) { + conventionalGithubReleaser( + { type: 'oauth', token: process.env.GH_TOKEN }, + { preset }, + done + ); +} +exports.release = gulp.series( + bumpVersion, + changelog, + commitTagPush, + githubRelease +); ``` From 4c1beadcba7381ae3b938947bd06c8785ca11fb9 Mon Sep 17 00:00:00 2001 From: entrywayaudibly <71117336+entrywayaudibly@users.noreply.github.com> Date: Wed, 21 Oct 2020 18:51:22 +0000 Subject: [PATCH 32/45] Docs: Add subtitles for registry error messages (#2502) --- docs/api/registry.md | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/docs/api/registry.md b/docs/api/registry.md index c25198a3d..008c959f8 100644 --- a/docs/api/registry.md +++ b/docs/api/registry.md @@ -7,7 +7,6 @@ sidebar_label: registry() # registry() - Allows custom registries to be plugged into the task system, which can provide shared tasks or augmented functionality. **Note:** Only tasks registered with `task()` will be provided to the custom registry. The task functions passed directly to `series()` or `parallel()` will not be provided - if you need to customize the registry behavior, compose tasks with string references. @@ -50,14 +49,34 @@ If a `registryInstance` is passed, nothing will be returned. If no arguments are ### Errors -When a constructor (instead of an instance) is passed as `registryInstance`, throws an error with the message, "Custom registries must be instantiated, but it looks like you passed a constructor". +#### Incorrect Parameter + +When a constructor (instead of an instance) is passed as `registryInstance`, throws an error with the message: + +> Custom registries must be instantiated, but it looks like you passed a constructor. + +#### Missing get Method + +When a registry without a `get` method is passed as `registryInstance`, throws an error with the message: + +> Custom registry must have `get` function. + +#### Missing set Method + +When a registry without a `set` method is passed as `registryInstance`, throws an error with the message: + +> Custom registry must have `set` function. + +#### Missing init Method + +When a registry without an `init` method is passed as `registryInstance`, throws an error with the message: -When a registry without a `get` method is passed as `registryInstance`, throws an error with the message, "Custom registry must have `get` function". +> Custom registry must have `init` function" -When a registry without a `set` method is passed as `registryInstance`, throws an error with the message, "Custom registry must have `set` function". +#### Missing tasks Method -When a registry without an `init` method is passed as `registryInstance`, throws an error with the message, "Custom registry must have `init` function" +When a registry without a `tasks` method is passed as `registryInstance`, throws an error with the message: -When a registry without a `tasks` method is passed as `registryInstance`, throws an error with the message, "Custom registry must have `tasks` function". +> Custom registry must have `tasks` function. [creating-custom-registries]: ../advanced/creating-custom-registries.md From d51c6eb8ff51bc7d251f30e1b15288b72492c384 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Wed, 21 Oct 2020 12:02:40 -0700 Subject: [PATCH 33/45] Docs: Rename the automate releases recipe file --- .../{automate-release-workflow.md => automate-releases.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/recipes/{automate-release-workflow.md => automate-releases.md} (100%) diff --git a/docs/recipes/automate-release-workflow.md b/docs/recipes/automate-releases.md similarity index 100% rename from docs/recipes/automate-release-workflow.md rename to docs/recipes/automate-releases.md From c26ebcb1c9842251c8dd716461d735e26feb862a Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Wed, 21 Oct 2020 12:25:54 -0700 Subject: [PATCH 34/45] Docs: Cleanup registry error message subtitles --- docs/api/registry.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/api/registry.md b/docs/api/registry.md index 008c959f8..d1b2123d3 100644 --- a/docs/api/registry.md +++ b/docs/api/registry.md @@ -49,31 +49,31 @@ If a `registryInstance` is passed, nothing will be returned. If no arguments are ### Errors -#### Incorrect Parameter +#### Incorrect parameter When a constructor (instead of an instance) is passed as `registryInstance`, throws an error with the message: > Custom registries must be instantiated, but it looks like you passed a constructor. -#### Missing get Method +#### Missing `get` method When a registry without a `get` method is passed as `registryInstance`, throws an error with the message: > Custom registry must have `get` function. -#### Missing set Method +#### Missing `set` method When a registry without a `set` method is passed as `registryInstance`, throws an error with the message: > Custom registry must have `set` function. -#### Missing init Method +#### Missing `init` method When a registry without an `init` method is passed as `registryInstance`, throws an error with the message: > Custom registry must have `init` function" -#### Missing tasks Method +#### Missing `tasks` method When a registry without a `tasks` method is passed as `registryInstance`, throws an error with the message: From b6d6d7c8c37f4be846cf796d3929fe25c5329808 Mon Sep 17 00:00:00 2001 From: azu Date: Mon, 11 Jan 2021 07:49:51 +0900 Subject: [PATCH 35/45] Docs: fix recipe link (#2526) --- docs/recipes/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/recipes/README.md b/docs/recipes/README.md index 3433f444c..6748fa542 100644 --- a/docs/recipes/README.md +++ b/docs/recipes/README.md @@ -1,6 +1,6 @@ # Recipes -* [Automate release workflow](automate-release-workflow.md) +* [Automate release workflow](automate-releases.md) * [Combining streams to handle errors](combining-streams-to-handle-errors.md) * [Delete files and folders](delete-files-folder.md) * [Fast browserify builds with watchify](fast-browserify-builds-with-watchify.md) From df252509b52acd712300b3b5d00bf7aedf0dbd40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anderson=20Samir=20Corr=C3=AAa=20Paz=20de=20Camargo?= Date: Sun, 10 Jan 2021 20:13:16 -0300 Subject: [PATCH 36/45] Docs: Fix typo in task docs (#2524) --- docs/api/task.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/task.md b/docs/api/task.md index 21aaec404..de3c54621 100644 --- a/docs/api/task.md +++ b/docs/api/task.md @@ -61,7 +61,7 @@ Since any registered task can be run from the command line, avoid using spaces i | parameter | type | note | |:--------------:|:------:|-------| -| taskName | string | An alias for the task function within the the task system. Not needed when using named functions for `taskFunction`. | +| taskName | string | An alias for the task function within the task system. Not needed when using named functions for `taskFunction`. | | taskFunction
**(required)** | function | A [task function][task-concepts] or composed task - generated by `series()` and `parallel()`. Ideally a named function. [Task metadata][task-metadata-section] can be attached to provide extra information to the command line. | ### Returns From f91c388beb265e5008202f11100309549162247a Mon Sep 17 00:00:00 2001 From: roydukkey Date: Mon, 8 Feb 2021 15:22:24 -0500 Subject: [PATCH 37/45] Docs: Remove typo in custom registry docs (#2543) --- docs/advanced/creating-custom-registries.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/advanced/creating-custom-registries.md b/docs/advanced/creating-custom-registries.md index fdd2a94aa..a5423b5fa 100644 --- a/docs/advanced/creating-custom-registries.md +++ b/docs/advanced/creating-custom-registries.md @@ -95,7 +95,7 @@ Must return an object listing all tasks in the registry. ### Sharing Tasks -To share common tasks with all your projects, you can expose an `init` method on the registry and it will receive the an instance of gulp as the only argument. You can then use `gulpInst.task(name, fn)` to register pre-defined tasks. +To share common tasks with all your projects, you can expose an `init` method on the registry and it will receive an instance of gulp as the only argument. You can then use `gulpInst.task(name, fn)` to register pre-defined tasks. For example, you might want to share a `clean` task: From 9877de07cf923c889d7f0661d87f3d6f8634eeb1 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Martin Date: Fri, 9 Apr 2021 23:07:03 +0200 Subject: [PATCH 38/45] Docs: Guide CustomRegistries to maintain properties on tasks (fixes #2561) (#2565) --- docs/advanced/creating-custom-registries.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/advanced/creating-custom-registries.md b/docs/advanced/creating-custom-registries.md index a5423b5fa..6fcdbeb65 100644 --- a/docs/advanced/creating-custom-registries.md +++ b/docs/advanced/creating-custom-registries.md @@ -169,8 +169,11 @@ function ConfigRegistry(config){ util.inherits(ConfigRegistry, DefaultRegistry); ConfigRegistry.prototype.set = function set(name, fn) { + var bound = fn.bind(this.config); + // Preserve internal properties and task metadata. + var task = Object.assign(bound, fn); // The `DefaultRegistry` uses `this._tasks` for storage. - var task = this._tasks[name] = fn.bind(this.config); + this._tasks[name] = task; return task; }; From 598f971a6567401e5760f4fd0b84df0180c2e350 Mon Sep 17 00:00:00 2001 From: Seno <4535187+s-en-o@users.noreply.github.com> Date: Tue, 4 May 2021 07:37:34 +1200 Subject: [PATCH 39/45] Docs: Fix broken link in recipe (#2571) --- docs/recipes/minimal-browsersync-setup-with-gulp4.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/recipes/minimal-browsersync-setup-with-gulp4.md b/docs/recipes/minimal-browsersync-setup-with-gulp4.md index ec22c0717..82acb674b 100644 --- a/docs/recipes/minimal-browsersync-setup-with-gulp4.md +++ b/docs/recipes/minimal-browsersync-setup-with-gulp4.md @@ -35,7 +35,7 @@ The gulpfile could be broken in 3 parts. ### 1. Write the task to prepare the dist package as usual -Refer to the main [README](https://github.com/gulpjs/gulp/blob/4.0/README.md#use-last-javascript-version-in-your-gulpfile) +Refer to the main [README](https://github.com/gulpjs/gulp/blob/master/docs/README.md) for more information. ```javascript From 818bd73e5da1ad69f43eef84214c98d6392a73e4 Mon Sep 17 00:00:00 2001 From: Artem Guskov <61526280+brendan8c@users.noreply.github.com> Date: Tue, 22 Jun 2021 21:18:17 +0300 Subject: [PATCH 40/45] Docs: Remove gulp-sourcemaps because it is built-in (#2592) --- docs/recipes/browserify-transforms.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/docs/recipes/browserify-transforms.md b/docs/recipes/browserify-transforms.md index 47a0d4d54..58c74bc33 100644 --- a/docs/recipes/browserify-transforms.md +++ b/docs/recipes/browserify-transforms.md @@ -15,7 +15,6 @@ var source = require('vinyl-source-stream'); var buffer = require('vinyl-buffer'); var log = require('gulplog'); var uglify = require('gulp-uglify'); -var sourcemaps = require('gulp-sourcemaps'); var reactify = require('reactify'); gulp.task('javascript', function () { @@ -28,13 +27,11 @@ gulp.task('javascript', function () { }); return b.bundle() - .pipe(source('app.js')) + .pipe(source('app.js', { sourcemaps: true })) .pipe(buffer()) - .pipe(sourcemaps.init({loadMaps: true})) // Add transformation tasks to the pipeline here. .pipe(uglify()) .on('error', log.error) - .pipe(sourcemaps.write('./')) - .pipe(gulp.dest('./dist/js/')); + .pipe(gulp.dest('./dist/js/', { sourcemaps: '../sourcemaps/' })); }); ``` From 85896d4f099a80d58dd08d1f6d80586b07678995 Mon Sep 17 00:00:00 2001 From: Viishesh Jain <60565221+Viisheshjain05@users.noreply.github.com> Date: Mon, 19 Dec 2022 23:32:08 +0530 Subject: [PATCH 41/45] chore(docs): Update stream handbook link (#2711) --- docs/writing-a-plugin/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/writing-a-plugin/README.md b/docs/writing-a-plugin/README.md index bcd708356..bf2b54b61 100644 --- a/docs/writing-a-plugin/README.md +++ b/docs/writing-a-plugin/README.md @@ -193,7 +193,7 @@ if (someCondition) { If you're unfamiliar with streams, you will need to read up on them: -* https://github.com/substack/stream-handbook (a MUST read) +* https://www.freecodecamp.org/news/node-js-streams-everything-you-need-to-know-c9141306be93/ * https://nodejs.org/api/stream.html Other libraries that are not file manipulating through streams but are made for use with gulp are tagged with the [gulpfriendly](https://npmjs.org/browse/keyword/gulpfriendly) keyword on npm. From 72668c61e445c81fad23bc6ed24967a3238a648d Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sun, 24 Mar 2024 17:43:12 -0700 Subject: [PATCH 42/45] chore!: Normalize repository, dropping node <10.13 support (#2758) feat: Support `.cjs` extension for gulpfiles fix: Ensure watch does not trigger on negated globs fix: Ensure watch allows japanese characters in globs --- .ci/.azure-pipelines-steps.yml | 38 ---------- .ci/.azure-pipelines.yml | 90 ------------------------ .github/workflows/dev.yml | 75 ++++++++++++++++++++ .github/workflows/release.yml | 16 +++++ .npmrc | 1 + .prettierignore | 3 + .travis.yml | 12 ---- LICENSE | 2 +- README.md | 75 ++++---------------- appveyor.yml | 26 ------- package.json | 39 +++++----- test/.eslintrc | 3 - test/.gitkeep | 0 test/dest.js | 48 +++++++------ test/fixtures/gulpfiles/cjs/gulpfile.cjs | 3 + test/index.test.js | 36 +++++++--- test/src.js | 52 +++++++------- test/watch.js | 79 +++++++++++++++++---- 18 files changed, 279 insertions(+), 319 deletions(-) delete mode 100644 .ci/.azure-pipelines-steps.yml delete mode 100644 .ci/.azure-pipelines.yml create mode 100644 .github/workflows/dev.yml create mode 100644 .github/workflows/release.yml create mode 100644 .npmrc create mode 100644 .prettierignore delete mode 100644 .travis.yml delete mode 100644 appveyor.yml delete mode 100644 test/.eslintrc create mode 100644 test/.gitkeep create mode 100644 test/fixtures/gulpfiles/cjs/gulpfile.cjs diff --git a/.ci/.azure-pipelines-steps.yml b/.ci/.azure-pipelines-steps.yml deleted file mode 100644 index 894c21eee..000000000 --- a/.ci/.azure-pipelines-steps.yml +++ /dev/null @@ -1,38 +0,0 @@ -steps: -- script: npm i -g npm@$(npm_version) - displayName: Use legacy npm version $(npm_version) - condition: ne(variables['npm_version'], '') - -- task: NodeTool@0 - inputs: - versionSpec: '$(node_version)' - displayName: Use Node $(node_version) - -- script: npm install - displayName: npm install - -- script: npm test - displayName: Run tests - -- script: npm run coveralls - displayName: Run coveralls - env: - # Pretend to be AppVeyor for now - APPVEYOR: true - APPVEYOR_BUILD_NUMBER: $(Build.BuildNumber) - APPVEYOR_BUILD_ID: $(Agent.OS)_$(node_version) - APPVEYOR_REPO_COMMIT: $(Build.SourceVersion) - APPVEYOR_REPO_BRANCH: $(Build.SourceBranchName) - # Overwrite the AppVeyor Service Name - COVERALLS_SERVICE_NAME: Azure Pipelines - COVERALLS_REPO_TOKEN: $(COVERALLS_REPO_TOKEN_SECRET) - COVERALLS_PARALLEL: true - CI_PULL_REQUEST: $(System.PullRequest.PullRequestNumber) - -- script: npm run azure-pipelines - displayName: Write tests to xml - -- task: PublishTestResults@2 - inputs: - testResultsFiles: '**/test.xunit' - condition: succeededOrFailed() diff --git a/.ci/.azure-pipelines.yml b/.ci/.azure-pipelines.yml deleted file mode 100644 index 2d717af1b..000000000 --- a/.ci/.azure-pipelines.yml +++ /dev/null @@ -1,90 +0,0 @@ -trigger: -- master -- releases/* - -jobs: - - job: Test_Linux - displayName: Run Tests on Linux - pool: - vmImage: "Ubuntu 16.04" - strategy: - matrix: - Node_v12: - node_version: 12 - Node_v10: - node_version: 10 - Node_v8: - node_version: 8 - Node_v6: - node_version: 6 - Node_v4: - node_version: 4 - Node_v0_12: - node_version: 0.12 - Node_v0_10: - node_version: 0.10 - steps: - - template: .azure-pipelines-steps.yml - - - job: Test_Windows - displayName: Run Tests on Windows - pool: - vmImage: vs2017-win2016 - strategy: - matrix: - Node_v12: - node_version: 12 - Node_v10: - node_version: 10 - Node_v8: - node_version: 8 - Node_v6: - node_version: 6 - Node_v4: - node_version: 4 - npm_version: 2 - Node_v0_12: - node_version: 0.12 - npm_version: 2 - Node_v0_10: - node_version: 0.10 - npm_version: 2 - steps: - - template: .azure-pipelines-steps.yml - - - job: Test_MacOS - displayName: Run Tests on MacOS - pool: - vmImage: macos-10.13 - strategy: - matrix: - Node_v12: - node_version: 12 - Node_v10: - node_version: 10 - Node_v8: - node_version: 8 - Node_v6: - node_version: 6 - Node_v4: - node_version: 4 - Node_v0_12: - node_version: 0.12 - Node_v0_10: - node_version: 0.10 - steps: - - template: .azure-pipelines-steps.yml - - - job: Notify_Coveralls - displayName: Notify Coveralls that the parallel report is done - pool: - vmImage: "Ubuntu 16.04" - dependsOn: - - Test_Linux - - Test_Windows - - Test_MacOS - steps: - - script: curl -k https://coveralls.io/webhook?repo_token=$COVERALLS_REPO_TOKEN -d "payload[build_num]=$BUILD_NAME&payload[status]=done" - env: - COVERALLS_REPO_TOKEN: $(COVERALLS_REPO_TOKEN_SECRET) - BUILD_NAME: $(Build.BuildNumber) diff --git a/.github/workflows/dev.yml b/.github/workflows/dev.yml new file mode 100644 index 000000000..3b07263a5 --- /dev/null +++ b/.github/workflows/dev.yml @@ -0,0 +1,75 @@ +name: dev +on: + pull_request: + push: + branches: + - master + - main +env: + CI: true + +jobs: + prettier: + name: Format code + runs-on: ubuntu-latest + if: ${{ github.event_name == 'push' }} + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Prettier + uses: gulpjs/prettier_action@v3.0 + with: + commit_message: 'chore: Run prettier' + prettier_options: '--write .' + + test: + name: Tests for Node ${{ matrix.node }} on ${{ matrix.os }} + runs-on: ${{ matrix.os }} + + strategy: + fail-fast: false + matrix: + node: [10, 12, 14, 16] + os: [ubuntu-latest, windows-latest, macos-latest] + + steps: + - name: Clone repository + uses: actions/checkout@v2 + + - name: Set Node.js version + uses: actions/setup-node@v2 + with: + node-version: ${{ matrix.node }} + + - run: node --version + - run: npm --version + + - name: Install npm dependencies + run: npm install + + - name: Run lint + run: npm run lint + + - name: Run tests + run: npm test + + - name: Coveralls + uses: coverallsapp/github-action@v1.1.2 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + flag-name: ${{matrix.os}}-node-${{ matrix.node }} + parallel: true + + coveralls: + needs: test + name: Finish up + + runs-on: ubuntu-latest + steps: + - name: Coveralls Finished + uses: coverallsapp/github-action@v1.1.2 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + parallel-finished: true diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..87cd13c01 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,16 @@ +name: release +on: + push: + branches: + - master + - main + +jobs: + release-please: + runs-on: ubuntu-latest + steps: + - uses: GoogleCloudPlatform/release-please-action@v2 + with: + token: ${{ secrets.GITHUB_TOKEN }} + release-type: node + package-name: release-please-action diff --git a/.npmrc b/.npmrc new file mode 100644 index 000000000..43c97e719 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +package-lock=false diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 000000000..c96ebe0c9 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,3 @@ +coverage/ +.nyc_output/ +CHANGELOG.md diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index eda5b0009..000000000 --- a/.travis.yml +++ /dev/null @@ -1,12 +0,0 @@ -sudo: false -language: node_js -node_js: - - '12' - - '10' - - '8' - - '6' - - '4' - - '0.12' - - '0.10' -after_script: - - npm run coveralls diff --git a/LICENSE b/LICENSE index 6a29df97f..7980c1d40 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2013-2018 Blaine Bublitz , Eric Schoffstall and other contributors +Copyright (c) 2013-2024 Blaine Bublitz and Eric Schoffstall Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 162f1bee5..b8b66b504 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,7 @@

The streaming build system

-[![NPM version][npm-image]][npm-url] [![Downloads][downloads-image]][npm-url] [![Azure Pipelines Build Status][azure-pipelines-image]][azure-pipelines-url] [![Build Status][travis-image]][travis-url] [![AppVeyor Build Status][appveyor-image]][appveyor-url] [![Coveralls Status][coveralls-image]][coveralls-url] [![OpenCollective Backers][backer-badge]][backer-url] [![OpenCollective Sponsors][sponsor-badge]][sponsor-url] [![Gitter chat][gitter-image]][gitter-url] - +[![NPM version][npm-image]][npm-url] [![Downloads][downloads-image]][npm-url] [![Build Status][ci-image]][ci-url] [![Coveralls Status][coveralls-image]][coveralls-url] ## What is gulp? @@ -15,25 +14,6 @@ - **Strong Ecosystem** - Use npm modules to do anything you want + over 3000 curated plugins for streaming file transformations. - **Simple** - By providing only a minimal API surface, gulp is easy to learn and simple to use. -## What's new in 4.0?! - -* The task system was rewritten from the ground-up, allowing task composition using `series()` and `parallel()` methods. -* The watcher was updated, now using chokidar (no more need for gulp-watch!), with feature parity to our task system. -* First-class support was added for incremental builds using `lastRun()`. -* A `symlink()` method was exposed to create symlinks instead of copying files. -* Built-in support for sourcemaps was added - the gulp-sourcemaps plugin is no longer necessary! -* Task registration of exported functions - using node or ES exports - is now recommended. -* Custom registries were designed, allowing for shared tasks or augmented functionality. -* Stream implementations were improved, allowing for better conditional and phased builds. - - -## gulp for enterprise - -Available as part of the Tidelift Subscription - -The maintainers of gulp and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/npm-gulp?utm_source=npm-gulp&utm_medium=referral&utm_campaign=enterprise&utm_term=repo) - - ## Installation Follow our [Quick Start guide][quick-start]. @@ -246,48 +226,21 @@ for a second time. Anyone can help make this project better - check out our [Contributing guide](/CONTRIBUTING.md)! -## Backers - -Support us with a monthly donation and help us continue our activities. - -[![Backers][backers-image]][support-url] - -## Sponsors - -Become a sponsor to get your logo on our README on Github. - -[![Sponsors][sponsors-image]][support-url] + +[quick-start]: https://gulpjs.com/docs/en/getting-started/quick-start +[getting-started-guide]: https://gulpjs.com/docs/en/getting-started/quick-start +[api-docs]: https://gulpjs.com/docs/en/api/concepts +[esm-module]: https://github.com/standard-things/esm + -[downloads-image]: https://img.shields.io/npm/dm/gulp.svg + +[downloads-image]: https://img.shields.io/npm/dm/gulp.svg?style=flat-square [npm-url]: https://www.npmjs.com/package/gulp -[npm-image]: https://img.shields.io/npm/v/gulp.svg - -[azure-pipelines-url]: https://dev.azure.com/gulpjs/gulp/_build/latest?definitionId=1&branchName=master -[azure-pipelines-image]: https://dev.azure.com/gulpjs/gulp/_apis/build/status/gulp?branchName=master +[npm-image]: https://img.shields.io/npm/v/gulp.svg?style=flat-square -[travis-url]: https://travis-ci.org/gulpjs/gulp -[travis-image]: https://img.shields.io/travis/gulpjs/gulp.svg?label=travis-ci - -[appveyor-url]: https://ci.appveyor.com/project/gulpjs/gulp -[appveyor-image]: https://img.shields.io/appveyor/ci/gulpjs/gulp.svg?label=appveyor +[ci-url]: https://github.com/gulpjs/gulp/actions?query=workflow:dev +[ci-image]: https://img.shields.io/github/actions/workflow/status/gulpjs/gulp/dev.yml?branch=master&style=flat-square [coveralls-url]: https://coveralls.io/r/gulpjs/gulp -[coveralls-image]: https://img.shields.io/coveralls/gulpjs/gulp/master.svg - -[gitter-url]: https://gitter.im/gulpjs/gulp -[gitter-image]: https://badges.gitter.im/gulpjs/gulp.svg - -[backer-url]: #backers -[backer-badge]: https://opencollective.com/gulpjs/backers/badge.svg?color=blue -[sponsor-url]: #sponsors -[sponsor-badge]: https://opencollective.com/gulpjs/sponsors/badge.svg?color=blue - -[support-url]: https://opencollective.com/gulpjs#support - -[backers-image]: https://opencollective.com/gulpjs/backers.svg -[sponsors-image]: https://opencollective.com/gulpjs/sponsors.svg - -[quick-start]: https://gulpjs.com/docs/en/getting-started/quick-start -[getting-started-guide]: https://gulpjs.com/docs/en/getting-started/quick-start -[api-docs]: https://gulpjs.com/docs/en/api/concepts -[esm-module]: https://github.com/standard-things/esm +[coveralls-image]: https://img.shields.io/coveralls/gulpjs/gulp/master.svg?style=flat-square + diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index d8845d71e..000000000 --- a/appveyor.yml +++ /dev/null @@ -1,26 +0,0 @@ -# https://www.appveyor.com/docs/appveyor-yml -# https://www.appveyor.com/docs/lang/nodejs-iojs - -environment: - matrix: - # node.js - - nodejs_version: "0.10" - - nodejs_version: "0.12" - - nodejs_version: "4" - - nodejs_version: "6" - - nodejs_version: "8" - - nodejs_version: "10" - -install: - - ps: Install-Product node $env:nodejs_version - - npm install - -test_script: - - node --version - - npm --version - - cmd: npm test - -build: off - -# build version format -version: "{build}" diff --git a/package.json b/package.json index 256684af3..b335a1340 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "repository": "gulpjs/gulp", "license": "MIT", "engines": { - "node": ">= 0.10" + "node": ">=10.13.0" }, "main": "index.js", "files": [ @@ -25,25 +25,32 @@ "scripts": { "lint": "eslint .", "pretest": "npm run lint", - "test": "nyc mocha --async-only", - "azure-pipelines": "nyc mocha --async-only --reporter xunit -O output=test.xunit", - "coveralls": "nyc report --reporter=text-lcov | coveralls" + "test": "nyc mocha --async-only" }, "dependencies": { - "glob-watcher": "^5.0.3", - "gulp-cli": "^2.2.0", - "undertaker": "^1.2.1", - "vinyl-fs": "^3.0.0" + "glob-watcher": "^6.0.0", + "gulp-cli": "^3.0.0", + "undertaker": "^2.0.0", + "vinyl-fs": "^4.0.0" }, "devDependencies": { - "coveralls": "github:phated/node-coveralls#2.x", - "eslint": "^2.13.1", - "eslint-config-gulp": "^3.0.1", - "expect": "^1.20.2", - "mkdirp": "^0.5.1", - "mocha": "^3.0.0", - "nyc": "^10.3.2", - "rimraf": "^2.6.3" + "eslint": "^7.0.0", + "eslint-config-gulp": "^5.0.0", + "eslint-plugin-node": "^11.1.0", + "expect": "^27.0.0", + "mkdirp": "^3.0.1", + "mocha": "^8.0.0", + "nyc": "^15.0.0", + "rimraf": "^3.0.0" + }, + "nyc": { + "reporter": [ + "lcov", + "text-summary" + ] + }, + "prettier": { + "singleQuote": true }, "keywords": [ "build", diff --git a/test/.eslintrc b/test/.eslintrc deleted file mode 100644 index 06b940f7d..000000000 --- a/test/.eslintrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": "gulp/test" -} diff --git a/test/.gitkeep b/test/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/test/dest.js b/test/dest.js index 3dbba4600..16c58d213 100644 --- a/test/dest.js +++ b/test/dest.js @@ -16,8 +16,8 @@ describe('gulp.dest()', function() { it('should return a stream', function(done) { var stream = gulp.dest(path.join(__dirname, './fixtures/')); - expect(stream).toExist(); - expect(stream.on).toExist(); + expect(stream).toBeDefined(); + expect(stream.on).toBeDefined(); done(); }); @@ -26,20 +26,22 @@ describe('gulp.dest()', function() { var outstream = gulp.dest(outpath); instream.pipe(outstream); + var expectedContents = Buffer.from('this is a test'); + outstream.on('error', done); outstream.on('data', function(file) { // Data should be re-emitted right - expect(file).toExist(); - expect(file.path).toExist(); - expect(file.contents).toExist(); + expect(file).toBeDefined(); + expect(file.path).toBeDefined(); + expect(file.contents).toBeDefined(); expect(file.path).toEqual(path.join(outpath, './copy/example.txt')); - expect(file.contents).toEqual('this is a test'); + expect(file.contents).toEqual(expectedContents); }); outstream.on('end', function() { fs.readFile(path.join(outpath, 'copy', 'example.txt'), function(err, contents) { - expect(err).toNotExist(); - expect(contents).toExist(); - expect(contents).toEqual('this is a test'); + expect(err).toBeNull(); + expect(contents).toBeDefined(); + expect(contents).toEqual(expectedContents); done(); }); }); @@ -53,15 +55,15 @@ describe('gulp.dest()', function() { outstream.on('error', done); outstream.on('data', function(file) { // Data should be re-emitted right - expect(file).toExist(); - expect(file.path).toExist(); - expect(file.contents).toNotExist(); + expect(file).toBeDefined(); + expect(file.path).toBeDefined(); + expect(file.contents).toBeNull(); expect(file.path).toEqual(path.join(outpath, './copy/example.txt')); }); outstream.on('end', function() { fs.readFile(path.join(outpath, 'copy', 'example.txt'), function(err, contents) { - expect(err).toExist(); - expect(contents).toNotExist(); + expect(err).toBeDefined(); + expect(contents).toBeUndefined(); done(); }); }); @@ -74,16 +76,16 @@ describe('gulp.dest()', function() { outstream.on('error', done); outstream.on('data', function(file) { // Data should be re-emitted right - expect(file).toExist(); - expect(file.path).toExist(); - expect(file.contents).toExist(); + expect(file).toBeDefined(); + expect(file.path).toBeDefined(); + expect(file.contents).toBeDefined(); expect(file.path).toEqual(path.join(outpath, './copy/example.txt')); }); outstream.on('end', function() { fs.readFile(path.join(outpath, 'copy', 'example.txt'), function(err, contents) { - expect(err).toNotExist(); - expect(contents).toExist(); - expect(contents).toEqual('this is a test'); + expect(err).toBeNull(); + expect(contents).toBeDefined(); + expect(contents).toEqual(Buffer.from('this is a test')); done(); }); }); @@ -112,13 +114,13 @@ describe('gulp.dest()', function() { outstream.on('error', done); outstream.on('data', function(file) { // Data should be re-emitted right - expect(file).toExist(); - expect(file.path).toExist(); + expect(file).toBeDefined(); + expect(file.path).toBeDefined(); expect(file.path).toEqual(path.join(outpath, './stuff')); }); outstream.on('end', function() { fs.exists(path.join(outpath, 'stuff'), function(exists) { - expect(exists).toExist(); + expect(exists).toBeDefined(); done(); }); }); diff --git a/test/fixtures/gulpfiles/cjs/gulpfile.cjs b/test/fixtures/gulpfiles/cjs/gulpfile.cjs new file mode 100644 index 000000000..b7e1a2d35 --- /dev/null +++ b/test/fixtures/gulpfiles/cjs/gulpfile.cjs @@ -0,0 +1,3 @@ +exports.default = function (done) { + done() +} diff --git a/test/index.test.js b/test/index.test.js index 8921084d8..0e8b65fb0 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -1,5 +1,8 @@ 'use strict'; +var cp = require('child_process'); +var path = require('path'); + var expect = require('expect'); var gulp = require('../'); @@ -8,52 +11,65 @@ describe('gulp', function() { describe('hasOwnProperty', function() { it('src', function(done) { - expect(gulp.hasOwnProperty('src')).toEqual(true); + expect(Object.prototype.hasOwnProperty.call(gulp, 'src')).toEqual(true); done(); }); it('dest', function(done) { - expect(gulp.hasOwnProperty('dest')).toEqual(true); + expect(Object.prototype.hasOwnProperty.call(gulp, 'dest')).toEqual(true); done(); }); it('symlink', function(done) { - expect(gulp.hasOwnProperty('symlink')).toEqual(true); + expect(Object.prototype.hasOwnProperty.call(gulp, 'symlink')).toEqual(true); done(); }); it('watch', function(done) { - expect(gulp.hasOwnProperty('watch')).toEqual(true); + expect(Object.prototype.hasOwnProperty.call(gulp, 'watch')).toEqual(true); done(); }); it('task', function(done) { - expect(gulp.hasOwnProperty('task')).toEqual(true); + expect(Object.prototype.hasOwnProperty.call(gulp, 'task')).toEqual(true); done(); }); it('series', function(done) { - expect(gulp.hasOwnProperty('series')).toEqual(true); + expect(Object.prototype.hasOwnProperty.call(gulp, 'series')).toEqual(true); done(); }); it('parallel', function(done) { - expect(gulp.hasOwnProperty('parallel')).toEqual(true); + expect(Object.prototype.hasOwnProperty.call(gulp, 'parallel')).toEqual(true); done(); }); it('tree', function(done) { - expect(gulp.hasOwnProperty('tree')).toEqual(true); + expect(Object.prototype.hasOwnProperty.call(gulp, 'tree')).toEqual(true); done(); }); it('lastRun', function(done) { - expect(gulp.hasOwnProperty('lastRun')).toEqual(true); + expect(Object.prototype.hasOwnProperty.call(gulp, 'lastRun')).toEqual(true); done(); }); it('registry', function(done) { - expect(gulp.hasOwnProperty('registry')).toEqual(true); + expect(Object.prototype.hasOwnProperty.call(gulp, 'registry')).toEqual(true); + done(); + }); + }); + + it('can run against gulpfile.cjs', function (done) { + this.timeout(5000); + + var cli = path.join(__dirname, '../bin/gulp.js'); + var opts = { cwd: path.join(__dirname, 'fixtures/gulpfiles/cjs' ) }; + cp.exec('node ' + cli, opts, function (err, stdout, stderr) { + expect(err).toBeNull(); + expect(stdout).toMatch('gulpfile.cjs'); + expect(stderr).toEqual(''); done(); }); }); diff --git a/test/src.js b/test/src.js index 4ec1df962..82501e73e 100644 --- a/test/src.js +++ b/test/src.js @@ -9,19 +9,20 @@ var gulp = require('../'); describe('gulp.src()', function() { it('should return a stream', function(done) { var stream = gulp.src('./fixtures/*.coffee', { cwd: __dirname }); - expect(stream).toExist(); - expect(stream.on).toExist(); + expect(stream).toBeDefined(); + expect(stream.on).toBeDefined(); done(); }); + it('should return a input stream from a flat glob', function(done) { var stream = gulp.src('./fixtures/*.coffee', { cwd: __dirname }); stream.on('error', done); stream.on('data', function(file) { - expect(file).toExist(); - expect(file.path).toExist(); - expect(file.contents).toExist(); + expect(file).toBeDefined(); + expect(file.path).toBeDefined(); + expect(file.contents).toBeDefined(); expect(file.path).toEqual(path.join(__dirname, './fixtures/test.coffee')); - expect(file.contents).toEqual('this is a test'); + expect(file.contents).toEqual(Buffer.from('this is a test')); }); stream.on('end', function() { done(); @@ -38,8 +39,8 @@ describe('gulp.src()', function() { var files = []; stream.on('error', done); stream.on('data', function(file) { - expect(file).toExist(); - expect(file.path).toExist(); + expect(file).toBeDefined(); + expect(file.path).toBeDefined(); files.push(file); }); stream.on('end', function() { @@ -61,8 +62,8 @@ describe('gulp.src()', function() { var files = []; stream.on('error', done); stream.on('data', function(file) { - expect(file).toExist(); - expect(file.path).toExist(); + expect(file).toBeDefined(); + expect(file.path).toBeDefined(); files.push(file); }); stream.on('end', function() { @@ -76,22 +77,23 @@ describe('gulp.src()', function() { var stream = gulp.src('./fixtures/*.coffee', { read: false, cwd: __dirname }); stream.on('error', done); stream.on('data', function(file) { - expect(file).toExist(); - expect(file.path).toExist(); - expect(file.contents).toNotExist(); + expect(file).toBeDefined(); + expect(file.path).toBeDefined(); + expect(file.contents).toBeNull(); expect(file.path).toEqual(path.join(__dirname, './fixtures/test.coffee')); }); stream.on('end', function() { done(); }); }); + it('should return a input stream with contents as stream when buffer is false', function(done) { var stream = gulp.src('./fixtures/*.coffee', { buffer: false, cwd: __dirname }); stream.on('error', done); stream.on('data', function(file) { - expect(file).toExist(); - expect(file.path).toExist(); - expect(file.contents).toExist(); + expect(file).toBeDefined(); + expect(file.path).toBeDefined(); + expect(file.contents).toBeDefined(); var buf = ''; file.contents.on('data', function(d) { buf += d; @@ -103,20 +105,22 @@ describe('gulp.src()', function() { expect(file.path).toEqual(path.join(__dirname, './fixtures/test.coffee')); }); }); + it('should return a input stream from a deep glob', function(done) { var stream = gulp.src('./fixtures/**/*.jade', { cwd: __dirname }); stream.on('error', done); stream.on('data', function(file) { - expect(file).toExist(); - expect(file.path).toExist(); - expect(file.contents).toExist(); + expect(file).toBeDefined(); + expect(file.path).toBeDefined(); + expect(file.contents).toBeDefined(); expect(file.path).toEqual(path.join(__dirname, './fixtures/test/run.jade')); - expect(file.contents).toEqual('test template'); + expect(file.contents).toEqual(Buffer.from('test template')); }); stream.on('end', function() { done(); }); }); + it('should return a input stream from a deeper glob', function(done) { var stream = gulp.src('./fixtures/**/*.dmc', { cwd: __dirname }); var a = 0; @@ -136,11 +140,11 @@ describe('gulp.src()', function() { stream.on('error', done); stream.on('data', function(file) { ++a; - expect(file).toExist(); - expect(file.path).toExist(); - expect(file.contents).toExist(); + expect(file).toBeDefined(); + expect(file.path).toBeDefined(); + expect(file.contents).toBeDefined(); expect(file.path).toEqual(path.join(__dirname, './fixtures/test.coffee')); - expect(file.contents).toEqual('this is a test'); + expect(file.contents).toEqual(Buffer.from('this is a test')); }); stream.on('end', function() { expect(a).toEqual(1); diff --git a/test/watch.js b/test/watch.js index 0ac076d23..eab1ec011 100644 --- a/test/watch.js +++ b/test/watch.js @@ -7,7 +7,7 @@ var path = require('path'); var expect = require('expect'); var rimraf = require('rimraf'); -var mkdirp = require('mkdirp'); +var mkdirp = require('mkdirp').mkdirp; var gulp = require('../'); @@ -25,10 +25,22 @@ function updateTempFile(path) { }, 125); } +function removeTempFile(path) { + setTimeout(function() { + fs.unlinkSync(path); + }, 125); +} + describe('gulp.watch()', function() { - beforeEach(rimraf.bind(null, outpath)); - beforeEach(mkdirp.bind(null, outpath)); - afterEach(rimraf.bind(null, outpath)); + beforeEach(function (done) { + rimraf(outpath, done); + }); + beforeEach(function () { + return mkdirp(outpath); + }); + afterEach(function (done) { + rimraf(outpath, done); + }); it('should call the function when file changes: no options', function(done) { var tempFile = path.join(outpath, 'watch-func.txt'); @@ -83,15 +95,18 @@ describe('gulp.watch()', function() { createTempFile(tempFile); - var watcher = gulp.watch('watch-func.txt', { cwd: outpath }, function() { - // TODO: proper fail here - expect('Watcher erroneously called'); - }); - setTimeout(function() { - watcher.close(); - done(); - }, 10); + // Chokidar seems to pick up the file we just created, so we wait briefly before setup + // I wonder if node hasn't fully flushed the file or something... + var watcher = gulp.watch('watch-func.txt', { cwd: outpath }, function() { + done(new Error('should not each here!')); + }); + + setTimeout(function () { + watcher.close(); + done(); + }, 1000); + }, 250); }); it('should call the function when file changes: w/ options', function(done) { @@ -108,6 +123,40 @@ describe('gulp.watch()', function() { updateTempFile(tempFile); }); + it('should call the function when file changes at a path with japanese characters', function(done) { + var japaneseDir = path.join(outpath, 'フォルダ'); + + fs.mkdirSync(japaneseDir); + + var tempFile = path.join(japaneseDir, 'foobar.txt'); + + createTempFile(tempFile); + + var watcher = gulp.watch('フォルダ/*', { cwd: outpath }, function(cb) { + watcher.close(); + cb(); + done(); + }); + + updateTempFile(tempFile); + }); + + it('should not call the function when ignored file changes', function(done) { + var tempFile = path.join(outpath, 'ignored.txt'); + + createTempFile(tempFile); + + var watcher = gulp.watch(['*', '!ignored.txt'], { cwd: outpath }, function() { + done(new Error('should not each here!')); + }); + + removeTempFile(tempFile); + setTimeout(function () { + watcher.close(); + done(); + }, 1000); + }); + it('should not drop options when no callback specified', function(done) { var tempFile = path.join(outpath, 'watch-func-nodrop-options.txt'); // By passing a cwd option, ensure options are not lost to gaze @@ -118,7 +167,7 @@ describe('gulp.watch()', function() { var watcher = gulp.watch(relFile, { cwd: cwd }) .on('change', function(filepath) { - expect(filepath).toExist(); + expect(filepath).toBeDefined(); expect(path.resolve(cwd, filepath)).toEqual(path.resolve(tempFile)); watcher.close(); done(); @@ -128,8 +177,8 @@ describe('gulp.watch()', function() { }); it('should work without options or callback', function(done) { - // TODO: check we return watcher? - gulp.watch('x'); + var watcher = gulp.watch('x'); + watcher.close(); done(); }); From b00de681f5ef6ade283d544f62f770f6b27a9e52 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Mon, 25 Mar 2024 07:47:55 -0700 Subject: [PATCH 43/45] feat: Provide an ESM export (#2760) --- README.md | 32 +++++++----------------- index.mjs | 16 ++++++++++++ package.json | 6 +++++ test/fixtures/gulpfiles/mjs/gulpfile.mjs | 30 ++++++++++++++++++++++ test/index.test.js | 18 +++++++++++++ 5 files changed, 79 insertions(+), 23 deletions(-) create mode 100644 index.mjs create mode 100644 test/fixtures/gulpfiles/mjs/gulpfile.mjs diff --git a/README.md b/README.md index b8b66b504..96d62a676 100644 --- a/README.md +++ b/README.md @@ -112,26 +112,12 @@ exports.default = build; ## Use latest JavaScript version in your gulpfile -__Most new versions of node support most features that Babel provides, except the `import`/`export` syntax. When only that syntax is desired, rename to `gulpfile.esm.js`, install the [esm][esm-module] module, and skip the Babel portion below.__ +Gulp provides a wrapper that will be loaded in your ESM code, so you can name your gulpfile as `gulpfile.mjs` or with `"type": "module"` specified in your `package.json` file. -Node already supports a lot of __ES2015+__ features, but to avoid compatibility problems we suggest to install Babel and rename your `gulpfile.js` to `gulpfile.babel.js`. - -```sh -npm install --save-dev @babel/register @babel/core @babel/preset-env -``` - -Then create a **.babelrc** file with the preset configuration. - -```js -{ - "presets": [ "@babel/preset-env" ] -} -``` - -And here's the same sample from above written in **ES2015+**. +And here's the same sample from above written in **ESNext**. ```js -import gulp from 'gulp'; +import { src, dest, watch } from 'gulp'; import less from 'gulp-less'; import babel from 'gulp-babel'; import concat from 'gulp-concat'; @@ -160,7 +146,7 @@ export const clean = () => del([ 'assets' ]); * You can also declare named functions and export them as tasks */ export function styles() { - return gulp.src(paths.styles.src) + return src(paths.styles.src) .pipe(less()) .pipe(cleanCSS()) // pass in options to the stream @@ -168,23 +154,23 @@ export function styles() { basename: 'main', suffix: '.min' })) - .pipe(gulp.dest(paths.styles.dest)); + .pipe(dest(paths.styles.dest)); } export function scripts() { - return gulp.src(paths.scripts.src, { sourcemaps: true }) + return src(paths.scripts.src, { sourcemaps: true }) .pipe(babel()) .pipe(uglify()) .pipe(concat('main.min.js')) - .pipe(gulp.dest(paths.scripts.dest)); + .pipe(dest(paths.scripts.dest)); } /* * You could even use `export as` to rename exported tasks */ function watchFiles() { - gulp.watch(paths.scripts.src, scripts); - gulp.watch(paths.styles.src, styles); + watch(paths.scripts.src, scripts); + watch(paths.styles.src, styles); } export { watchFiles as watch }; diff --git a/index.mjs b/index.mjs new file mode 100644 index 000000000..f1d808dd7 --- /dev/null +++ b/index.mjs @@ -0,0 +1,16 @@ +import gulp from "./index.js"; + +// These are bound to the gulp instance in our CommonJS file +// so it is okay to reassign them to export +export const watch = gulp.watch; +export const task = gulp.task; +export const series = gulp.series; +export const parallel = gulp.parallel; +export const registry = gulp.registry; +export const tree = gulp.tree; +export const lastRun = gulp.lastRun; +export const src = gulp.src; +export const dest = gulp.dest; +export const symlink = gulp.symlink; + +export default gulp; diff --git a/package.json b/package.json index b335a1340..5d2a668a6 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,12 @@ "node": ">=10.13.0" }, "main": "index.js", + "exports": { + ".": { + "import": "./index.mjs", + "require": "./index.js" + } + }, "files": [ "LICENSE", "index.js", diff --git a/test/fixtures/gulpfiles/mjs/gulpfile.mjs b/test/fixtures/gulpfiles/mjs/gulpfile.mjs new file mode 100644 index 000000000..332e027c9 --- /dev/null +++ b/test/fixtures/gulpfiles/mjs/gulpfile.mjs @@ -0,0 +1,30 @@ +import assert from "assert"; +import EventEmitter from "events"; + +import gulp, { + watch, + task, + series, + parallel, + registry, + tree, + lastRun, + src, + dest, + symlink, +} from 'gulp'; + +export default function (done) { + assert(typeof watch === 'function'); + assert(typeof task === 'function'); + assert(typeof series === 'function'); + assert(typeof parallel === 'function'); + assert(typeof registry === 'function'); + assert(typeof tree === 'function'); + assert(typeof lastRun === 'function'); + assert(typeof src === 'function'); + assert(typeof dest === 'function'); + assert(typeof symlink === 'function'); + assert(gulp instanceof EventEmitter); + done(); +} diff --git a/test/index.test.js b/test/index.test.js index 0e8b65fb0..de5f68c4f 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -73,4 +73,22 @@ describe('gulp', function() { done(); }); }); + + it('can run against gulpfile.mjs', function (done) { + // Node v10 didn't support `exports` in package.json + if (process.version.startsWith('v10.')) { + this.skip(); + } + + this.timeout(5000); + + var cli = path.join(__dirname, '../bin/gulp.js'); + var opts = { cwd: path.join(__dirname, 'fixtures/gulpfiles/mjs' ) }; + cp.exec('node ' + cli, opts, function (err, stdout, stderr) { + expect(err).toBeNull(); + expect(stdout).toMatch('gulpfile.mjs'); + expect(stderr).toEqual(''); + done(); + }); + }); }); From bf72116c5d5f613836b392fb83633ea6c14f3a65 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Thu, 28 Mar 2024 19:49:51 -0700 Subject: [PATCH 44/45] chore: Add index.mjs to files list --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 5d2a668a6..2596c6084 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "files": [ "LICENSE", "index.js", + "index.mjs", "bin" ], "bin": { From 5c4c5473c5582a8e4495c695ecd93b13f0852cbd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 28 Mar 2024 19:56:40 -0700 Subject: [PATCH 45/45] chore: Release 5.0.0 (#2762) chore: Update changelog for all subprojects (#2763) --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Blaine Bublitz --- CHANGELOG.md | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 2 +- 2 files changed, 104 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d6555dedd..d712e881b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,108 @@ # gulp changelog +## [5.0.0](https://www.github.com/gulpjs/gulp/compare/v4.0.2...v5.0.0) (2024-03-29) + +We've tried to provide a high-level changelog for gulp v5 below, but it +doesn't contain all changes from the 60+ dependencies that we maintain. + +Please see [individual changelogs](#individual-changelogs) to drill down +into all changes that were made. + +### ⚠ BREAKING CHANGES + +* Drop support for Node.js <10.13 +* Default stream encoding to UTF-8 +* Standardized on `anymatch` library for globbing paths. All globs should work the same between `src` and `watch` now! +* Removed support for ordered globs. This aligns with the chokidar globbing implementation. If you need your globs to be ordered, you can use `ordered-read-stream` +* All globs and paths are normalized to unix-like filepaths +* Only allow JS variants for `.gulp.*` config files +* Removed support for alpha releases of v4 from `gulp-cli` +* Removed the `--verify` flag +* Renamed the `--require` flag to `--preload` to avoid conflicting with Node.js flags +* Removed many legacy and deprecated loaders +* Upgrade to chokidar v3 +* Clone `Vinyl` objects with stream contents using `teex`, but no longer wait for all streams to flow before cloned streams will receive data +* Stop using `process.umask()` to make directories, instead falling back to Node's default mode +* Throw on non-function, non-string option coercers +* Drop support of Node.js snake_case flags +* Use a Symbol for attaching the `gulplog` namespace to the store +* Use a Symbol for attaching the `gulplog` store to the global +* Use sha256 to hash the `v8flags` cache into a filename + +### Features + +* Streamlined the dependency tree +* Switch all streams implementation to Streamx +* Rewrote `glob-stream` to use a custom directory walk that relies on newer Node.js features and is more performant than old implementation +* Implement translation support for all CLI messages and all messages passing through gulplog +* Allow users to customize or remove the timestamp from their logs +* Upgraded gulplog to v2. Messages logged via v1 will also display a deprecated warning. Plugins should update to v2 as the community upgrades to gulp 5 +* Added support for `gulpile.cjs` and `gulpfile.mjs` +* Add support for `swc`, `esbuild`, `sucrase`, and `mdx` loaders +* Provide an ESM export ([#2760](https://www.github.com/gulpjs/gulp/issues/2760)) ([b00de68](https://www.github.com/gulpjs/gulp/commit/b00de681f5ef6ade283d544f62f770f6b27a9e52)) +* Support sourcemap handling on streaming `Vinyl` contents +* Support `extends` syntax for `.gulp.*` config file +* Allow overriding `gulpfile` and `preloads` via `.gulp.*` config file + +### Bug Fixes + +* Resolve bugs related to symlinks on various platforms +* Resolved some reported ReDoS CVEs and improved performance in glob-parent +* Rework errors surfaced when encountering files or symlinks when trying to create directories +* Ensure watch allows japanese characters in globs ([72668c6](https://www.github.com/gulpjs/gulp/commit/72668c61e445c81fad23bc6ed24967a3238a648d)) +* Ensure watch does not trigger on negated globs ([72668c6](https://www.github.com/gulpjs/gulp/commit/72668c61e445c81fad23bc6ed24967a3238a648d)) +* Improve handling of BOM at the beginning of a stream +* Properly handle function coercer in array of option coercers +* Fork `to-absolute-glob` to: + - Check negative patterns before trimming + - Ensure glob-like characters are escaped in cwd & root options + - Resolve `../` at the beginning of globs + +### Miscellaneous Chores + +* Remove lazystream dependency +* Updated various stream test suites to test against Node.js core `stream`, `readable-stream`, and `streamx` +* Normalize repository, dropping node <10.13 support ([#2758](https://www.github.com/gulpjs/gulp/issues/2758)) ([72668c6](https://www.github.com/gulpjs/gulp/commit/72668c61e445c81fad23bc6ed24967a3238a648d)) + +### Individual Changelogs + +We created and maintain various projects that gulp depends upon. You can find their changelogs linked below: + +* [undertaker](https://github.com/gulpjs/undertaker/blob/master/CHANGELOG.md#200-2024-03-22) +* [vinyl-fs](https://github.com/gulpjs/vinyl-fs/blob/master/CHANGELOG.md#400-2023-06-11) +* [glob-stream](https://github.com/gulpjs/glob-stream/blob/master/CHANGELOG.md#801-2024-03-25) +* [gulp-cli](https://github.com/gulpjs/gulp-cli/blob/master/CHANGELOG.md#300-2024-03-24) +* [interpret](https://github.com/gulpjs/interpret/blob/master/CHANGELOG.md#311-2022-06-29) +* [glob-parent](https://github.com/gulpjs/glob-parent/blob/main/CHANGELOG.md#602-2021-09-29) +* [glob-watcher](https://github.com/gulpjs/glob-watcher/blob/master/CHANGELOG.md#600-2023-05-31) +* [vinyl](https://github.com/gulpjs/vinyl/blob/master/CHANGELOG.md#300-2022-09-26) +* [fs-mkdirp-stream](https://github.com/gulpjs/fs-mkdirp-stream/blob/master/CHANGELOG.md#201-2022-09-17) +* [lead](https://github.com/gulpjs/lead/blob/master/CHANGELOG.md#400-2022-09-22) +* [vinyl-sourcemap](https://github.com/gulpjs/vinyl-sourcemap/blob/master/CHANGELOG.md#200-2022-10-17) +* [to-through](https://github.com/gulpjs/to-through/blob/master/CHANGELOG.md#300-2022-09-07) +* [resolve-options](https://github.com/gulpjs/resolve-options/blob/master/CHANGELOG.md#200-2022-06-24) +* [remove-bom-stream](https://github.com/gulpjs/remove-bom-stream/blob/master/CHANGELOG.md#200-2022-04-19) +* [value-or-function](https://github.com/gulpjs/value-or-function/blob/master/CHANGELOG.md#400-2022-01-30) +* [now-and-later](https://github.com/gulpjs/now-and-later/blob/master/CHANGELOG.md#300-2022-06-25) +* [@gulpjs/to-absolute-glob](https://github.com/gulpjs/to-absolute-glob/blob/master/CHANGELOG.md#400-2023-01-03) +* [fined](https://github.com/gulpjs/fined/blob/master/CHANGELOG.md#200-2021-10-31) +* [mute-stdout](https://github.com/gulpjs/mute-stdout/blob/master/CHANGELOG.md#200-2021-11-22) +* [semver-greatest-satisfied-range](https://github.com/gulpjs/semver-greatest-satisfied-range/blob/master/CHANGELOG.md#200-2022-01-31) +* [flagged-respawn](https://github.com/gulpjs/flagged-respawn/blob/master/CHANGELOG.md#200-2021-11-21) +* [rechoir](https://github.com/gulpjs/rechoir/blob/master/CHANGELOG.md#080-2021-07-24) +* [gulplog](https://github.com/gulpjs/gulplog/blob/master/CHANGELOG.md#220-2024-03-23) +* [glogg](https://github.com/gulpjs/glogg/blob/master/CHANGELOG.md#220-2024-03-23) +* [@gulpjs/messages](https://github.com/gulpjs/messages/blob/master/CHANGELOG.md#110-2024-03-24) +* [sparkles](https://github.com/gulpjs/sparkles/blob/master/CHANGELOG.md#210-2024-03-23) +* [liftoff](https://github.com/gulpjs/liftoff/blob/main/CHANGELOG.md#500-2024-03-16) +* [v8flags](https://github.com/gulpjs/v8flags/blob/master/CHANGELOG.md#401-2023-09-03) +* [bach](https://github.com/gulpjs/bach/blob/master/CHANGELOG.md#201-2022-08-29) +* [undertaker-registry](https://github.com/gulpjs/undertaker-registry/blob/master/CHANGELOG.md#200-2021-12-29) +* [async-settle](https://github.com/gulpjs/async-settle/blob/master/CHANGELOG.md#200-2022-06-25) +* [last-run](https://github.com/gulpjs/last-run/blob/master/CHANGELOG.md#200-2022-01-10) +* [async-done](https://github.com/gulpjs/async-done/blob/master/CHANGELOG.md#200-2022-06-25) +* [replace-homedir](https://github.com/gulpjs/replace-homedir/blob/master/CHANGELOG.md#200-2022-01-31) + ## 4.0.0 ### Task system changes diff --git a/package.json b/package.json index 2596c6084..be5477ddf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gulp", - "version": "4.0.2", + "version": "5.0.0", "description": "The streaming build system.", "homepage": "https://gulpjs.com", "author": "Gulp Team (https://gulpjs.com/)",