Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-16620] CLI: Add configurable source for new project templates

GitHub Issuen/a
TypeNew Feature
PriorityCritical
StatusClosed
ResolutionFixed
Resolution Date2014-05-09T17:48:39.000+0000
Affected Version/sn/a
Fix Version/s2014 Sprint 07, 2014 Sprint 07 Tooling, 2014 Sprint 09 Tooling, Release 3.3.0
ComponentsCLI
Labelsqe-testadded
ReporterStephen Feather
AssigneeChris Barber
Created2014-03-12T23:42:29.000+0000
Updated2014-05-30T18:09:51.000+0000

Description

Currently custom templates can be built and placed in the templates folder in the root of each installed SDK. Would like to have an entry called *paths.templates* added to the *config.json* that could be searched for custom templates (and possibly overwrite/overrule those located in the {sdk}/templates folder) when creating a new project. This would allow large enterprise orgs to:

share common project templates across development environments

reduce the time to adopt a new sdk (currently requires moving custom templates to the new sdk on all systems)

reduce required storage space caused by duplication

Attachments

FileDateSize
foo.zip2014-04-01T21:03:08.000+00003135604

Comments

  1. Ricardo Alcocer 2014-03-27

    @Praveen Innamuri should know about this and see if there's a way for Studio to use these CLI functions (TISTUD-6260)
  2. Chris Barber 2014-04-01

    Titanium CLI master pull request: https://github.com/appcelerator/titanium/pull/125 Titanium Mobile master pull request: https://github.com/appcelerator/titanium_mobile/pull/5569
  3. Chris Barber 2014-04-01

    There are a number of new ways to specify templates!

    Default template

    This will use the default template that comes with Titanium Mobile. It basically looks in the SDK's "templates/app" folder.
       ti create
       
       

    -or-

    ti create --template default

    Global template directory

    Now "ti create" will also scan all Titanium install locations for a "templates" directory containing the template you specified:
       /Users/chris/Library/Application Support/Titanium/templates/mytemplate
       
       ti create --template mytemplate
       

    Custom template paths

    You can add more search paths via the paths.templates config option. You set this value to the path containing the templates. In this example, /path/to/mytemplates contains a template called "foo".
       ti config paths.templates /path/to/mytemplates
       
       ti create --template foo
       

    Local directory

       ti create --template /path/to/mytemplates/foo
       

    Local zip file

       ti create --template /path/to/myfootemplate.zip
       

    Remote zip file

       ti create --template http://www.chrisrocks.com/myfootemplate.zip
       

    New Template Structure

    Templates now have a different file structure. You should have a "templates" directory containing all the files that will be automatically copied. You may have a "hooks" folder as well containing a Titanium CLI hook that allows you to tie into one of the several available hooks. Any other directory is ignored, so you could drop a package.json, readme, node_modules, whatever in the template directory.
       ├─┬ hooks <DIR> (optional)
       │ └── mytemplatehook.js (optional)
       └─┬ template <DIR> (should exist)
         ├── Resources <DIR> (should exists, automatically created if it doesn't)
         └── tiapp.xml (should exist, automatically created if it doesn't)
       

    Template Hooks

    Hooks give you the ability to do custom things when creating a project.
       exports.init = function (logger, config, cli, appc) {
       	logger.log('HI FROM FOO HOOK!');
       	
       	cli.on('create.copyFiles', {
       		pre: function (data) {
       			logger.log('COPYING FILES FROM ' + data.args[0] + ' TO ' + data.args[1]);
       		}
       	});
       
       	cli.on('create.populateTiappXml', {
       		pre: function (data) {
       			logger.log('POPULATING TIAPP.XML');
       			dump(data.args[1]);
       			data.args[1].foo = "bar";
       		}
       	});
       
       	cli.on('create.pre.platform.android', function (creator, next) {
       		logger.log(('[EVENT-HOOK] create.pre.platform.android [' + creator.projectType + ']').magenta);
       		next();
       	});
       	cli.on('create.post.platform.android', function (creator, next) {
       		logger.log(('[EVENT-HOOK] create.post.platform.android [' + creator.projectType + ']').magenta);
       		next();
       	});
       
       	// note: current the platform is called "iphone", so this hook won't fire right now
       	cli.on('create.pre.platform.ios', function (creator, next) {
       		logger.log(('[EVENT-HOOK] create.pre.platform.ios [' + creator.projectType + ']').magenta);
       		next();
       	});
       	cli.on('create.post.platform.ios', function (creator, next) {
       		logger.log(('[EVENT-HOOK] create.post.platform.ios [' + creator.projectType + ']').magenta);
       		next();
       	});
       
       	cli.on('create.pre.platform.iphone', function (creator, next) {
       		logger.log(('[EVENT-HOOK] create.pre.platform.iphone [' + creator.projectType + ']').magenta);
       		next();
       	});
       	cli.on('create.post.platform.iphone', function (creator, next) {
       		logger.log(('[EVENT-HOOK] create.post.platform.iphone [' + creator.projectType + ']').magenta);
       		next();
       	});
       
       	cli.on('create.pre.platform.mobileweb', function (creator, next) {
       		logger.log(('[EVENT-HOOK] create.pre.platform.mobileweb [' + creator.projectType + ']').magenta);
       		next();
       	});
       	cli.on('create.post.platform.mobileweb', function (creator, next) {
       		logger.log(('[EVENT-HOOK] create.post.platform.mobileweb [' + creator.projectType + ']').magenta);
       		next();
       	});
       
       	cli.on('create.pre.platform.blackberry', function (creator, next) {
       		logger.log(('[EVENT-HOOK] create.pre.platform.blackberry [' + creator.projectType + ']').magenta);
       		next();
       	});
       	cli.on('create.post.platform.blackberry', function (creator, next) {
       		logger.log(('[EVENT-HOOK] create.post.platform.blackberry [' + creator.projectType + ']').magenta);
       		next();
       	});
       
       	cli.on('create.pre.platform.tizen', function (creator, next) {
       		logger.log(('[EVENT-HOOK] create.pre.platform.tizen [' + creator.projectType + ']').magenta);
       		next();
       	});
       	cli.on('create.post.platform.tizen', function (creator, next) {
       		logger.log(('[EVENT-HOOK] create.post.platform.tizen [' + creator.projectType + ']').magenta);
       		next();
       	});
       
       	cli.on('create.post', function (creator, next) {
       		logger.log(('[EVENT-HOOK] create.post [' + creator.projectType + ']').magenta);
       		next();
       	});
       
       	cli.on('create.finalize', function (creator, next) {
       		logger.log(('[EVENT-HOOK] create.finalize [' + creator.projectType + ']').magenta);
       		next();
       	});
       };
       
    Available FUNCTION hooks: * create.copyFiles ** You can change the source directory being copied ** For example, you may not have a "template" directory, instead you could change it to something else * create.populateTiappXml ** You can tweak properties, add properties, add modules, do whatever you want! Available EVENT hooks: * create.pre.platform.<PLATFORM NAME> ** This will fire for each platform that you are create the project for (i.e. android, iphone, mobileweb, etc) * create.post.platform.<PLATFORM NAME> ** This will fire for each platform that you are create the project for (i.e. android, iphone, mobileweb, etc) * create.post ** Fired after all platforms have finished * create.finalize ** Fired when the creation has completed or errored
  4. Chris Barber 2014-04-01

    Happy [~sfeather]?
  5. Stephen Feather 2014-04-01

    Like the proverbial pig in mud. Thanks man.
  6. Deepti Pandey 2014-04-23

    Reopening this ticket usig following configurations : Mac :10.9.2 Studio - 3.3.0.201404211130 SDK - 3.3.0.v20140422163054 acs-1.0.14 alloy-1.4.0-dev npm-1.3.2 titanium-3.3.0-dev titanium-code-processor-1.1.1-beta1 Xcode :5.1.1 Test steps followed are : 1. Create a folder named "templates" at any location 2. Copy attached example foo.zip (extracted version) 3.On terminal write : ti config paths.templates /path/to/template folder created in first step. 4.ti create --template foo and provide rest of the project creation details 5.Error occured
       /Users/deepti.pandey/Library/Application Support/Titanium/mobilesdk/osx/3.3.0.v20140422163054/cli/lib/creators/app.js:166
       				finalize();
       				^
       TypeError: undefined is not a function
           at AppCreator.<anonymous> (/Users/deepti.pandey/Library/Application Support/Titanium/mobilesdk/osx/3.3.0.v20140422163054/cli/lib/creators/app.js:166:5)
           at /usr/local/lib/node_modules/titanium/node_modules/async/lib/async.js:119:25
           at AppCreator.<anonymous> (/usr/local/lib/node_modules/titanium/node_modules/async/lib/async.js:24:16)
           at CLI._fireHookCallback (/usr/local/lib/node_modules/titanium/lib/hook.js:269:12)
           at /usr/local/lib/node_modules/titanium/lib/hook.js:248:10
           at /usr/local/lib/node_modules/titanium/node_modules/async/lib/async.js:232:13
           at async.eachSeries (/usr/local/lib/node_modules/titanium/node_modules/async/lib/async.js:130:20)
           at _asyncMap (/usr/local/lib/node_modules/titanium/node_modules/async/lib/async.js:226:9)
           at Object.mapSeries (/usr/local/lib/node_modules/titanium/node_modules/async/lib/async.js:216:23)
           at async.series (/usr/local/lib/node_modules/titanium/node_modules/async/lib/async.js:549:19)
       
  7. Ingo Muschenetz 2014-04-28

    [~sfeather] is this working for you? I'm wondering if the reopened report is an edge case.
  8. Stephen Feather 2014-04-28

    @ingo Message seen, will be tomorrow or Wednesday before I can get to it to re-test.
  9. Chris Barber 2014-05-06

    Fixed. Titanium SDK master pull request: https://github.com/appcelerator/titanium_mobile/pull/5661
  10. Olga Romero 2014-05-30

    Tested with: Mac osx 10.9.3 Mavericks Appcelerator Studio, build: 3.3.0.201405271647 Titanium SDK, build: 3.3.0.v20140528144113 Node.JS Version: v0.10.13 NPM Version: 1.3.2 acs@1.0.14 alloy@1.4.0-beta npm@1.3.2 titanium@3.3.0-beta titanium-code-processor@1.1.1

    Actual result

        POPULATING TIAPP.XML
        { id: 'com.appcelerator.olatest',
          name: 'olatest',
          url: 'http://',
          version: '1.0',
          guid: 'e1e932cc-a895-448d-ae6a-8c8cdaa11836',
          'deployment-targets': 
           { android: true,
             blackberry: true,
             ipad: true,
             iphone: true,
             mobileweb: true },
          'sdk-version': '3.3.0.v20140528144113' }
        [INFO]  Writing tiapp.xml
        [INFO]  Project created successfully in 103ms
        

JSON Source