Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-15806] Alloy compiler runs twice when installed via titanium-bundle

GitHub Issuen/a
TypeBug
PriorityCritical
StatusClosed
ResolutionWon't Fix
Resolution Date2013-11-24T17:56:06.000+0000
Affected Version/sRelease 3.2.0
Fix Version/sn/a
ComponentsCLI
Labelsalloy, cli, compiler
ReporterFokke Zandbergen
AssigneeChris Barber
Created2013-11-24T13:45:59.000+0000
Updated2017-03-22T21:30:06.000+0000

Description

update

It appears that this only really affects those using the titanium-bundle, as it adds an extra hook for the alloy process, thus causing it to fire twice. All Alloy projects contain their own plugin, so there's no need for anything Alloy-related to be in paths.hooks, otherwise we get problems like this.
paths.hooks                = ["/Users/tlukasavage/Development/node_modules/titanium-bundle/node_modules/alloy/hooks"]
You can see that more than one alloy plugin is found and used in the CLI output when you execute "ti build -p ios":
[DEBUG] Loaded plugin hooks:
[DEBUG] /Users/tlukasavage/Development/node_modules/titanium-bundle/node_modules/alloy/hooks/alloy.js
[DEBUG] /Users/tlukasavage/Development/node_modules/titanium-bundle/node_modules/titanium/hooks/tisdk3fixes.js
[DEBUG] /Users/tlukasavage/Library/Application Support/Titanium/mobilesdk/osx/3.2.0/iphone/cli/hooks/install.js
[DEBUG] /Users/tlukasavage/Library/Application Support/Titanium/mobilesdk/osx/3.2.0/iphone/cli/hooks/package.js
[DEBUG] /Users/tlukasavage/Library/Application Support/Titanium/mobilesdk/osx/3.2.0/iphone/cli/hooks/run.js
[DEBUG] /Users/tlukasavage/Development/twice/plugins/ti.alloy/hooks/alloy.js
Deleting the paths.hooks entry "/Users/tlukasavage/Development/node_modules/titanium-bundle/node_modules/alloy/hooks" causes everything to go back to working as normal. In the end, the titanium-bundle should not be installing hooks for Alloy, and the CLI should have some means of identifying that a hook has already run for the given build.

To reproduce

ti create -p ios -n twice --id test.twice -d .
cd twice
alloy new
ti build -p ios

Analysis

If you remove the Alloy plugin from tiapp.xml it solves the problem for the next build, but then the compiler itself will re-add the plugin, causing the next run to compile twice again.
<plugins>
  <plugin version="1.0">ti.alloy</plugin>
</plugins>

Log

The log showing the compile being done twice:
[INFO]  Forcing rebuild: /Users/zandbergen/dev/tests/twice/build/iphone/build-manifest.json does not exist
[INFO]  Initiating prepare phase
[INFO]  Found Alloy app in /Users/zandbergen/dev/tests/twice/app
[DEBUG] ----- CONFIGURATION -----
[DEBUG] raw config = "platform=ios,version=0,simtype=none,devicefamily=universal,deploytype=development"
[DEBUG] platform = ios
[DEBUG] version = 0
[DEBUG] simtype = none
[DEBUG] devicefamily = universal
[DEBUG] deploytype = development
[DEBUG] project path = /Users/zandbergen/dev/tests/twice
[DEBUG] app path = /Users/zandbergen/dev/tests/twice/app
[DEBUG]
[DEBUG] ----- CONFIG.JSON -----
[DEBUG] {
[DEBUG]   "dependencies": {},
[DEBUG]   "sourcemap": true,
[DEBUG]   "autoStyle": false,
[DEBUG]   "adapters": [
[DEBUG]     "localStorage",
[DEBUG]     "properties",
[DEBUG]     "sql"
[DEBUG]   ]
[DEBUG] }
[DEBUG]
[DEBUG] ----- CLEANING RESOURCES -----
[DEBUG] Removing orphaned controllers...
[DEBUG] Removing orphaned models...
[DEBUG] Removing orphaned styles...
[DEBUG] Removing orphaned sync adapters...
[DEBUG] Removing orphaned assets and libs...
[DEBUG]
[DEBUG] ----- BASE RUNTIME FILES -----
[TRACE] SRC_DIR=/Users/zandbergen/node_modules/titanium-bundle/node_modules/alloy/Alloy/lib
[TRACE] Copying SRC_DIR/alloy.js --> Resources/iphone/alloy.js
[TRACE] Copying SRC_DIR/alloy/backbone.js --> Resources/iphone/alloy/backbone.js
[TRACE] Copying SRC_DIR/alloy/underscore.js --> Resources/iphone/alloy/underscore.js
[TRACE] Copying SRC_DIR/alloy/widget.js --> Resources/iphone/alloy/widget.js
[TRACE] Copying SRC_DIR/alloy/controllers/BaseController.js --> Resources/iphone/alloy/controllers/BaseController.js
[TRACE] Copying SRC_DIR/alloy/sync/localStorage.js --> Resources/iphone/alloy/sync/localStorage.js
[TRACE] Copying SRC_DIR/alloy/sync/properties.js --> Resources/iphone/alloy/sync/properties.js
[TRACE] Copying SRC_DIR/alloy/sync/sql.js --> Resources/iphone/alloy/sync/sql.js
[TRACE]
[TRACE] SRC_DIR=/Users/zandbergen/node_modules/titanium-bundle/node_modules/alloy/Alloy/common
[TRACE] Copying SRC_DIR/constants.js --> Resources/iphone/alloy/constants.js
[TRACE]
[TRACE] SRC_DIR=/Users/zandbergen/dev/tests/twice/app/assets
[TRACE]
[DEBUG]
[INFO] ----- MVC GENERATION -----
[INFO] [global style] loading from cache...
[INFO] [index.xml] view processing...
[INFO]   style:      "index.tss"
[INFO]   view:       "index.xml"
[INFO]   controller: "index.js"
[TRACE] - Processing "builtins" module...
[TRACE] - Processing "optimizer" module...
[TRACE] - Processing "compress" module...
[INFO]   created:    "Resources/iphone/alloy/controllers/index.js"
[DEBUG]   map:        "build/map/Resources/iphone/alloy/controllers/index.js.map"
[INFO]   created:     "Resources/iphone/alloy/styles/index.js"
[INFO]
[INFO] [app.js] using cached app.js...
[INFO]
[INFO] ----- OPTIMIZING -----
[INFO] - iphone/alloy.js
[TRACE]   processing "builtins" module...
[TRACE]   processing "optimizer" module...
[TRACE]   processing "compress" module...
[INFO] - iphone/alloy/sync/localStorage.js
[TRACE]   processing "builtins" module...
[TRACE]   processing "optimizer" module...
[TRACE]   processing "compress" module...
[INFO] - iphone/alloy/sync/properties.js
[TRACE]   processing "builtins" module...
[TRACE]   processing "optimizer" module...
[TRACE]   processing "compress" module...
[INFO] - iphone/alloy/sync/sql.js
[TRACE]   processing "builtins" module...
[TRACE]   processing "optimizer" module...
[TRACE]   processing "compress" module...
[TRACE]
[TRACE] Benchmarking
[TRACE] ------------
[TRACE] [0.67619s] TOTAL
[INFO]
[INFO] Alloy compiled in 0.67619s
[INFO]  Found Alloy app in /Users/zandbergen/dev/tests/twice/app
[INFO]  Executing Alloy compile: /usr/local/bin/node /usr/local/bin/alloy compile /Users/zandbergen/dev/tests/twice/app --config platform=ios,version=0,simtype=none,devicefamily=universal,deploytype=development
[DEBUG]        .__  .__
[DEBUG] _____  |  | |  |   ____ ___.__.
[DEBUG] \__  \ |  | |  |  /  _ <   |  |
[DEBUG]  / __ \|  |_|  |_(  <_> )___  |
[DEBUG] (____  /____/____/\____// ____|
[DEBUG]      \/                 \/
[DEBUG] Alloy 1.3.0 by Appcelerator. The MVC app framework for Titanium.
[DEBUG]
[DEBUG] ----- CONFIGURATION -----
[DEBUG] raw config = "platform=ios,version=0,simtype=none,devicefamily=universal,deploytype=development"
[DEBUG] platform = ios
[DEBUG] version = 0
[DEBUG] simtype = none
[DEBUG] devicefamily = universal
[DEBUG] deploytype = development
[DEBUG] project path = /Users/zandbergen/dev/tests/twice
[DEBUG] app path = /Users/zandbergen/dev/tests/twice/app
[DEBUG]
[DEBUG] ----- CONFIG.JSON -----
[DEBUG] {
[DEBUG]   "dependencies": {},
[DEBUG]   "sourcemap": true,
[DEBUG]   "autoStyle": false,
[DEBUG]   "adapters": [
[DEBUG]     "localStorage",
[DEBUG]     "properties",
[DEBUG]     "sql"
[DEBUG]   ]
[DEBUG] }
[DEBUG]
[DEBUG] ----- CLEANING RESOURCES -----
[DEBUG] Removing orphaned controllers...
[DEBUG] Removing orphaned models...
[DEBUG] Removing orphaned styles...
[DEBUG] Removing orphaned sync adapters...
[DEBUG] Removing orphaned assets and libs...
[DEBUG]
[DEBUG] ----- BASE RUNTIME FILES -----
[TRACE] SRC_DIR=/Users/zandbergen/node_modules/titanium-bundle/node_modules/alloy/Alloy/lib
[TRACE] Copying SRC_DIR/alloy.js --> Resources/iphone/alloy.js
[TRACE] Copying SRC_DIR/alloy/backbone.js --> Resources/iphone/alloy/backbone.js
[TRACE] Copying SRC_DIR/alloy/underscore.js --> Resources/iphone/alloy/underscore.js
[TRACE] Copying SRC_DIR/alloy/widget.js --> Resources/iphone/alloy/widget.js
[TRACE] Copying SRC_DIR/alloy/controllers/BaseController.js --> Resources/iphone/alloy/controllers/BaseController.js
[TRACE] Copying SRC_DIR/alloy/sync/localStorage.js --> Resources/iphone/alloy/sync/localStorage.js
[TRACE] Copying SRC_DIR/alloy/sync/properties.js --> Resources/iphone/alloy/sync/properties.js
[TRACE] Copying SRC_DIR/alloy/sync/sql.js --> Resources/iphone/alloy/sync/sql.js
[TRACE]
[TRACE] SRC_DIR=/Users/zandbergen/node_modules/titanium-bundle/node_modules/alloy/Alloy/common
[TRACE] Copying SRC_DIR/constants.js --> Resources/iphone/alloy/constants.js
[TRACE]
[TRACE] SRC_DIR=/Users/zandbergen/dev/tests/twice/app/assets
[TRACE]
[DEBUG]
[INFO]  ----- MVC GENERATION -----
[INFO]  [global style] loading from cache...
[INFO]  [index.xml] view processing...
[INFO]    style:      "index.tss"
[INFO]    view:       "index.xml"
[INFO]    controller: "index.js"
[TRACE] - Processing "builtins" module...
[TRACE] - Processing "optimizer" module...
[TRACE] - Processing "compress" module...
[INFO]    created:    "Resources/iphone/alloy/controllers/index.js"
[DEBUG]   map:        "build/map/Resources/iphone/alloy/controllers/index.js.map"
[INFO]    created:     "Resources/iphone/alloy/styles/index.js"
[INFO]
[INFO]  [app.js] using cached app.js...
[INFO]
[INFO]  ----- OPTIMIZING -----
[INFO]  - iphone/alloy.js
[TRACE]   processing "builtins" module...
[TRACE]   processing "optimizer" module...
[TRACE]   processing "compress" module...
[INFO]  - iphone/alloy/sync/localStorage.js
[TRACE]   processing "builtins" module...
[TRACE]   processing "optimizer" module...
[TRACE]   processing "compress" module...
[INFO]  - iphone/alloy/sync/properties.js
[TRACE]   processing "builtins" module...
[TRACE]   processing "optimizer" module...
[TRACE]   processing "compress" module...
[INFO]  - iphone/alloy/sync/sql.js
[TRACE]   processing "builtins" module...
[TRACE]   processing "optimizer" module...
[TRACE]   processing "compress" module...
[TRACE]
[TRACE] Benchmarking
[TRACE] ------------
[TRACE] [0.55402s] TOTAL
[INFO]
[INFO]  Alloy compiled in 0.55402s
[INFO]  Alloy compiler completed successfully
[INFO]  Cleaning old build directory
[INFO]  Performing full rebuild
[INFO]  Copying Xcode iOS files
[DEBUG] Copying /Users/zandbergen/Library/Application Support/Titanium/mobilesdk/osx/3.2.0.v20131122172908/iphone/Classes => /Users/zandbergen/dev/tests/twice/build/iphone/Classes

Comments

  1. Tony Lukasavage 2013-11-24

    So it looks like the titanium-bundle is installing any hooks or commands it can find and them to the ti config. This is causing the Alloy hook to be fired twice. Once for the one in the project, once for the one that the titanium-bundle added. This is obviously not the desired behavior. I can hack titanium-bundle to not do this for Alloy, but a better long term solution would be for the CLI to be able to determine if 2 hooks have the same purpose, and when it has access to a global one versus a project-specific one, it should only fire the project specific one.

    workaround

    Execute "ti config", find the extra path.hooks entry for alloy, and delete it.
  2. Chris Barber 2013-11-24

    As far as the CLI is concerned, a CLI plugin hook is just a JavaScript file. It has no idea what the JavaScript file is. There is no notion of a hook name/id or version. There's no way for the CLI to say "hey, you already loaded the Alloy hook" because it doesn't know what an Alloy hook is. Someday we may add a name/id and version to each individual hook, but it would be optional. Since the Alloy hook knows how to identify itself, the Alloy hook should detect if there's already an Alloy hook loaded and if so, return. This can be done by referencing cli.hooks.loadedFilenames or maybe scanning cli.hooks.pre\['build.pre.compile'\] and cli.hooks.post\['build.pre.compile'\] for your callback functions.
  3. Tony Lukasavage 2013-11-24

    I think this should be the job of the CLI, via the means of id and version like you stated. It seems silly to push that responsibility out every single hook, rather than just solve the problem centrally in the CLI, especially when the workarounds you suggest AFAIK are undocumented. The issue in this ticket is addressed for the most part, but the underlying problem IMO needs to be addressed by the CLI, making it a bit more sensible when executing hooks that may be installed globally and locally to the current project.
  4. Chris Barber 2013-11-24

    Maybe the CLI will support it someday. That doesn't solve the problem today that there are plugin hooks in the wild that would not implement these ids and versions. Technically the old plugin system had the same problem. In the meantime, add yourself to the watch list for TIMOB-13847 and maybe it'll land in 3.2.1.
  5. Tony Lukasavage 2013-11-24

    /me subscribed And that's fine if there's some on the wild that don't support the different format. That would be pretty trivial in the CLI to make the distinction between a string entry, which gets no validation, and an entry that is an object containing a name, version, etc...
  6. Lee Morris 2017-03-22

    Closing ticket as Won't Fix.

JSON Source