5

After migrating to El Capitan, it seems users are experiencing an issue with grunt installations, possibly related to the rootless changes of El Capitan. In particular, running the grunt --force command results in EPERM errors. The workflow is as follows:

Assuming npm has been installed, navigate to the grunt directory with package.json and gruntfile.js and invoke grunt:

grunt --force

Example Gruntfile.js file contents:

module.exports = function(grunt) {

    // All configuration goes here 
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),

        concat: {
            // Configuration for concatenating files goes here.
            dist: {
                src: [
                        '../js/libs/owl.carousel.js',
                        '../js/libs/jquery.actual.js',
                        '../js/libs/chosen.jquery.js',
                        '../js/libs/jquery.parallax.js',
                        '../js/src/common.js'  
                ],
                dest: '../js/pro/global.js',
            },
        },

        uglify: {
            build: {
                src: '../js/pro/global.js',
                dest: '../js/pro/global.min.js',
            },
        },


        imagemin: {
            dynamic: {
                files: [{
                    expand: true,
                    cwd: '../img/src/',
                    src: ['**/*.{png,jpg,gif}'],
                    dest: '../img/pro/'
                }]
            }
        },

        compass: {
            dev: {
                options: {              
                    sassDir: '../sass',
                    cssDir: '../css',
                    fontsDir: '../fonts',
                    imagesDir: '../img/',
                    images: '../img/',
                    javascriptsDir: '../js/pro',
                    //environment: 'development',
                    outputStyle: 'compressed',
                    relativeAssets: true,
                    httpPath: '.',
                }
            },
        },

        watch: {
            scripts: {
                files: ['../js/**/**.js'],
                tasks: ['concat', 'uglify'],
                options: {
                    spawn: true,
                },
            },
            images: {
                files: ['../img/src/**.{png,jpg,gif}'],
                tasks: ['imagemin'],
                options: {
                    spawn: true,
                }
            },
            compass: {
                files: ['../**/*.{scss,sass}'],
                tasks: ['compass:dev'],
            }

        },

        svgstore: {
            defaults: {
                options: {
                    prefix : 'icon-',
                },
                files: {
                    '../img/svg-defs.svg': ['../img/svg/*.svg']
                }
            }
        },


    });

    // Where we tell Grunt we plan to use this plug-in.
    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-imagemin');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-contrib-compass');
    grunt.loadNpmTasks('grunt-svgstore');

    // Where we tell Grunt what to do when we type "grunt" into the terminal.
    grunt.registerTask('default', ['concat', 'uglify', /*'imagemin',*/ 'compass', 'svgstore', 'watch']);

};

Example package.json file contents:

{
"name": "Call Me Maybe",
"version": "0.2.0",
"devDependencies": {
    "grunt": "^0.4.5",
    "grunt-contrib-compass": "^1.0.4",
    "grunt-contrib-concat": "^0.5.1",
    "grunt-contrib-imagemin": "^0.9.4",
    "grunt-contrib-sass": "^0.9.2",
    "grunt-contrib-uglify": "^0.9.2",
    "grunt-contrib-watch": "^0.6.1",
    "grunt-svgstore": "^0.5.0"
  }
}

The resulting EPERM errors are as follows:

Running "concat:dist" (concat) task
Warning: Unable to write "../js/pro/global.js" file (Error code: EPERM). Used --force, continuing.

Running "uglify:build" (uglify) task
Warning: Unable to write "../js/pro/global.min.js" file (Error code: EPERM). Used --force, continuing.

Running "compass:dev" (compass) task
Warning: Command failed: /bin/sh: compass: command not found. Used --force, continuing.
Warning: You need to have Ruby and Compass installed and in your system PATH for this task to work. More info: https://github.com/gruntjs/grunt-contrib-compass Used --force, continuing.

Running "svgstore:defaults" (svgstore) task
Warning: Unable to write "../img/svg-defs.svg" file (Error code: EPERM). Used --force, continuing.

Running "watch" task
Waiting...

Interestingly, Ruby and Compass are also installed, so it does align with the theory of the rootless unable to write to folders issues, but how can the dependency cores be moved elsewhere (i.e. /usr/local/bin) so this isn't an issue?

During the El Capitan Betas, some users suggested enabling root via terminal - though this seemingly no longer works, as the error persists and /usr/bin folder still doesn't allow for permission changes.

beta208
  • 617
  • 1
  • 6
  • 18
  • I had a bunch of issues with global gem installations after el capitan and had to reinstall them again to the `/usr/local/bin` directory with `sudo gem install -n /usr/local/bin compass`. But I don't recognize your errors. Is it possible any node dependencies are installed globally in the root? – Joao Oct 21 '15 at 20:30
  • Possibly, I did use that `sudo gem install -n /usr/local/bin compass` but didn't solve the issue. I do find that when running `grunt -v --force` everything runs fine, but when each file goes to write, it can't write, for example `Warning: Unable to write "../img/svg-defs.svg" file (Error code: EPERM). Used --force, continuing.` – beta208 Nov 16 '15 at 20:36
  • `brew install node` will put npm in `usr/local/bin` so you can forget about permission troubles. I also recommend a reboot to recovery and a `csrutil disable` to turn off SIP. Especially if you have formulae that reside in `usr/local/sbin` DISCLAIMER: I recommend disabling SIP if you are pretty security conscious and I'm not responsible for an accidental `sudo rm -rf /.` check `brew install safe-rm` if you want to be really careful. Cheers. – suzumakes Feb 11 '16 at 18:50

2 Answers2

1

For those running into the same issue, I had to eliminate the use of binaries installed to the path: /usr/bin, and reinstall after updating the path /usr/local/bin. Ruby tended to be the primary culprit. Because I was struggling with locating all my ruby installs, I ended up installing rbenv to manage my ruby versions.

The following terminal commands may be helpful in identifying your problematic paths:

which ruby
gem environment
gem uninstall [insert gem name here]
[google how to set your paths to /usr/local/bin... (will be in a hidden file)]
gem install [insert gem name here]
beta208
  • 617
  • 1
  • 6
  • 18
0

Installing non-system software on /usr/bin is a bad move, and is now prohibited in El Capitan, and with good reason.

I am not familiar with grunt, but if you can get to use /usr/local/bin instead then probably everything works.

  • I agree, hence I've bolded my portion of the question that asks 'how' can they be moved elsewhere so that isn't an issue. I would also like to make it clear that I did not down vote your answer, so please do not downvote my question in spite. – beta208 Oct 12 '15 at 17:30