Skip to content

A Grunt plugin to provide local build tasks for Phonegap applications

License

Notifications You must be signed in to change notification settings

logankoester/grunt-phonegap

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Grunt: Phonegap

A Grunt plugin to provide build tasks for Phonegap applications

Build Status Dependency Status devDependency Status Gittip

NPM

grunt-phonegap integrates Phonegap development with Grunt-based workflows by wrapping the Phonegap 3.0 command line interface.

Rather than polluting the top-level of your project, grunt-phonegap copies your files into a subdirectory containing the Phonegap project, which gets regenerated every time the task phonegap:build is executed.

Jump to Section

Requirements

[Back To Top]

You will need the phonegap CLI tool installed globally to use grunt-phonegap.

npm install phonegap -g

You should also install whatever system dependencies are required by the platforms you intend to target.

For help with that, see Platform Guides from the Phonegap documentation.

Getting Started

[Back To Top]

If you haven't used Grunt before, be sure to check out the Getting Started guide, as it explains how to create a Gruntfile as well as install and use Grunt plugins. Once you're familiar with that process, you may install this plugin with this command:

Demo

For new apps

The easiest way to start a new project is with the grunt-init-phonegap template.

It will ask you some basic questions and then generate a project skeleton in your current directory.

git clone https://github.com/logankoester/grunt-init-phonegap.git ~/.grunt-init/phonegap
mkdir myapp
cd myapp
grunt-init phonegap

Once the skeleton has generated, open up your new Gruntfile.coffee add one or more platforms to the list.

Your app is ready to build! [Skip to Tasks] to see how.

For existing apps

npm install grunt-phonegap --save-dev

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

grunt.loadNpmTasks('grunt-phonegap');

Overview

[Back To Top]

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

Point phonegap.config.root to the output of your other build steps (where your index.html file is located).

Point phonegap.config.config to your config.xml file.

phonegap.config.cordova should be the .cordova directory that is generated by phonegap create. It must contain a config.json file or your app cannot be built.

Options

grunt.initConfig({
  phonegap: {
    config: {
      root: 'www',
      merges: 'merges', //(Optional) You may specify folder with your platform specific assets
      config: 'www/config.xml',
      cordova: '.cordova',
      cli: 'cordova', // (Optional) Default to `phonegap local`
      html : 'index.html', // (Optional) You may change this to any other.html
      path: 'phonegap',
      cleanBeforeBuild: true // when false the build path doesn't get regenerated
      plugins: [
        '/local/path/to/plugin', 
        'http://example.com/path/to/plugin.git',
        {
          id: 'git://example.com/example/repository',
          variables: [
            {
              name: 'APP_ID',
              value: 'EXAMPLE_ID'
            },
            {
              name: 'CLIENT_KEY',
              value: 'EXAMPLE_KEY'
            }
          ]
        }
      ],
      platforms: ['android'],
      maxBuffer: 200, // You may need to raise this for iOS.
      verbose: false,
      releases: 'releases',
      releaseName: function(){
        var pkg = grunt.file.readJSON('package.json');
        return(pkg.name + '-' + pkg.version);
      },
      debuggable: false,
      // custom properties overriding AndroidManifest.xml
      androidManifest: {
        // properties added to <application>
        application : {
        },
        // properties added to <activity>
        activity : {
          "android:launchMode":"singleTask" // This is necessary to force single app instance.
        }
      },
      // Must be set for ios to work.
      // Should return the app name.
      name: function(){
        var pkg = grunt.file.readJSON('package.json');
        return pkg.name;
      },

      // Add a key if you plan to use the `release:android` task
      // See http://developer.android.com/tools/publishing/app-signing.html
      key: {
        store: 'release.keystore',
        alias: 'release',
        aliasPassword: function(){
          // Prompt, read an environment variable, or just embed as a string literal
          return('');
        },
        storePassword: function(){
          // Prompt, read an environment variable, or just embed as a string literal
          return('');
        }
      },

      // Set an app icon at various sizes (optional)
      icons: {
        android: {
          ldpi: 'icon-36-ldpi.png',
          mdpi: 'icon-48-mdpi.png',
          hdpi: 'icon-72-hdpi.png',
          xhdpi: 'icon-96-xhdpi.png'
        },
        wp8: {
          app: 'icon-62-tile.png',
          tile: 'icon-173-tile.png'
        },
        ios: {
          icon29: 'icon29.png',
          icon29x2: 'icon29x2.png',
          icon40: 'icon40.png',
          icon40x2: 'icon40x2.png',
          icon50: 'icon50.png',
          icon50x2: 'icon50x2.png',
          icon57: 'icon57.png',
          icon57x2: 'icon57x2.png',
          icon60: 'icon60.png',
          icon60x2: 'icon60x2.png',
          icon60x3: 'icon60x2.png',
          icon72: 'icon72.png',
          icon72x2: 'icon72x2.png',
          icon76: 'icon76.png',
          icon76x2: 'icon76x2.png'
        }
      },

      // Set a splash screen at various sizes (optional)
      // Only works for Android and IOS
      screens: {
        android: {
          ldpi: 'screen-ldpi-portrait.png',
          // landscape version
          ldpiLand: 'screen-ldpi-landscape.png',
          mdpi: 'screen-mdpi-portrait.png',
          // landscape version
          mdpiLand: 'screen-mdpi-landscape.png',
          hdpi: 'screen-hdpi-portrait.png',
          // landscape version
          hdpiLand: 'screen-hdpi-landscape.png',
          xhdpi: 'screen-xhdpi-portrait.png',
          // landscape version
          xhdpiLand: 'www/screen-xhdpi-landscape.png'
        },
        wp8: 'SplashScreenImage.jpg',
        ios: {
          // ipad landscape
          ipadLand: 'screen-ipad-landscape.png',
          ipadLandx2: 'screen-ipad-landscape-2x.png',
          // ipad portrait
          ipadPortrait: 'screen-ipad-portrait.png',
          ipadPortraitx2: 'screen-ipad-portrait-2x.png',
          // iphone portrait
          iphonePortrait: 'screen-iphone-portrait.png',
          iphonePortraitx2: 'screen-iphone-portrait-2x.png',
          iphone568hx2: 'screen-iphone-568h-2x.png',
          iphone667h: 'screen-iphone-667h.png',
          iphone736h: 'screen-iphone-736h.png'
        }
      },

      // A list of resources to be copied.
      resources : {
        android : [{
          from : 'phonegap/res/files/android', 
          to   : 'res'}
        ]
      },

      // Android-only integer version to increase with each release.
      // See http://developer.android.com/tools/publishing/versioning.html
      versionCode: function(){ return(1) },

      // Android-only options that will override the defaults set by Phonegap in the
      // generated AndroidManifest.xml
      // See https://developer.android.com/guide/topics/manifest/uses-sdk-element.html
      minSdkVersion: function(){ return(10) },
      targetSdkVersion: function(){ return(19) },

      // iOS7-only options that will make the status bar white and transparent
      iosStatusBar: 'WhiteAndTransparent',

      // If you want to use the Phonegap Build service to build one or more
      // of the platforms specified above, include these options.
      // See https://build.phonegap.com/
      remote: {
        username: 'your_username',
        password: 'your_password',
        platforms: ['android', 'blackberry', 'ios', 'symbian', 'webos', 'wp7']
      },

      // Set an explicit Android permissions list to override the automatic plugin defaults.
      // In most cases, you should omit this setting. See 'Android Permissions' in README.md for details.
      permissions: ['INTERNET', 'ACCESS_COURSE_LOCATION', '...']
    }
  }
})

Dynamic config.xml

[Back To Top]

Beginning with v0.4.1, phonegap.config.config may be either a string or an object.

As a string, the file is copied directly, as with previous versions.

As an object with the keys template<String> and data<Object>, the file at template will be processed using grunt.template.

Example

Gruntfile.js

  // ...
  phonegap: {
    config: {
      config: {
        template: '_myConfig.xml',
        data: {
          id: 'com.grunt-phonegap.example'
          version: grunt.pkg.version
          name: grunt.pkg.name
        }
      }
  // ...

_myConfig.xml

<?xml version='1.0' encoding='utf-8'?>
<widget
  id="<%= id %>"
  version="<%= version %>"
  xmlns="http://www.w3.org/ns/widgets"
  xmlns:gap="http://phonegap.com/ns/1.0">

    <name><%= name %></name>

    <!-- ... -->
</widget>

App Icons

[Back To Top]

If you choose to set phonegap.config.icons with one or more icon sizes, these files will be copied into the appropriate directories to use as your app icon.

You may want to use this feature in conjunction with grunt-rasterize to generate the correctly sized icon files from an SVG source.

Currently this feature supports Android, Windows Phone 8, and iOS.

Example
  phonegap: {
    config: {
      // ...
      icons: {
      	android: {
          ldpi: 'icon-36-ldpi.png',
          mdpi: 'icon-48-mdpi.png',
          hdpi: 'icon-72-hdpi.png',
          xhdpi: 'icon-96-xhdpi.png'
        },
        wp8: {
          app: 'icon-62-tile.png',
          tile: 'icon-173-tile.png'
        },
        ios: {
          icon29: 'icon29.png',
          icon29x2: 'icon29x2.png',
          icon40: 'icon40.png',
          icon40x2: 'icon40x2.png',
          icon50: 'icon50.png',
          icon50x2: 'icon50x2.png',
          icon57: 'icon57.png',
          icon57x2: 'icon57x2.png',
          icon60: 'icon60.png',
          icon60x2: 'icon60x2.png',
          icon60x3: 'icon60x2.png',
          icon72: 'icon72.png',
          icon72x2: 'icon72x2.png',
          icon76: 'icon76.png',
          icon76x2: 'icon76x2.png'
        }
      }
      // ...
    }
  }

versionCode

[Back To Top]

The config-xml documentation from Phonegap Build (the remote build service) indicate that you can set a versionCode for your AndroidManifest.xml file inside your config.xml. However, phonegap just ignores that property.

Google Play will not allow you to upload more than one APK with the same versionCode.

If you set a phonegap.config.versionCode value (function or literal), grunt phonegap:build will post-process the generated AndroidManifest.xml file and set it for you.

In most applications it should simply be an integer that you increment with each release.

See http://developer.android.com/tools/publishing/versioning.html

This option will be ignored for non-Android platforms or when using the remote build service.

Android Debugging

[Back To Top]

When you use phonegap:release to build an apk package for the Android platform, grunt-phonegap will post-process the phonegap-generated AndroidManifest.xml file to set debuggable=false, unless you set the phonegap.config.debuggable option to true.

A debuggable package cannot be published to the Play store. If you want to generate an unsigned, debuggable package for testing on your own devices, you can use the phonegap:debug:android task instead to do this.

This feature exists to ensure we get the intended behavior no matter what Phonegap version you are using. In Phonegap 4.3.x, the release apk is created with debuggable=true regardless of whether a debug certificate was used. In Phonegap 4.4.x, this has been corrected.

minSdkVersion and targetSdkVersion

[Back To Top]

Some Android applications need to force a specific value for minSdkVersion and targetSdkVersion, for example to enable "quirks mode" in Android 4.4's Chrome-based WebView.

Supposedly, Phonegap Build supports this through a config.xml preference like this:

<preference name="android-targetSdkVersion" value="13" />

However, setting this preference appears to have no effect on the output during a local build.

If you set phonegap.config.minSdkVersion and/or phonegap.config.targetSdkVersion, grunt phonegap:build will post-process the generated AndroidManifest.xml file and set it for you.

This option will be ignored for non-Android platforms or when using the remote build service. For remote Android builds, instead try the android-targetSdkVersion preference mentioned above.

Android Permissions

[Back To Top]

If phonegap.config.permissions is omitted, plugin permissions will be set automatically by Phonegap. In most cases, this is what you want.

Ordinarily with Phonegap (local), permissions for the Android platform are written to AndroidManifest.xml based on the requirements of the plugins that you have added to your project, so you do not have to worry about them.

In some (perhaps unusual) situations, you may want to alter these permissions without modifying a plugin.

When you may want to do this:

  • To reserve not-yet-used permissions during development
  • To enable a plugin that does not require the right permissions for your target version of Android
  • While troubleshooting a permissions error in your app.
  • When using an advanced Grunt workflow to set your permissions for different builds dynamically (by specifying phonegap.config.permissions as a function)

If you need this feature, set phonegap.config.permissions to an array of permission basenames, such as ['ACCESS_NETWORK_STATE'].

When phonegap.config.permissions is set, all permissions added by Cordova + plugins will be removed, giving you complete control over the permission manifest.

This means you need to explicitely add any permissions required by plugins, or your app will not work.

Be careful to check any permissions your plugins need before adding this feature to your app, and remember to update it when adding additional plugins later.

If you are using the Phonegap Build cloud service for the Android platform, this setting will have no effect.

Android Screen Orientation

[Back To Top]

If you need to specify the screen orientation for your app on the Android platform, you may set a value for phonegap.config.screenOrientation to cause grunt-phonegap to post-process the generated AndroidManifest.xml and set the correct value for you.

The value can be any one of the following strings:

  • unspecified
  • behind
  • landscape
  • portrait
  • reverseLandscape
  • reversePortrait
  • sensorLandscape
  • sensorPortrait
  • userLandscape
  • userPortrait
  • sensor
  • fullSensor
  • nosensor
  • user
  • fullUser
  • locked

For an explanation of these options, refer to the android:screenOrientation section of in the Android developer guide.

This option will be ignored for non-Android platforms or when using the remote build service.

Application Name

[Back To Top]

If phonegap.config.androidApplicationName is a string or function, then it will be applied to the <application android:name /> attribute in your AndroidManifest.xml.

This option should almost always be left undefined. You will only need to set this if you are implementing a base plugin (a Java class extending from android.app.Application), for example to implement crash reporting with ACRA.

Phonegap Build

[Back To Top]

If you set phonegap.config.remote to a subset of phonegap.config.platforms, those platforms will be built remotely. This is still somewhat experimental, and may not integrate with all local features.

If you use Phonegap Build, you should add your Phonegap App ID to your .cordova/config.json file - otherwise each build will be treated as a new app toward your account quota.

Example: {"lib":{"www":{"id":"phonegap","version":"3.3.0"}}, "phonegap": {"id": 1234567}}

You can find the PhoneGap App ID in your PhoneGap Builds panel.

Tasks

[Back To Top]

phonegap:build[:platform]

Running phonegap:build with no arguments will...

  • Purge your phonegap.config.path
  • Copy your phonegap.config.cordova and phonegap.config.root files into it
  • Add any plugins listed in phonegap.config.plugins
  • ..and then generate a Phonegap build for all platforms listed in phonegap.config.platforms

If you pass a specific platform as an argument (eg grunt phonegap:build:android), the phonegap.config.platforms array will be ignored and only that specific platform will be built.

Note that by default the project will be built with phonegap local but you can switch to cordova, by setting the phonegap.config.cli to cordova. But it won't let you remote build on phonegap build servers.

phonegap:run[:platform][:device]

After a build is complete, the phonegap:run grunt task can be used to launch your app on an emulator or hardware device. It accepts two optional arguments, platform and device.

Example: grunt phonegap:run:android:emulator

If you are using the Android platform, you can see the list of connected devices by running adb devices.

The platform argument will default to the first platform listed in phonegap.config.platforms.

phonegap:release[:platform]

Create a releases/ directory containing a signed application package for distribution.

Currently android is the only platform supported by this task. You will need to create a keystore file at phonegap.config.key.store like this:

$ keytool -genkey -v -keystore release.keystore -alias release -keyalg RSA -keysize 2048 -validity 10000

The keytool command will interactively ask you to set store and alias passwords, which must match the return value of phonegap.config.key.aliasPassword and phonegap.config.key.storePassword respectively.

phonegap:debug[:platform]

Creates a releases/debug directory containing an unsigned application package with debugging enabled.

Currently android is the only platform supported by this task.

By browsing to this APK asset from test hardware device, we can quickly install the APK output from our build. Then we use chrome://inspect to inspect the network traffic as an example - this is not possible using the signed APK.

phonegap:login

Log into the Phonegap Build service with the credentials specified at phonegap.config.remote.username and phonegap.config.remote.password.

phonegap:logout

Log out of the Phonegap Build service.

Running the test suite

[Back To Top]

git clone https://github.com/logankoester/grunt-phonegap.git
cd grunt-phonegap
npm install
git submodule init
git submodule update
grunt

Note that not all tests can be run on all platforms. For example, tests depending on the Windows Phone SDK will be skipped if your OS is detected to be non-Windows.

Contributing

[Back To Top]

Fork the repo on Github and open a pull request. Note that the files in tasks/ and test/ are the output of CoffeeScript files in src/, and will be overwritten if edited by hand.

Likewise, README.md is the output of the grunt docs task, and will be overwritten. README updates should be made in the Markdown files under docs/.

Before running the included test suite, you must first run git submodule update --init on your local clone (see above).

Please run grunt build before submitting a pull request. The build output should be included with your changes.

Release History

[Back To Top]

You can find all the changelogs here.

Latest changelog is from v0.15.2.md:

v0.15.2

  • Adds grunt-init-phonegap project template to make it easier to start new projects
  • Updates async and grunt-contrib-nodeunit dependencies

License

[Back To Top]

Copyright (c) 2013-2014 Logan Koester. Released under the MIT license. See LICENSE-MIT for details.

Bitdeli Badge

xrefs funcs top func library users authors Total views Views in the last 24 hours