Adapt dest folder to ** globbing pattern - gruntjs

I'm working with grunt-contrib-copy. I have this file tree:
`-- src
`-- model
|-- a4
| `-- public
| |-- css
| |-- img
| `-- js
|-- posters
| `-- public
| |-- css
| |-- img
| `-- js
`-- prints
`-- public
|-- css
|-- img
`-- js
I would like to copy the files in
src/model/**/public/img to dist/images/{1}/ where {1} is the folder name (a4, posters, prints... dynamic folders that are bound to change too), so:
src/model/a4/public/img/file.png -> dist/images/a4/file.png
Is there a way to specify that with grunt-contrib-copy (maybe the rename function?) or do I have to iterate manually over the files?
Right now this is what I have:
grunt.registerTask 'images-generate', ->
gruntCopyFiles.images = {
expand: true,
cwd: './src/model/',
src: ["**/public/img/*.png", "**/public/img/*.jpg"],
dest: "./dist/images/"
}
But this copies src/model/a4/public/img/file.png to dist/images/a4/public/img/file.png which is not what I want.
Any suggestion? Thanks!

Is there a way to specify that with grunt-contrib-copy (maybe the rename function?) or do I have to iterate manually over the files?
Utilizing the rename function is the way to achieve this. Glob patterns alone cannot meet your requirement, nor can the flatten option.
Something like the following also copies any subfolders which may potentially reside inside the source img folders:
gruntCopyFiles.images = {
expand: true,
cwd: 'src/model',
dest: 'dist/images',
src: '**/public/img/**/*.{png,jpg,gif}',
rename: function(dest, src) {
var items = src.split('/'),
baseIndex = items.indexOf('img') + 1,
subPath = items.slice(baseIndex, items.length).join('/');
return [dest, items[0], subPath].join('/');
}
}
Example:
src/model/a4/public/img/file.png --> dist/images/a4/file.png
src/model/a4/public/img/quux/file.jpg --> dist/images/a4/quux/file.jpg

Looks like you can use flatten to get stripped-down destination paths:
gruntCopyFiles.images = {
flatten: true,
expand: true,
cwd: './src/model/',
src: ["**/public/img/*.png", "**/public/img/*.jpg"],
dest: "./dist/images/"
}
From the docs:
flatten Remove all path parts from generated dest paths.

Related

How to skip source parent directory using grunt uglify

src directory:
dir1
|-- 1.js
|-- 2.js
`-- sub-dir1
`-- 1.js
dest directory:
min
`-- dir1
|-- 1.min.js
|-- 2.min.js
`-- sub-dir1
`-- 1.min.js
My code snippet:
uglify: {
t2: {
options: {
banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' +
'<%= grunt.template.today("yyyy-mm-dd") %> */'
},
files: [{
expand: true,
src: ['dir1/**/*.js'],
dest: 'min',
rename: function (dst, src) {
return dst + '/' + src.replace('.js', '.min.js');
}
}]
}
}
But I want to skip source directory under destination directory, desired structure is:
min
|-- 1.min.js
|-- 2.min.js
`-- sub-dir1
`-- 1.min.js
There's a couple of ways to achieve this. Solution A (below) is the simplest and most commonly used.
Solution A
When building the files object dynamically you can utilize the cwd property. The description of the cwd property in the docs reads:
cwd All src matches are relative to (but don't include) this path.
Change your files property to the following:
// ...
files: [{
expand: true,
cwd: 'dir1/', // <-- Add this.
src: '**/*.js', // <-- Change your src glob to this.
dest: 'min',
rename: function (dst, src) {
return dst + '/' + src.replace('.js', '.min.js');
}
}]
// ...
Solution B
Another way, (without utilizing the cwd property), is to change your rename method to the following instead:
// ...
rename: function (dst, src) {
src = src.split('/');
src.shift();
src = src.join('/');
return dst + '/' + src.replace('.js', '.min.js');
}
// ...
The src = src.split('/'); part utilizes the String split() method with the / separator to split the src path into an array of individual path items.
The src.shift(); part utilizes the Array shift() method to remove the first element from the array (e.g. dir1).
The src = src.join('/') part utilizes the Array join() method with the / separator to form the new path as a String.

grunt-rebase – copy to multiple folders along with flattening the structure

I was wondering if anyone could help me with this.
I have a project where I am creating multiple html pages for different sites. Each of these sites shares a common assets folder (fonts, css, js etc) my directory layout is as follows:
|-- project
| |--assets
| | |—-css
| | |—-images
| | |—-fonts
| | |—-js
| |--site-1
| | |—-index.html
| |--site-2
| | |—-index.html
| |--site-3
| | |—-index.html
What I would like to achieve is the following:
• A 'dist' folder that contains:
|-- dist
| |--site-1
| | |—-index.html
| | |—-style.min.css
| | |—-image1.jpg
| | |—-image2.jpg
| | |—-image3.jpg etc...
| | |—-scripts.min.js
| | |—-font1.otf
| | |—-font2.otf etc...
| |--site-2
| | |—-index.html
| | |—-style.min.css
| | |—-image1.jpg
| | |—-image2.jpg
| | |—-image3.jpg etc...
| | |—-scripts.min.js
| | |—-font1.otf
| | |—-font2.otf etc...
| |--site-3
| | |—-index.html
| | |—-style.min.css
| | |—-image1.jpg
| | |—-image2.jpg
| | |—-image3.jpg etc...
| | |—-scripts.min.js
| | |—-font1.otf
| | |—-font2.otf etc...
Just to explain the desired result:
• each site is 'flattened' within a directory, so that all of the assets, images, js, css, fonts are on the same level as the index.html file. (a requirement of the 3rd party that needs these)
• The corresponding links in each of the .html, .css & .js are updated the reflect the above.
• At times there might be more or less than just 3 'site' folders - so it would be great if I could 'loop' through and detect a folder name convention (??) - just a nice have if anyone smarter than me knows how to do this with a grunt task.
I have been trying the grunt-rebase task to make this work. It sounds like it is what I need, however I am really struggling with the documentation to make it work, along with a lack of experience with grunt tasks.
Any help would be great. If you need any more info please let me know.
EDIT - here is my grunt.js file - I have removed unneeded tasks and other bumpf for clarity.
module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
copy: {
main: {
files: [
{expand: true, cwd: 'project/', src: ['**/*'], dest: 'dist/', filter: 'isFile'}
]
}
},
rebase: {
scoped: {
files: [{
//css ref's
expand: true,
cwd: 'dist/assets/css/',
src: '*.css',
dest: 'dist/site-1/',
reference: '../assets/images/',
scopes: {
url: {
'../images/': '',
'../fonts/': ''
}
}
}, {
//html ref's
expand: true,
cwd: 'dist/site-1/',
src: '**/*.html',
dest: 'dist/site-1/',
reference: true,
scopes: {
url: {
'../assets/images/': ''
},
img: {
'../assets/images/': ''
},
link: {
'../assets/css/': ''
},
script: {
'../assets/js/': ''
}
}
}, {
//images
expand: true,
cwd: 'dist/assets/images/',
src: '**/*',
dest: 'dist/site-1/'
}, {
//fonts
expand: true,
cwd: 'dist/assets/fonts/',
src: '**/*',
dest: 'dist/site-1/'
},
{
//js
expand: true,
cwd: 'dist/assets/js/',
src: '*.js',
dest: 'dist/site-1/'
}]
}
}
});
//1 - make copy of entire prod directory to 'dist folder'
//2 - rebase task
//3 - TODO - delete dist/assets folder (not needed after rebase)
grunt.registerTask('Create Exported Project', [
'copy',
'rebase'
]);
};
The above rebase task works....but only for one folder that i hard code into the 'dest' field for each scope (the 'site-1' folder).
I was hoping for some flexibility to be able to loop through all folders that match a condition (maybe the string - 'site-').

Reduce network traffic for Native Client installation from Chrome Web Store

My Chrome app contains three .nexe files for arm, x86-32 and 64-bit processors. When I install this app from Chrome web store, the size of downloaded package is the same as the size of the app containing all .nexe files. Is it possible to optimize this network traffic?
My .nmf file bundled in the app looks like this:
{
"program": {
"arm": { "url": "arm.nexe" },
"x86-32": { "url": "x86_32.nexe" },
"x86-64": { "url": "x86_64.nexe" }
}
}
Thanks
Yes, you can add a platform specific section to your manifest.json. Then the packages will only download the components that are specified for that CPU architecture.
There is documentation for that feature here: https://developer.chrome.com/native-client/devguide/distributing#reducing-the-size-of-the-user-download-package
And there is an example in the SDK as well: examples/tutorial/multi_platform
To summarize the documentation above:
First create a _platform_specific directory in your App package. For each architecture, create a subdirectory with that name:
|-- my_app_directory/
| |-- manifest.json
| |-- my_app.html
| |-- my_module.nmf
| +-- css/
| +-- images/
| +-- scripts/
| |-- _platform_specific/
| | |-- x86-64/
| | | |-- my_module_x86_64.nexe
| | |-- x86-32/
| | | |-- my_module_x86_32.nexe
| | |-- arm/
| | | |-- my_module_arm.nexe
| | |-- all/
| | | |-- my_module_x86_64.nexe
| | | |-- my_module_x86_64.nexe
| | | |-- my_module_x86_32.nexe
Then in the manifest.json file, specify the location of these directories:
...
"platforms": [
{
"nacl_arch": "x86-64",
"sub_package_path": "_platform_specific/x86-64/"
},
{
"nacl_arch": "x86-32",
"sub_package_path": "_platform_specific/x86-32/"
},
{
"nacl_arch": "arm",
"sub_package_path": "_platform_specific/arm/"
},
{
"sub_package_path": "_platform_specific/all/"
}
]
You'll want your .nmf to point to the location of these nexes. The SDK build system has an option to do all of this for you automatically, I'd suggest using it.

grunt-contrib-copy error (Error code: ENOENT)

I searched internet and it looks only me had this problem with grunt-contrib-copy.
project
gruntfile.js
->app
->img
->pic1.png
->pic2.png
Result I expected:
project
gruntfile.js
->app
->dist
->img
->pic1.png
->pic2.png
->img
->pic1.png
->pic2.png
In another word, just copy files in /project/app/img to /project/app/dist/img.
Here is my copy config, which is NOT working:
copy: {
main: {
src: ['*.*'],
expend: true,
cwd: 'app/img/',
dest: 'app/dist/img/'
}
},
Here is error message:
Warning: Unable to read "download.png" file (Error code: ENOENT). Use --force to continue.
(download.png is the name of picture file)
How should I config the copy option? Thank you!
It looks like you have a typo, it should be expand instead of expend. So the cwd property is being ignored. Try the following config instead:
copy: {
main: {
src: ['**/*'],
expand: true,
cwd: 'app/img/',
dest: 'app/dist/img/'
}
},
The glob pattern *.* is probably not necessary as * will already match all files (unless you're specifically trying to match only files with a . in them.) Try using src: '*' to match all files within the single folder or src: '**/*' to match all files and folders within the cwd.

Grunt rename not working

My directory structure looks like this:
-src/
-----pages/
----------...
-----...
-build
My gruntfile contains the following task:
copy: {
all:{
dest:"<%= builddir %>/",
src: ["src/**/*.{yaml,yml,py,html,htm,json,css}"],
rename:function(d, s){return d.replace("src/","");}
}
},
builddir: "build/<%= pkg.name %>-<%= pkg.version %>-<%= date %>",
When I run the copy task, it copies all the selected files into the directory containing the package name, version and build date, as expected, but it copies the entire src directory. while I only want to copy the contents of the src directory, so I'm trying to remove src/' from dest using therename`property, which doesn't work for some reason.
I've only started using grunt today, so I might be makiing a rookie mistake here.
Hmm... I think all you need is the cwd (current working directory) option. Unless you in fact want to flatten the files into a single directory.
copy: {
all:{
expand: true,
dest:"<%= builddir %>/",
src: ["**/*.{yaml,yml,py,html,htm,json,css}"],
cwd: "src/"
}
}
You'll need to set the flatten option, which removes the directory structure.
copy: {
all:{
expand: true,
flatten: true,
dest:"<%= builddir %>/",
src: ["src/**/*.{yaml,yml,py,html,htm,json,css}"]
}
}

Resources