Open szalishchuk opened 10 years ago
Hey @szalishchuk, I like your suggestion. The reason it isn't already implemented this way already is that I've been using grunt-environment to accomplish the same goal.
Your solution, however, is more standard in the Grunt world, so this is probably a good direction to go.
For grunt-phonegap#1.0.0
(which I have not really been working on, just thinking about, so far), I think we should make a number of breaking changes to the configuration object, to wrap some of the more platform-specific features into their appropriate namespace. For example:
phonegap: {
options: {
icons: {} // Default icons for all environments, all platforms...
}, platforms: {
android: {
// Android-specific options for all environments...
versionCode: {}
keys: {}
icons: {} // Icons specifically themed for Android
}
}
development: {
options: {
icons: {} // Default icons with a badge to indicate "development" builds
}, platforms: {
android: {
icons: {} // Android-specific icons with a badge to indicate "development" builds
}
}
}
}
This is essentially two layers of "profiles", one being named by the end-user and the other being named by the set of supported platforms by Phonegap. It might seem a little contrived in this example, but it gives users a lot of flexibility to configure their projects, and helps clean up the config object's top-level.
How does this look to you?
phonegap.platforms
is a great idea, because it is currently not obvious which option is platform specific and which isn't. Although in this case I would change an order of commands in the grunt task to be grunt phonegap:prod:android:release
instead of grunt phonegap:prod:release:android
to make chaining semantically go through the namespace hierarchy (:prod:android
) and then execute an action on these (:release
). It is also have a flavor of natural language.
Agreed! On Feb 18, 2014 11:30 AM, "Sviatoslav Zalishchuk" notifications@github.com wrote:
Problem
I have two separate directories which I would like grunt-phonegap to use as base directory:
- source code (dev files with comments that I work with)
- dist/webapp which I build with another grunt task. It has everything stripped down to 3 files: index.html, package.js and package.css
So, I would like to be able to build an app in debug mode with full source code files being used. I would also like to include weinre debug script there, which I already do with preprocessing my html file, but it requires grunt-phonegap to point to the right directory. And once I'm ready to make a release and deploy and .apk file, I would like to use my dist/webapp directory, where my assets are as thin as possible.
I don't feel that there's a viable solution with grunt-phonegap at this point to solve this case. Solution
Profile based configuration (or whatever people like to call it) is pretty much a standard for grunt based plugins nowadays, because of, I assume, it is being straightforward and flexible at the same time. I believe grunt-phonegap would benefit from it as well.
Instead of this:
phonegap: { config: { // options ... } }
We could have this:
phonegap: { options: { // Common settings } ,dev: { options: { // Settings that are specific for dev environment } ,someMethod: function() {} // e.g. releaseName } ,prod: { options: { // Settings that are specific for production environment } ,someMethod: function() {} // e.g. releaseName } }
This way we can share common settings and method implementations in general scope and override those on profile level. Profile name is a custom thing that each developer creates for himself. Then, to call a specific setting you need to run the following grunt phonegap[:profileName][:nextOption][:nextOption] So you won't have to change your command chain convention, just add one command with the highest priority. If no profile was specified, then :default option should be used.
At the end of the day we would get the following task to build a release version of the app for android grunt phonegap:dev:release:android or grunt phonegap:prod:release:android
Reply to this email directly or view it on GitHubhttps://github.com/logankoester/grunt-phonegap/issues/54 .
I ended up hacking this in to my project. Here is how I did it:
In gruntfile.coffee:
module.exports = (grunt) ->
target = grunt.option('target') || 'development'
appConfig = require('./native/config').forEnv(target)
grunt.initConfig
phonegap:
config:
root: 'native/www'
config: 'native/www/config.xml'
cordova: 'native/.cordova'
path: appConfig.buildPath()
plugins: ['https://git-wip-us.apache.org/repos/asf/cordova-plugin-device.git'
'https://github.com/mkcode/org.apache.cordova.statusbar'
'https://git-wip-us.apache.org/repos/asf/cordova-plugin-network-information.git']
platforms: ['ios']
maxBuffer: 200 # You may need to raise this for iOS.
verbose: true
releases: 'releases'
releaseName: ->
pkg = grunt.file.readJSON('package.json')
return(pkg.name + '-' + pkg.version)
# Must be set for ios to work.
# Should return the app name.
name: -> appConfig.appName
# pkg = grunt.file.readJSON('package.json')
# return pkg.name
native/config.coffee:
# Set properties for the native app in this file
# GlobalConfig keys are overwritten by specific env keys
_localIP = require('address').ip()
globalConfig =
buildPath: -> 'native-build/myapp-native-' + @env
envConfig =
development:
appName: 'My App - Dev'
appId: 'com.myapp.mobile.development'
mobileRoot: "http://#{_localIP}:3333"
urlRoot: "http://#{_localIP}:5000"
debug: true
serverIP: _localIP
staging:
appName: 'My App - Staging'
appId: 'com.myapp.mobile.staging'
mobileRoot: "http://m.staging.myapp.com"
urlRoot: "https://myapp-staging.herokuapp.com"
production:
appName: 'My App'
appId: 'com.myapp.mobile'
mobileRoot: "http://m.myapp.com"
urlRoot: "https://myapp.com"
extend = (object, properties) ->
for key, val of properties
object[key] = val
object
exports.forEnv = (env) ->
config = extend(globalConfig, envConfig[env])
config['env'] = env
config[env] = true
config
And those mobileRoot and urlRoot properties are fed into an index.html handlebars template that is copied into phonegap before phonegap build is run
Doing it like this allows me to run:
grunt phonegap:build --target staging
and it makes a specific application for that env
Also forgot to mention, for this to work on iOS, the config.xml needs to be handled as well:
In config.xml.hbs:
<?xml version='1.0' encoding='utf-8'?>
<widget id="{{ appId }}" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:gap="http://phonegap.com/ns/1.0">
<name>{{ appName }}</name>
So the build process is:
Interesting hack @mkcode! I've seen at least three ways to do this now, but @szalishchuk is right - Grunt has a standard API for this and it would be ideal if a future version of grunt-phonegap
could adhere to it.
Right now I'm accomplishing this by having a global phonegap variable.
var phonegapConfig = {
dev : {...},
staging : {...},
prod : {...},
}
Which I use with an environment flag:
grunt.initConfig({
phonegap: phonegapConfig[grunt.option('target') || 'dev']
});
I agree that using the standard grunt interface for multiple environments would be nice, but it also makes sense to me how that current phonegap tasks mirror the phonegap cli commands.
:+1:
Problem
I have two separate directories which I would like
grunt-phonegap
to use as base directory:So, I would like to be able to build an app in debug mode with full source code files being used. I would also like to include weinre debug script there, which I already do with preprocessing my html file, but it requires
grunt-phonegap
to point to the right directory. And once I'm ready to make a release and deploy and .apk file, I would like to use mydist/webapp
directory, where my assets are as thin as possible.I don't feel that there's a viable solution with
grunt-phonegap
at this point to solve this case.Solution
Profile based configuration (or whatever people like to call it) is pretty much a standard for grunt based plugins nowadays, because of, I assume, it is being straightforward and flexible at the same time. I believe grunt-phonegap would benefit from it as well.
Instead of this:
We could have this:
This way we can share common settings and method implementations in general scope and override those on profile level. Profile name is a custom thing that each developer creates for himself. Then, to call a specific setting you need to run the following
grunt phonegap[:profileName][:nextOption][:nextOption]
So you won't have to change your command chain convention, just add one command with the highest priority. If no profile was specified, then:default
option should be used.At the end of the day we would get the following task to build a release version of the app for android
grunt phonegap:dev:release:android
orgrunt phonegap:prod:release:android