![Oracle Drags Its Feet in the JavaScript Trademark Dispute](https://cdn.sanity.io/images/cgdhsj6q/production/919c3b22c24f93884c548d60cbb338e819ff2435-1024x1024.webp?w=400&fit=max&auto=format)
Security News
Oracle Drags Its Feet in the JavaScript Trademark Dispute
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
gulp-restructure-tree
Advanced tools
A powerful, declarative way to restructure complex directory structures with Gulp. Use globs, RegExps and functions arranged in a tree structure to rename files.
$ npm install gulp-restructure-tree --save-dev
restructureTree(treeMap[, options])
Describe your file tree with plain javascript objects to move or filter files in your Gulp pipeline:
const restructureTree = require('gulp-restructure-tree')
gulp.src('./**')
.pipe(restructureTree({
'src': {
'**.md': null, // Exclude all markdown files in src/
'utils/': 'libs/' // Move all file in src/utils/ to libs/
},
'log-*.txt': 'logs/$1.log', // Rename files matching ./src/log-*
}))
.pipe(gulp.dest('./dist'))
// src/utils/react-if/dist/index.js ⇒ dist/libs/react-if/dist/index.js
// log-1491831591372.txt ⇒ dist/logs/1491831591372.log
gulp-restructure-tree
gives you many more ways to match files and directories, read on to learn more.
restructureTree( treeMap[, options] )
treeMap
:A tree structure described with plain javascript objects. Keys are branches
and non-object values are leaves
.
branches
:
A branch represents a path segment, the name of one directory or file.
Simple bash-style *
, **
glob patterns can be used, or Regular Expression for more complicated matching requirements.
foo
: Regular string branches match filenames literally.*
: A wildcard can be included anywhere in the path to match any number of characters in a filename.fo*ar
will match foobar
but will not match nested directories foo/bar
.**
: A branch name can begin with a "globstar" pattern, in that case it will recursively match as many directories as necessary to complete the rest of the tree.1**az
will match foo/bar/baz
.foo/
: If the last branch in a route ends with a /
, it will match everything inside that directory.2{ 'foo/': 'bar' }
is the same as { 'foo': { '**': 'bar' }}
.[/foo[a-z-]+/]
: A branch name can be a Regular Expression. It will match any branch that matches it. No RegExp flags are supported.3[["foo","bar*","baz"]]
: A branch name can also be an array, in which case it will match if any of the array elements matches.3leaves
:
Any value that is either a function, a string, or null, represents a destination. Files whose paths match the path leading up to the leaf will be moved to the specified destination.
{string} foo/
: A string destination path that ends with a /
is interpreted as a directory destination. Matched files will keep their filenames, and the folder hierarchy that starts at the point the file path and the treeMap
path "diverges" will be conserved4.{string} foo
: A string destination path that doesn't end with a /
is interpreted as a file destination. Matched files will be renamed to match the new destination filename, and all of their original folder hierarchy discarded.$1
, $2
, ...) in the destination string.(pathObject) => {string|pathObject}
: Takes a parsed pathObject
, and returns either a path string that will be interpreted the same as a string leaf, or a pathObject
that will be applied directly.5null
: The file will be removed from the stream.options
:dryRun
{boolean=false}
: Don't move files, only log operations that would be executed (implies verbose mode).verbose
{boolean=false}
: Log file move operations to stdout.logUnchanged
{boolean=false}
: In verbose mode, also log operations that don't result in any path change.onlyFiles
{boolean=false}
: Don't process directories.bypassCache
{boolean=false}
: Force recompile of treeMap
argument. 6(In case of doubts, see PathMatcher.test.js
for a more comprehensive spec.)
// gulpfile.babel.js
import restructureTree from 'gulp-restructure-tree'
// Map starting directory structure with a tree having the destinations as its
// leaves.
const treeMap = {
app: {
modules: {
'*': {
// Use wildcard globs: * and ** (recursive).
'**.css': 'styles/',
// A string value is interpreted as a destination path.
// A destination with a trailing / is interpreted as a directory, without
// it is interpreted as a destination file and the file will be renamed.
// app/modules/basket/alt/christmas.css ⇒ styles/basket/alt/christmas.css
gui: {
'**GUI.jsx': 'templates/$1-$3.js',
// Insert back references, here whatever directory was matched by the *
// just after 'modules' will serve as the first part of the filename.
// This "trailing" ** counts as two capture groups, one for
// the folders and one for the ending file ("**/*").
// app/modules/basket/gui/itemsGUI.jsx ⇒ templates/basket-items.js
},
[/(.*)(\.min)?\.jsx?/]: 'scripts/$2.js',
// Use RegExp by converting them to strings, capture groups are used for the
// back references.
// app/modules/basket/itemsRefHandling.min.js ⇒ scripts/itemsRefHandling.js
'img/': 'assets/$1/$3.compressed',
// A trailing branch with a trailing / is interpreted as a recursive
// match (equivalent to a trailing '**' branch).
// app/modules/basket/img/cart.png ⇒ assets/basket/cart.png.compressed
}
},
helpers: {
'jquery-*': 'libs/global/',
// Rules are evaluated from top to bottom so place more specific rules on top.
// If you placed this rule after the following one, it would match on the
// first one and never reach this one.
// app/helpers/jquery-3.1.1.min.js ⇒ libs/global/jquery-3.1.1.min.js
[/.*\.jsx?/]:
({ name, extname }) =>
`libs/${extname === 'jsx' ? 'react/' : ''}${name}/${name}.js`
// Function leaves take a parsed path as argument and return a destination
// path as a string or parsed path object.
// app/helpers/modalify.js ⇒ libs/modalify/modalify.js
// app/helpers/dropdown.jsx ⇒ libs/react/dropdown/dropdown.js
}
},
documentation: {
'/': './docs',
// Match folder by selecting it with a '/' rule. This will move the empty
// directory.
// documentation ⇒ docs
[['COPYRIGHT', 'LICENSE', 'CHANGELOG-*']]: './',
// Use arrays to match a set of filenames without bothering with RegExps.
// documentation/LICENSE ⇒ LICENSE
'**': null,
// Discard files by routing them to a null leaf.
// documentation/module-organization.html ⇒ [Removed from output]
},
}
export function move() {
gulp.src('./src/**', { base: './src' })
.pipe(restructureTree(treeMap))
.pipe(gulp.dest('./dist')
}
$ git clone https://github.com/SewanDevs/ceiba-router.git
$ npm run build # Compile project with Webpack
$ npm run watch # Run Webpack in watch mode
$ npm run test # Run Jest on all .test.js files
$ npm run testWatch # Run Jest in watch mode
gulp-restructure-tree
will warn you if you use such keys in your tree and suggest making the branch a simple RegExp as a workaround to keep the definition order (e.g.: "7"
→"/7/"
).[1]: A globstar introduces two capture groups, one that will match the last folder matched, and one that will match the file name (e.g.: with { "foo/**": "quux/$1/$2" }
: ./foo/bar/baz/qux
⇒./quux/baz/qux
).
[2]: Internally, a globstar is appended to the route, which means you can reference them in capture groups (e.g.: with { "foo/": "qux/$1/$2.bak" }
: ./foo/bar/baz
⇒./qux/bar/baz.bak
).
[3]: RegExp and Array branches are included using computed property name syntax. The string representation of ReExps and Array instances is used to differentiate them from plain branches. Thus, a branch that begins and ends with a /
will be interpreted as a RegExp branch, and a branch that has a ,
in it will be interpreted as an array branch. If you want to match a literal comma in a filename, you must escape it (e.g.: "foo\\,bar.txt"
will match the file foo,bar.txt
).
[4]: The concept of divergence is defined as follow: until a tree path is composed of regular string branches and it matches the file path, the paths are not diverging. The non-diverging matching directories will be "eaten" from the resulting path
(e.g.: with { foo: { bar: { 'b*z/': 'dest/' }}}
: foo/bar/baz/qux
⇒dest/baz/qux
, the folders foo
and bar
have been omitted in the resulting path, but baz
has been kept since it isn't an "exact" match).
[5]: The pathObject
sent to function destinations has an additional key in addition to those provided by path.parse
: full
, which is the full relative path name as provided by the vinyl stream. It is provided as a convenience and is ignored in the function's return value.
[6]: treeMap
objects are compiled and cached in memory. It won't be recompiled if you pass the same object to gulp-restructure-tree
multiple times. This means splitting definitions in multiple sub-trees for the different tasks shouldn't significantly improve performance. This also means that if you want to mutate the same treeMap
object in between calls to gulp-restructure-tree
, your changes won't be accounted for unless you pass in the bypassCache
option.
FAQs
Restructure complex directory structures declaratively
The npm package gulp-restructure-tree receives a total of 5 weekly downloads. As such, gulp-restructure-tree popularity was classified as not popular.
We found that gulp-restructure-tree demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
Security News
The Linux Foundation is warning open source developers that compliance with global sanctions is mandatory, highlighting legal risks and restrictions on contributions.
Security News
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.