extra c: added to destination path on windows ((Error code: ENOENT)) - gruntjs

Using latest version of grunt if we try to work like copying
copy: {
main: {
files: [
{ expand: true
src: ['/dev/war archive/latestfile/**/*.txt'],
dest: '/fernando/backups/pbuse/war',
filter :'isFile'
}
]
}
}
This will result in Error: Unable to create directory "C:\harikishore\backups\war\C:" (Error code: ENOENT)

In latest version of grunt we need to add the cwd(currentworkingdirectory) where the provided src is located for the action otherwise grunt-action will consider the actual system path included with src,so while creating destination will try to create the systempath which will result in the above error so it will work if change the code as below:
copy: {
main: {
files: [
{ expand: true,
cwd : '/dev/war archive/latestfile/'
src: ['**/*.txt'],
dest: '/fernando/backups/pbuse/war',
filter :'isFile'
}
]
}
}
So,now it will start the dest folder creation from src instead of system path included
Alternative: adding flaten:true property
This will allow us to pass the action since we are not creating the inner folder structure of src in dest just copying all the files and dumping in single outer folder.
If we need inner folder structure of src in dest also then we must need cwd

Related

Grunt-string-replace not working

I have an app folder where I want to replace http://localhost:8000 for http://fomoapp-melbourne.rhcloud.com in two files: companies-list.component.ts and events-list.component.ts. I am trying to use grunt-replace-string plugin and it seemingly runs successfully with green Done result and no errors, but no replacement happens.
Here is how Gruntfile.js looks like:
module.exports = function(grunt){
[
'grunt-string-replace',
].forEach(function(task){
grunt.loadNpmTasks(task);
});
// configure plugins
grunt.initConfig({
'string-replace': {
dist: {
files: {
'./app/': ['companies-list.component.ts','events-list.component.ts'],
},
options: {
replacements: [{
pattern: 'http://localhost:8000',
replacement: 'http://fomoapp-melbourne.rhcloud.com',
}]
}
}
},
});
// register tasks
grunt.registerTask('default', ['string-replace']);
};
The Grunt Files object is for specifying a mapping of source files to destination files. The purpose of this mapping is to tell Grunt to get the contents of the files in source, do something to the contents, and then write the response to a new file in the destination folder.
It looks to me from your configuration that you want Grunt to rewrite two files in the app/ directory. This is not going to work. I will bet that if you run grunt with the verbose option, grunt --verbose, your output will contain the following:
Files: [no src] -> ./app/
This is because Grunt cannot find the source files because you need to specify their relative paths.
It's up to you how you want to structure your app, but you might want to have a src/ folder and a dist/ folder under app/. If you choose to build your files objects dynamically, your config might look something like this:
files: [{
expand: true,
cwd: './app/src/',
dest: './app/dest/',
src: ['companies-list.component.ts', 'events-list.component.ts']
}]
Additionally, the documentation for grunt-string-replace states:
If the pattern is a string, only the first occurrence will be replaced, as stated on String.prototype.replace.
This means that if you want multiple instances of your string to be replaced, you must provide a Regular Expression literal. For example:
replacements: [{
pattern: /http:\/\/localhost:8000/g,
replacement: 'http://fomoapp-melbourne.rhcloud.com'
}]

How to target all files in root folder and subfolders except some in Grunt

I'm trying to archive all files (including subfolders and files in them) in the root folder with some exceptions.
Here's the list of the files:
var fileList = [
'**/*',
'!archive.zip',
'!.sass-cache/*',
'!assets/*',
'!node_modules/*',
'!.bowerrc',
'!.editorconfig',
'!.gitattributes',
'!.gitignore',
'!.jshintrc',
'!bower.json',
'!Gruntfile.js',
'!package.json',
'!README.md',
'!sublime.sublime-project',
'!sublime.sublime-workspace',
];
And here's the grunt-contrib-compress config:
compress: {
main: {
options: {
archive: 'archive.zip'
},
files: [
{ src: [fileList], dest: 'archive/' }, // includes files in path
]
}
}
But I can't make it work. Seems that the process is stuck in endless loop and it keeps archiving itself over and over. I tried adding the name of the archive to the exception list, however it didn't help.
How can I get all the files archived from the root folder and subfolders with certain exceptions?
Thanks a lot.

grunt-contrib-jade compiling to single JS with cwd

I am trying to compile multiple jade templates into single JS file using grunt-contrib-jade. Problem I'm facing is that with full path to templates, I get function names with full path. I want to avoid that, so I tried using cwd (without expand). This ended up with the following:
>> Source file "test.jade" not found.
>> Source file "test2.jade" not found.
Is there any way I could achieve what I plan? My grunt config for that task is as following:
jade: {
js: {
options: {
client: true,
amd: true
},
files: [ {
cwd: 'js/views/',
src: ['*.jade'],
dest: 'js/tmp/templates.js'
} ]
}
},
Thanks in advice,
Dracco
Silly me, didn't fully read the documentation of the plugin :(.
The solution is trivial, using the processName option:
options: {
client: true,
amd: true,
processName: function(path) {
var pathChunks = path.split('.')[0].split('/');
return pathChunks[pathChunks.length - 1];
}
}

Grunt convert markdown to pdf recursively and dynamically

I am stuck writing a Gruntfile which aim is to convert a bunch of Markdown files to PDF dynamically. Giving the current folder hierarchy:
root/
|_subfolder1
| |_filename1.md
|_subfolder2
|_filename2.md
...
|_node_modules
|_subfolderN
|filenameN.md
I would like to run a Markdown to PDF task which would process the md file and ouput a PDF file with the matching filename in the same output directory.
I did create a custom task which is parsing current directory, ignoring the mode_modules folder and get the markdown file, but I don't know how to configure the md2pdf task with the good properties to reflect dynamic folder mapping.
Here's my current Gruntfile:
module.exports = function(grunt) {
// 1 - Configuration
grunt.initConfig({
md2pdf: {
}
});
// 2 - Plugins
grunt.loadNpmTasks('grunt-md2pdf');
// 3 - Task registering
grunt.registerTask('default', 'Get Subfolders', function() {
grunt.file.recurse('.', callback);
function callback(abspath, rootdir, subdir, filename) {
var filenameOutExt;
// if current occurence is a file subdir == undefined
// checking subdir to true means it's not undefined and
// the current path is a directory
if(subdir) {
// excluding node_modules folder
if (!subdir.match('node_modules')) {
// only process markdown files
if(filename.match('.md')) {
filenameOutExt = filename.split('.')[0];
// now for each markdown files, run md2pdf task
// and ouput filenameOutExt.pdf in same folder
// as the input files
}
}
}
}
});
};
I am using this plugin: https://www.npmjs.com/package/grunt-md2pdf
So my questions is how should I configure the md2pdf task to pass it the markdown files and generate matching filename pdf output in same directory.
Output should be:
root/
|_subfolder1
| |_filename1.md
|_filename1.pdf
|_subfolder2
|_filename2.md
|_filename2.pdf
...
|_node_modules
|_subfolderN
|filenameN.md
|_filenameN.pdf
Thanks a lot
According to this line, this task uses the grunt.files utilitary function. This makes things easier for us!
First, it's not usual in grunt to create a different task to find the files you need in any other task.
That is, each task should receive the files it needs to operate on. For example...
coffee:
main:
files: [
expand: true
cwd: 'assets/script'
src: ['**/*.coffee']
dest: "assets/script"
ext: '.js'
]
(Note that this config is in a Gruntfile.coffee file, hence the CoffeeScript syntax)
This type of file configuration using glob expansion is one of the most common. You can find details in the documentation.
It's pretty obvious:
In every directory (**), take everything (/*) from assets/script/ that ends with .coffee. Put it into assets/script. Rename extensions to .js.
So, your task can probably be configured like that:
md2pdf: {
main: {
files: [ {
expand: true,
src: ['**/*.md', '!node_modules/**/*'],
dest: "pdf/"
} ]
}
}
Ok figured it out !
module.exports = function(grunt) {
// 2 - Plugins
grunt.loadNpmTasks('grunt-md2pdf');
grunt.registerTask('default', 'Dynamically generate PDF from MD', function() {
grunt.file.expand("./**/*.md").forEach( function(file) {
if(!file.match('./node_modules')) {
var md2pdf = grunt.config.get('md2pdf') || {};
md2pdf[file] = {
src: file,
dest: file + '.pdf'
};
grunt.config.set('md2pdf', md2pdf);
}
});
grunt.task.run('md2pdf');
});
};

Using grunt to concat many files from many dirs into single renamed file in new directory

I have an Angular project with potentially many modules. Each module has it's own directory with subdirectories for controllers, directives, services, etc. Something like this:
src
|-- js
|-- modules
|-- moduleOne
| module.js
|-- controllers
| listController.js
| detailController.js
|-- directives
| listItem.js
| summaryWidget.js
|-- filters
|-- services
| moduleService.js
My build essentially bundles and compiles files from src/ and puts into dev/, then minifies the files in dev/ and moves into prod/. During dev, the server points to the dev/ folder and in production, the server points to the prod/ folder (also why the files are ending in .min.js even though they are only compiled/concated). This process is working well.
Currently, my concat task is grabbing all the files in moduleOne/ and creating a single moduleOne.js file in my dev directory. This is what I want to happen, but more dynamically:
concat: {
modules: {
files: {
"dev/js/modules/moduleOne.min.js": [
"src/js/modules/moduleOne/*.js",
"src/js/modules/moduleOne/**/*.js"
],
"dev/js/modules/moduleTwo.min.js": [
"src/js/modules/moduleTwo/*.js",
"src/js/modules/moduleTwo/**/*.js"
]
}
}
}
The problem is that I have to do this for every module, but don't think I would need to.
I tried doing the following because it's sort of what I want to do:
concat: {
modules: {
files: [{
expand: true,
cwd: "src/js/modules",
src: "**/*.js",
dest: "dev/js/modules",
ext: ".min.js"
}]
}
}
But the result was all my files and directory structure moved over from src/ to dev/. I basically used concat to do a copy, not helpful.
I'd like to do something like this:
concat: {
modules: {
files: [{
expand: true,
cwd: "src/js/modules",
src: "**/*.js",
dest: "dev/js/modules/<foldername>.min.js", <- how do I achieve this?
}]
}
}
I've been reading a lot, but it seems that I only get close to finding the answer and am having trouble putting the concepts together. A lot of what I find is just single files into a new directory, with a rename. I'd like multiple files to single file into new directory with a rename. Cuz that's how I roll :)
So, I found the answer I was looking for.
This SO post was basically the same question with a good answer. Unfortunately it didn't come up when I was creating my question or else you wouldn't be reading this.
There was a slight tweak to my needs. I needed to do it dynamically per module instead of just one compile.js file so my final code is as follows, placed just after my initConfig():
grunt.registerTask("prepareModules", "Finds and prepares modules for concatenation.", function() {
// get all module directories
grunt.file.expand("src/js/modules/*").forEach(function (dir) {
// get the module name from the directory name
var dirName = dir.substr(dir.lastIndexOf('/')+1);
// get the current concat object from initConfig
var concat = grunt.config.get('concat') || {};
// create a subtask for each module, find all src files
// and combine into a single js file per module
concat[dirName] = {
src: [dir + '/**/*.js'],
dest: 'dev/js/modules/' + dirName + '.min.js'
};
// add module subtasks to the concat task in initConfig
grunt.config.set('concat', concat);
});
});
// the default task
grunt.registerTask("default", ["sass", "ngtemplates", "prepareModules", "concat", "uglify", "cssmin"]);
This essentially makes my concat task look like it did when I was hand coding it, but just a little simpler (and scalable!).
concat: {
...
moduleOne: {
src: "src/js/modules/moduleOne/**/*.js",
dest: "dev/js/modules/moduleOne.min.js"
},
moduleTwo:{
src: "src/js/modules/moduleTwo/**/*.js",
dest: "dev/js/modules/moduleTwo.min.js"
}
}
Another deviation I made from the SO post was that I chose not to have prepareModules run concat on it's own when it was done. My default task (which watch is setup to run during dev) still does all my processing.
This leaves me with the following structure, ready for minification into prod/:
| dev
| js
| modules
|-- moduleOne.min.js
|-- moduleTwo.min.js

Resources