npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

grunt-force-developer

v0.1.10

Published

A grunt task for salesforce and force.com development

Downloads

35

Readme

grunt-force-developer

A grunt task for salesforce and force.com development. Designed to help force.com developers to work using the benefits of grunt and a folder structure when developing.

Getting Started

First - learn about Grunt Second - read the overview below Third - watch this short video demoing grunt-force-developer. Finally - Download via NPM and have a play.

npm install grunt-force-developer --save-dev

Once the plugin has been installed, it may be enabled inside your Gruntfile with this line of JavaScript:

grunt.loadNpmTasks('grunt-force-developer');

Overview

Using grunt and the grunt-force-developer tasks, developers for salesforce & force.com can:

  • Manage their projects / packages in any folder structure they like.
  • Integrate the full suite of grunt tasks into their deployment process.
  • Ensure only new & modified code is published as part of each deployment / build. This enables a developer to code using any IDE, pushing changes via grunt.

To use grunt-force-developer as quickly as possible, we recommend starting with the Gruntfile.js in examples.

Folder Structures

Traditional Folder Structure

Traditionally, when a developer is developing for salesforce / force.com, they are constrained by the mandated package structure. This structure is extremely limiting and, as the size of projects / packages grow, raplidly becomes unwieldy.

package.xml
== classes
    -- PaymentController.cls
    -- PaymentController.cls-meta.xml
    -- UserManagement.cls
    -- UserManagement.cls-meta.xml
== pages
    -- Payment.page
    -- Payment.page-meta.xml
    -- UserManagement.page
    -- UserManagement.page-meta.xml
== objects
    -- Payment__c.object

grunt-force-developer Folder Structure

Using grunt-force-developer, a developer can adopt a fully dynamic file structure that operates independent of the prescribed salesforce package structure. The below example is a snippet from a developer managing their package in structure with little constraints, appropriate for their project.

== .metadata
    -- Payment.page-meta.xml
    -- PaymentController.cls-meta.xml
    -- UserManagement.page-meta.xml
    -- UserManagementController.cls-meta.xml
== Admin
   == Users
      -- UserManagementController.cls
      -- UserManagement.page
== Payments
    -- PaymentController.cls
    -- Payment.page
    -- Payment__c.object

Usage

In your project's Gruntfile, add a section named force to the data object passed into grunt.initConfig().

var credentials = {
  consumerKey: '3MVG98SW_UPr.JFjzEoUdZZczc4pPByJsJh_3hvL_dxAMPsA8DpjdYBXepSg3GztwV.PPEG2Q6YaK1l.11111',
  consumerSecret: '1233452345246423523',
  username: '[email protected]',
  password: 'qwerty123',
  token: 'O7uccvnguEXqLnOBiTLC1234'
};

// Project configuration.
grunt.initConfig({
  force: {
    createPackage: {
      options: {
        action: 'package'
      },
    },
    deployPackage: {
      options: {
        action: 'deploy',
        consumerKey: credentials.consumerKey,
        consumerSecret: credentials.consumerSecret,
        username: credentials.username,
        password: credentials.password,
        token: credentials.token
      },
    }
  }
});

Options

options.action

Type: String Default value: 'deploy'

This option drives the behaviour of the plugin. There are 3 available modes:

  • reset = Deletes the 'package' directory and clears any files hashes. Ensures the next 'package' action will package all project files.
  • package = Copies all supported new & modified project files into the standard salesforce package structure.
  • deploy = Deploys the code to salesforce using nforce (Currently not working -- [grunt-ant-sfdc](https://github.com/kevinohara80/grunt-ant-sfdc] as an alternative).
  • commit = Updates the the files hashes cache, ensuring the next deploy call will only package changed, undeployed project files.

options.environment

Type: String Default value: 'production'

Values can be 'production' or 'sandbox'. Maps to nforce createConnection.

options.fileChangeHashFile

Type: String Default value: '.force-developer.filehash.json'

Persists the file hashes to determine modified and new files.

options.metadataSourceDirectory

Type: String Default value: 'app-metadata'

The folder used to store all '-meta.xml' files for the project. A corresponding file is required for all pages, components, trigger and classes. If the projectBaseDirectory isn't altered, the default location is ./project/app-metadata.

options.pollInterval

Type: Integer Default value: 500

Sets the polling interval when deploying a package.

options.projectBaseDirectory

Type: String Default value: 'project'

Used to determine the root of the project folder.

options.outputDirectory

Type: String Default value: '.package'

The folder used when the files are copied from the project folder into a salesforce package-compliant folder structure.

options.outputPackageZip

Type: String Default value: './.package/package.zip'

The location where the zipped package is to be stored.

options.apiVersion

Type: Integer Default value: 34

The api version to be used by the task. Used when creating on-demand meta-xml files.

Recommended Gruntfile.js

In this example, the default task is configured to package the new and modified project files and upload these using ant. ant has been used due to problems getting nforce-metadata to deploy zip files -- this will be addressed.

This script enables a developer to work using any folder structure and uploading changes by executing grunt. Once the nforce issue is addressed, this script would be executed grunt default-nforce.

Install the appropriate dependancies required for this Gruntfile by executing:

npm install grunt-force-developer grunt-ant-sfdc grunt-contrib-compress --save-dev

Please ensure ant is installed and available as part of the environment path.

Gruntfile.js:

'use strict';
module.exports = function(grunt) {

  // TODO: Update the credentials.
  var credentials = {
    // Not required for ant deployment
    consumerKey: '3MVG98SW_UPr.JFjzEoUdZZczc4pPByJsJh_3hvL_dxAMPsA8DpjdYBXepSg3GztwV.PPEG2Q6YaK1l.11111', 
    // Not required for ant deployment
    consumerSecret: '1233452345246423523',
    
    username: '[email protected]',
    password: 'qwerty123',
    token: 'O7uccvnguEXqLnOBiTLC1234'
  };

// Project configuration.
  grunt.initConfig({

    // Configuration to be run (and then tested).
    force: {
      resetCache: {
        options: {
          action: 'reset'
        },
      },
      createPackage: {
        options: {
          action: 'package'
        },
      },
      deployPackage: {
        options: {
          action: 'deploy',
          consumerKey: credentials.consumerKey,
          consumerSecret: credentials.consumerSecret,
          username: credentials.username,
          password: credentials.password,
          token: credentials.token
        },
      },
      commitCache: {
        options: {
          action: 'commit'
        },
      },
    },

    compress: {
      packageZip: {
        options: {
          archive: './.package/package.zip'
        },
        files: [
          {cwd: './.package/src/', expand: true, src: ['**']} // includes files in path and its subdirs
        ]
      }
    },

    antdeploy: {
      options: {
        root: './.package/src/', // note trailing slash is important
        apiVersion: '32.0',
        existingPackage: true
      },
      deployPackage: {
        options: {
          user: credentials.username,
          pass: credentials.password,
          token: credentials.token
        }
      }
    }

  });

  // These plugins provide necessary tasks.
  grunt.loadNpmTasks('grunt-ant-sfdc');
  grunt.loadNpmTasks('grunt-contrib-compress');
  grunt.loadNpmTasks('grunt-force-developer');

  grunt.registerTask('reset', ['force:resetCache']);
  grunt.registerTask('default', ['force:createPackage', 'compress:packageZip', 'antdeploy:deployPackage']);
  grunt.registerTask('default-nforce', ['force:createPackage', 'compress:packageZip', 'force:deployPackage']);

};

Contributing

In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using Grunt.

Acknowledgements

  • Kevin O'Hara for his exceptional nodejs/salesforce work ... and especially his nforce libraries.

Release History

  • 0.1.10
    • Changed search for meta-xml files to search all project directories before generating metadata.
  • 0.1.9
    • Fundamental change - Altered logic so a deploy action does not update the changed file cache. This means that once a deploy is successful, you must make a second call to update the changed file cache so they aren't included in any subsequent deploy calls.
  • 0.1.8
    • Added apiVersion to options.
    • Added support for dynamically creating -meta.xml files for classes and pages.