{"id":1212,"date":"2013-07-22T09:40:11","date_gmt":"2013-07-22T15:40:11","guid":{"rendered":"http:\/\/www.mooreds.com\/wordpress\/?p=1212"},"modified":"2013-07-23T14:54:39","modified_gmt":"2013-07-23T20:54:39","slug":"configuration-management-using-cordova-cli","status":"publish","type":"post","link":"https:\/\/www.mooreds.com\/wordpress\/archives\/1212","title":{"rendered":"Configuration management using Cordova CLI"},"content":{"rendered":"<p>Managing different builds of your Cordova application is relatively easy <a href=\"\/wordpress\/archives\/1197\">using hooks<\/a>.  <\/p>\n<p>I actually have a number of deployment environments, all built from my local source tree.<\/p>\n<ul>\n<li>web development, which lets me crank out the non cordova specific look and feel<\/li>\n<li>test, which runs qunit\/sinon unit tests<\/li>\n<li><a href=\"https:\/\/developer.blackberry.com\/html5\/download\/ripple\/\">ripple<\/a> development, which lets me run in the browser, but still test cordova specific events (online\/offline, for example) <\/li>\n<li>staging, which is used to build a phone distributable binary, but runs against our QA servers<\/li>\n<li>production, the same as stage, but against our production servers<\/li>\n<\/ul>\n<p>The first two don&#8217;t require a <code>cordova prepare<\/code> but the last three do.  The first three let you make changes in files and reload your web browser, where the last two require a phone or emulator to run.<\/p>\n<p>For a while I was switching between these manually, but eventually it became a pain, so I automated it.  The automation is driven off an environment variable, which is accessed by a <code>after_prepare<\/code> hook: <code>TARGET=stage cordova build android<\/code> sets target to <code>stage<\/code>, and <code>process.env.TARGET<\/code> is the nodejs code in the hook script that can access that environment variable.<\/p>\n<p>There is a config directory in the top level of the project and in there is a project.json file that contains project specific configuration for each target environment, like the server hostname.<\/p>\n<p>One wrinkle that took me some time to figure out was how to have code that was in the www directory &#8216;just work&#8217; out of the version control system, so I could do quick web development.  In the end, I have code like this in my javascript files<\/p>\n<pre>\r\nApp.config = {};\r\nApp.config.datahostname = \/*REP*\/'qa-host.com'\/*REP*\/;\r\n<\/pre>\n<p>and then this regular expression to replace it with the value from the configuration file when file is being prepared:<\/p>\n<pre>\r\nfunction replace_string_in_file(filename,to_replace,replace_with) {\r\n  var data = fs.readFileSync(filename, 'utf8');\r\n  var result = data.replace(new RegExp(to_replace,\"g\"), replace_with);\r\n  fs.writeFileSync(filename, result, 'utf8');\r\n}\r\n\r\n...\r\n\/\/ iterate over files to be updated with config info\r\nreplace_string_in_file(fullfilename,\"\/\\\\*REP\\\\*\/'qa-host.com'\/\\\\*REP\\\\*\/\",configobj[target].datahostname);\r\n<\/pre>\n<p>Note that I don&#8217;t read\/write files async&#8211;this happens rarely enough that the performance increase isn&#8217;t worth some of the weirdness you will see if more than one hook acts on your file, or if you edit the file right after running the hook.<\/p>\n<p>Since <code>\/*REP*\/stuff\/*REP*\/<\/code> isn&#8217;t likely to match anything inadvertently, you could probably parse all your files, but my configuration is limited to 3-4 files, so it is easier just to name them explicitly.<\/p>\n<p>Note that if during development, your javascript needs to access data served by a different web server (an API somewhere, for example), you&#8217;ll need to set up CORS correctly.  We&#8217;ll set that up in the next blog post.<\/p>\n<p><a href=\"http:\/\/eepurl.com\/BHYJ9\">Subscribe to my infrequent Cordova newsletter<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Managing different builds of your Cordova application is relatively easy using hooks. I actually have a number of deployment environments, all built from my local source tree. web development, which [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[64,7,60],"tags":[],"class_list":["post-1212","post","type-post","status-publish","format-standard","hentry","category-cordova-cli","category-mobile-technology","category-phonegap"],"_links":{"self":[{"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/posts\/1212","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/comments?post=1212"}],"version-history":[{"count":5,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/posts\/1212\/revisions"}],"predecessor-version":[{"id":1286,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/posts\/1212\/revisions\/1286"}],"wp:attachment":[{"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/media?parent=1212"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/categories?post=1212"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/tags?post=1212"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}