batman-rails-flo 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (162) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +29 -0
  3. data/Rakefile +2 -0
  4. data/lib/batman-rails-flo.rb +5 -0
  5. data/lib/batman_rails_flo/railtie.rb +9 -0
  6. data/lib/batman_rails_flo/tasks.rake +14 -0
  7. data/lib/batman_rails_flo/version.rb +3 -0
  8. data/vendor/assets/javascripts/batman_rails_flo/flo_server.js +67 -0
  9. data/vendor/assets/javascripts/batman_rails_flo/live_reload.js.coffee +129 -0
  10. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/CNAME +1 -0
  11. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/CONTRIBUTING.md +9 -0
  12. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/LICENSE +22 -0
  13. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/README +50 -0
  14. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/bin/cake +7 -0
  15. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/bin/coffee +7 -0
  16. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/lib/coffee-script/browser.js +134 -0
  17. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/lib/coffee-script/cake.js +112 -0
  18. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/lib/coffee-script/coffee-script.js +335 -0
  19. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/lib/coffee-script/command.js +569 -0
  20. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/lib/coffee-script/grammar.js +631 -0
  21. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/lib/coffee-script/helpers.js +252 -0
  22. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/lib/coffee-script/index.js +11 -0
  23. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/lib/coffee-script/lexer.js +926 -0
  24. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/lib/coffee-script/nodes.js +3158 -0
  25. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/lib/coffee-script/optparse.js +139 -0
  26. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/lib/coffee-script/parser.js +724 -0
  27. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/lib/coffee-script/register.js +66 -0
  28. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/lib/coffee-script/repl.js +163 -0
  29. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/lib/coffee-script/rewriter.js +475 -0
  30. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/lib/coffee-script/scope.js +146 -0
  31. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/lib/coffee-script/sourcemap.js +161 -0
  32. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/node_modules/mkdirp/LICENSE +21 -0
  33. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/node_modules/mkdirp/examples/pow.js +6 -0
  34. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/node_modules/mkdirp/index.js +82 -0
  35. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/node_modules/mkdirp/package.json +34 -0
  36. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/node_modules/mkdirp/readme.markdown +63 -0
  37. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/node_modules/mkdirp/test/chmod.js +38 -0
  38. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/node_modules/mkdirp/test/clobber.js +37 -0
  39. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/node_modules/mkdirp/test/mkdirp.js +28 -0
  40. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/node_modules/mkdirp/test/perm.js +32 -0
  41. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/node_modules/mkdirp/test/perm_sync.js +39 -0
  42. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/node_modules/mkdirp/test/race.js +41 -0
  43. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/node_modules/mkdirp/test/rel.js +32 -0
  44. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/node_modules/mkdirp/test/return.js +25 -0
  45. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/node_modules/mkdirp/test/return_sync.js +24 -0
  46. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/node_modules/mkdirp/test/root.js +18 -0
  47. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/node_modules/mkdirp/test/sync.js +32 -0
  48. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/node_modules/mkdirp/test/umask.js +28 -0
  49. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/node_modules/mkdirp/test/umask_sync.js +32 -0
  50. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/package.json +50 -0
  51. data/vendor/assets/javascripts/batman_rails_flo/node_modules/coffee-script/register.js +1 -0
  52. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/LICENSE +30 -0
  53. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/PATENTS +23 -0
  54. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/README.md +124 -0
  55. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/bin/flo +26 -0
  56. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/client/configure/configure.html +57 -0
  57. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/client/configure/configure.js +205 -0
  58. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/client/configure/style.css +334 -0
  59. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/client/connection.js +235 -0
  60. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/client/devtools.html +12 -0
  61. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/client/index.js +323 -0
  62. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/client/logger.js +42 -0
  63. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/client/logo.png +0 -0
  64. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/client/manifest.json +13 -0
  65. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/client/session.js +305 -0
  66. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/index.js +10 -0
  67. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/lib/flo.js +226 -0
  68. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/lib/server.js +94 -0
  69. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/README.md +66 -0
  70. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/index.js +437 -0
  71. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/LICENSE +23 -0
  72. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/README.md +218 -0
  73. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/minimatch.js +1055 -0
  74. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/node_modules/lru-cache/CONTRIBUTORS +14 -0
  75. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/node_modules/lru-cache/LICENSE +23 -0
  76. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/node_modules/lru-cache/README.md +97 -0
  77. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/node_modules/lru-cache/lib/lru-cache.js +252 -0
  78. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/node_modules/lru-cache/package.json +33 -0
  79. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/node_modules/lru-cache/test/basic.js +369 -0
  80. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/node_modules/lru-cache/test/foreach.js +52 -0
  81. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/node_modules/lru-cache/test/memory-leak.js +50 -0
  82. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/node_modules/sigmund/LICENSE +27 -0
  83. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/node_modules/sigmund/README.md +53 -0
  84. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/node_modules/sigmund/bench.js +283 -0
  85. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/node_modules/sigmund/package.json +42 -0
  86. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/node_modules/sigmund/sigmund.js +39 -0
  87. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/node_modules/sigmund/test/basic.js +24 -0
  88. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/package.json +40 -0
  89. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/test/basic.js +399 -0
  90. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/test/brace-expand.js +33 -0
  91. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/test/caching.js +14 -0
  92. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/test/defaults.js +274 -0
  93. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/minimatch/test/extglob-ending-with-state-char.js +8 -0
  94. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/walker/lib/walker.js +111 -0
  95. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/walker/license +13 -0
  96. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/walker/node_modules/makeerror/lib/makeerror.js +87 -0
  97. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/walker/node_modules/makeerror/node_modules/tmpl/lib/tmpl.js +17 -0
  98. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/walker/node_modules/makeerror/node_modules/tmpl/package.json +31 -0
  99. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/walker/node_modules/makeerror/node_modules/tmpl/readme.md +10 -0
  100. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/walker/node_modules/makeerror/package.json +34 -0
  101. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/walker/node_modules/makeerror/readme.md +77 -0
  102. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/walker/package.json +36 -0
  103. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/walker/readme.md +52 -0
  104. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/watch/LICENSE +55 -0
  105. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/watch/main.js +128 -0
  106. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/watch/package.json +34 -0
  107. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/watch/readme.mkd +72 -0
  108. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/watch/test/d/d/t +0 -0
  109. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/watch/test/d/t +0 -0
  110. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/watch/test/test_monitor.js +31 -0
  111. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/watch/test/test_monitorRootDirectory.js +28 -0
  112. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/node_modules/watch/test/test_watchTree.js +20 -0
  113. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/package.json +45 -0
  114. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/sane/test/test.js +243 -0
  115. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/CHANGELOG.md +81 -0
  116. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/LICENSE +177 -0
  117. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/Makefile +11 -0
  118. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/README.md +245 -0
  119. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/binding.gyp +14 -0
  120. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/build/Makefile +355 -0
  121. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/build/Release/linker.lock +0 -0
  122. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/build/Release/obj.target/validation/src/validation.o +0 -0
  123. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/build/Release/obj.target/xor/src/xor.o +0 -0
  124. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/build/Release/validation.node +0 -0
  125. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/build/Release/xor.node +0 -0
  126. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/build/binding.Makefile +6 -0
  127. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/build/config.gypi +115 -0
  128. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/build/gyp-mac-tool +512 -0
  129. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/build/validation.target.mk +154 -0
  130. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/build/xor.target.mk +154 -0
  131. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/index.js +1 -0
  132. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/install.js +31 -0
  133. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/lib/Constants.js +23 -0
  134. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/lib/Deprecation.js +38 -0
  135. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/lib/Validation.fallback.js +12 -0
  136. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/lib/Validation.js +18 -0
  137. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/lib/WebSocketClient.js +359 -0
  138. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/lib/WebSocketConnection.js +717 -0
  139. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/lib/WebSocketFrame.js +282 -0
  140. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/lib/WebSocketRequest.js +478 -0
  141. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/lib/WebSocketRouter.js +154 -0
  142. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/lib/WebSocketRouterRequest.js +59 -0
  143. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/lib/WebSocketServer.js +216 -0
  144. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/lib/utils.js +7 -0
  145. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/lib/websocket.js +11 -0
  146. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/lib/xor.fallback.js +13 -0
  147. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/lib/xor.js +18 -0
  148. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/package.json +43 -0
  149. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/src/validation.cc +144 -0
  150. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/src/xor.cpp +86 -0
  151. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/vendor/FastBufferList.js +192 -0
  152. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/vendor/node-ctype/LICENSE +18 -0
  153. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/node_modules/websocket/vendor/node-ctype/ctio-faster.js +1126 -0
  154. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/package.json +25 -0
  155. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/test/client/browser_websocket.js +63 -0
  156. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/test/client/connection_test.js +57 -0
  157. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/test/client/logger_mock.js +15 -0
  158. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/test/client/session_test.js +194 -0
  159. data/vendor/assets/javascripts/batman_rails_flo/node_modules/fb-flo/test/server/flo_test.js +211 -0
  160. data/vendor/assets/javascripts/batman_rails_flo/package.json +15 -0
  161. data/vendor/assets/javascripts/batman_rails_flo/reload_event_handler.js.coffee +56 -0
  162. metadata +232 -0
@@ -0,0 +1,512 @@
1
+ #!/usr/bin/env python
2
+ # Generated by gyp. Do not edit.
3
+ # Copyright (c) 2012 Google Inc. All rights reserved.
4
+ # Use of this source code is governed by a BSD-style license that can be
5
+ # found in the LICENSE file.
6
+
7
+ """Utility functions to perform Xcode-style build steps.
8
+
9
+ These functions are executed via gyp-mac-tool when using the Makefile generator.
10
+ """
11
+
12
+ import fcntl
13
+ import fnmatch
14
+ import glob
15
+ import json
16
+ import os
17
+ import plistlib
18
+ import re
19
+ import shutil
20
+ import string
21
+ import subprocess
22
+ import sys
23
+ import tempfile
24
+
25
+
26
+ def main(args):
27
+ executor = MacTool()
28
+ exit_code = executor.Dispatch(args)
29
+ if exit_code is not None:
30
+ sys.exit(exit_code)
31
+
32
+
33
+ class MacTool(object):
34
+ """This class performs all the Mac tooling steps. The methods can either be
35
+ executed directly, or dispatched from an argument list."""
36
+
37
+ def Dispatch(self, args):
38
+ """Dispatches a string command to a method."""
39
+ if len(args) < 1:
40
+ raise Exception("Not enough arguments")
41
+
42
+ method = "Exec%s" % self._CommandifyName(args[0])
43
+ return getattr(self, method)(*args[1:])
44
+
45
+ def _CommandifyName(self, name_string):
46
+ """Transforms a tool name like copy-info-plist to CopyInfoPlist"""
47
+ return name_string.title().replace('-', '')
48
+
49
+ def ExecCopyBundleResource(self, source, dest):
50
+ """Copies a resource file to the bundle/Resources directory, performing any
51
+ necessary compilation on each resource."""
52
+ extension = os.path.splitext(source)[1].lower()
53
+ if os.path.isdir(source):
54
+ # Copy tree.
55
+ # TODO(thakis): This copies file attributes like mtime, while the
56
+ # single-file branch below doesn't. This should probably be changed to
57
+ # be consistent with the single-file branch.
58
+ if os.path.exists(dest):
59
+ shutil.rmtree(dest)
60
+ shutil.copytree(source, dest)
61
+ elif extension == '.xib':
62
+ return self._CopyXIBFile(source, dest)
63
+ elif extension == '.storyboard':
64
+ return self._CopyXIBFile(source, dest)
65
+ elif extension == '.strings':
66
+ self._CopyStringsFile(source, dest)
67
+ else:
68
+ shutil.copy(source, dest)
69
+
70
+ def _CopyXIBFile(self, source, dest):
71
+ """Compiles a XIB file with ibtool into a binary plist in the bundle."""
72
+
73
+ # ibtool sometimes crashes with relative paths. See crbug.com/314728.
74
+ base = os.path.dirname(os.path.realpath(__file__))
75
+ if os.path.relpath(source):
76
+ source = os.path.join(base, source)
77
+ if os.path.relpath(dest):
78
+ dest = os.path.join(base, dest)
79
+
80
+ args = ['xcrun', 'ibtool', '--errors', '--warnings', '--notices',
81
+ '--output-format', 'human-readable-text', '--compile', dest, source]
82
+ ibtool_section_re = re.compile(r'/\*.*\*/')
83
+ ibtool_re = re.compile(r'.*note:.*is clipping its content')
84
+ ibtoolout = subprocess.Popen(args, stdout=subprocess.PIPE)
85
+ current_section_header = None
86
+ for line in ibtoolout.stdout:
87
+ if ibtool_section_re.match(line):
88
+ current_section_header = line
89
+ elif not ibtool_re.match(line):
90
+ if current_section_header:
91
+ sys.stdout.write(current_section_header)
92
+ current_section_header = None
93
+ sys.stdout.write(line)
94
+ return ibtoolout.returncode
95
+
96
+ def _CopyStringsFile(self, source, dest):
97
+ """Copies a .strings file using iconv to reconvert the input into UTF-16."""
98
+ input_code = self._DetectInputEncoding(source) or "UTF-8"
99
+
100
+ # Xcode's CpyCopyStringsFile / builtin-copyStrings seems to call
101
+ # CFPropertyListCreateFromXMLData() behind the scenes; at least it prints
102
+ # CFPropertyListCreateFromXMLData(): Old-style plist parser: missing
103
+ # semicolon in dictionary.
104
+ # on invalid files. Do the same kind of validation.
105
+ import CoreFoundation
106
+ s = open(source, 'rb').read()
107
+ d = CoreFoundation.CFDataCreate(None, s, len(s))
108
+ _, error = CoreFoundation.CFPropertyListCreateFromXMLData(None, d, 0, None)
109
+ if error:
110
+ return
111
+
112
+ fp = open(dest, 'wb')
113
+ fp.write(s.decode(input_code).encode('UTF-16'))
114
+ fp.close()
115
+
116
+ def _DetectInputEncoding(self, file_name):
117
+ """Reads the first few bytes from file_name and tries to guess the text
118
+ encoding. Returns None as a guess if it can't detect it."""
119
+ fp = open(file_name, 'rb')
120
+ try:
121
+ header = fp.read(3)
122
+ except e:
123
+ fp.close()
124
+ return None
125
+ fp.close()
126
+ if header.startswith("\xFE\xFF"):
127
+ return "UTF-16"
128
+ elif header.startswith("\xFF\xFE"):
129
+ return "UTF-16"
130
+ elif header.startswith("\xEF\xBB\xBF"):
131
+ return "UTF-8"
132
+ else:
133
+ return None
134
+
135
+ def ExecCopyInfoPlist(self, source, dest, *keys):
136
+ """Copies the |source| Info.plist to the destination directory |dest|."""
137
+ # Read the source Info.plist into memory.
138
+ fd = open(source, 'r')
139
+ lines = fd.read()
140
+ fd.close()
141
+
142
+ # Insert synthesized key/value pairs (e.g. BuildMachineOSBuild).
143
+ plist = plistlib.readPlistFromString(lines)
144
+ if keys:
145
+ plist = dict(plist.items() + json.loads(keys[0]).items())
146
+ lines = plistlib.writePlistToString(plist)
147
+
148
+ # Go through all the environment variables and replace them as variables in
149
+ # the file.
150
+ IDENT_RE = re.compile('[/\s]')
151
+ for key in os.environ:
152
+ if key.startswith('_'):
153
+ continue
154
+ evar = '${%s}' % key
155
+ evalue = os.environ[key]
156
+ lines = string.replace(lines, evar, evalue)
157
+
158
+ # Xcode supports various suffices on environment variables, which are
159
+ # all undocumented. :rfc1034identifier is used in the standard project
160
+ # template these days, and :identifier was used earlier. They are used to
161
+ # convert non-url characters into things that look like valid urls --
162
+ # except that the replacement character for :identifier, '_' isn't valid
163
+ # in a URL either -- oops, hence :rfc1034identifier was born.
164
+ evar = '${%s:identifier}' % key
165
+ evalue = IDENT_RE.sub('_', os.environ[key])
166
+ lines = string.replace(lines, evar, evalue)
167
+
168
+ evar = '${%s:rfc1034identifier}' % key
169
+ evalue = IDENT_RE.sub('-', os.environ[key])
170
+ lines = string.replace(lines, evar, evalue)
171
+
172
+ # Remove any keys with values that haven't been replaced.
173
+ lines = lines.split('\n')
174
+ for i in range(len(lines)):
175
+ if lines[i].strip().startswith("<string>${"):
176
+ lines[i] = None
177
+ lines[i - 1] = None
178
+ lines = '\n'.join(filter(lambda x: x is not None, lines))
179
+
180
+ # Write out the file with variables replaced.
181
+ fd = open(dest, 'w')
182
+ fd.write(lines)
183
+ fd.close()
184
+
185
+ # Now write out PkgInfo file now that the Info.plist file has been
186
+ # "compiled".
187
+ self._WritePkgInfo(dest)
188
+
189
+ def _WritePkgInfo(self, info_plist):
190
+ """This writes the PkgInfo file from the data stored in Info.plist."""
191
+ plist = plistlib.readPlist(info_plist)
192
+ if not plist:
193
+ return
194
+
195
+ # Only create PkgInfo for executable types.
196
+ package_type = plist['CFBundlePackageType']
197
+ if package_type != 'APPL':
198
+ return
199
+
200
+ # The format of PkgInfo is eight characters, representing the bundle type
201
+ # and bundle signature, each four characters. If that is missing, four
202
+ # '?' characters are used instead.
203
+ signature_code = plist.get('CFBundleSignature', '????')
204
+ if len(signature_code) != 4: # Wrong length resets everything, too.
205
+ signature_code = '?' * 4
206
+
207
+ dest = os.path.join(os.path.dirname(info_plist), 'PkgInfo')
208
+ fp = open(dest, 'w')
209
+ fp.write('%s%s' % (package_type, signature_code))
210
+ fp.close()
211
+
212
+ def ExecFlock(self, lockfile, *cmd_list):
213
+ """Emulates the most basic behavior of Linux's flock(1)."""
214
+ # Rely on exception handling to report errors.
215
+ fd = os.open(lockfile, os.O_RDONLY|os.O_NOCTTY|os.O_CREAT, 0o666)
216
+ fcntl.flock(fd, fcntl.LOCK_EX)
217
+ return subprocess.call(cmd_list)
218
+
219
+ def ExecFilterLibtool(self, *cmd_list):
220
+ """Calls libtool and filters out '/path/to/libtool: file: foo.o has no
221
+ symbols'."""
222
+ libtool_re = re.compile(r'^.*libtool: file: .* has no symbols$')
223
+ libtoolout = subprocess.Popen(cmd_list, stderr=subprocess.PIPE)
224
+ _, err = libtoolout.communicate()
225
+ for line in err.splitlines():
226
+ if not libtool_re.match(line):
227
+ print >>sys.stderr, line
228
+ return libtoolout.returncode
229
+
230
+ def ExecPackageFramework(self, framework, version):
231
+ """Takes a path to Something.framework and the Current version of that and
232
+ sets up all the symlinks."""
233
+ # Find the name of the binary based on the part before the ".framework".
234
+ binary = os.path.basename(framework).split('.')[0]
235
+
236
+ CURRENT = 'Current'
237
+ RESOURCES = 'Resources'
238
+ VERSIONS = 'Versions'
239
+
240
+ if not os.path.exists(os.path.join(framework, VERSIONS, version, binary)):
241
+ # Binary-less frameworks don't seem to contain symlinks (see e.g.
242
+ # chromium's out/Debug/org.chromium.Chromium.manifest/ bundle).
243
+ return
244
+
245
+ # Move into the framework directory to set the symlinks correctly.
246
+ pwd = os.getcwd()
247
+ os.chdir(framework)
248
+
249
+ # Set up the Current version.
250
+ self._Relink(version, os.path.join(VERSIONS, CURRENT))
251
+
252
+ # Set up the root symlinks.
253
+ self._Relink(os.path.join(VERSIONS, CURRENT, binary), binary)
254
+ self._Relink(os.path.join(VERSIONS, CURRENT, RESOURCES), RESOURCES)
255
+
256
+ # Back to where we were before!
257
+ os.chdir(pwd)
258
+
259
+ def _Relink(self, dest, link):
260
+ """Creates a symlink to |dest| named |link|. If |link| already exists,
261
+ it is overwritten."""
262
+ if os.path.lexists(link):
263
+ os.remove(link)
264
+ os.symlink(dest, link)
265
+
266
+ def ExecCodeSignBundle(self, key, resource_rules, entitlements, provisioning):
267
+ """Code sign a bundle.
268
+
269
+ This function tries to code sign an iOS bundle, following the same
270
+ algorithm as Xcode:
271
+ 1. copy ResourceRules.plist from the user or the SDK into the bundle,
272
+ 2. pick the provisioning profile that best match the bundle identifier,
273
+ and copy it into the bundle as embedded.mobileprovision,
274
+ 3. copy Entitlements.plist from user or SDK next to the bundle,
275
+ 4. code sign the bundle.
276
+ """
277
+ resource_rules_path = self._InstallResourceRules(resource_rules)
278
+ substitutions, overrides = self._InstallProvisioningProfile(
279
+ provisioning, self._GetCFBundleIdentifier())
280
+ entitlements_path = self._InstallEntitlements(
281
+ entitlements, substitutions, overrides)
282
+ subprocess.check_call([
283
+ 'codesign', '--force', '--sign', key, '--resource-rules',
284
+ resource_rules_path, '--entitlements', entitlements_path,
285
+ os.path.join(
286
+ os.environ['TARGET_BUILD_DIR'],
287
+ os.environ['FULL_PRODUCT_NAME'])])
288
+
289
+ def _InstallResourceRules(self, resource_rules):
290
+ """Installs ResourceRules.plist from user or SDK into the bundle.
291
+
292
+ Args:
293
+ resource_rules: string, optional, path to the ResourceRules.plist file
294
+ to use, default to "${SDKROOT}/ResourceRules.plist"
295
+
296
+ Returns:
297
+ Path to the copy of ResourceRules.plist into the bundle.
298
+ """
299
+ source_path = resource_rules
300
+ target_path = os.path.join(
301
+ os.environ['BUILT_PRODUCTS_DIR'],
302
+ os.environ['CONTENTS_FOLDER_PATH'],
303
+ 'ResourceRules.plist')
304
+ if not source_path:
305
+ source_path = os.path.join(
306
+ os.environ['SDKROOT'], 'ResourceRules.plist')
307
+ shutil.copy2(source_path, target_path)
308
+ return target_path
309
+
310
+ def _InstallProvisioningProfile(self, profile, bundle_identifier):
311
+ """Installs embedded.mobileprovision into the bundle.
312
+
313
+ Args:
314
+ profile: string, optional, short name of the .mobileprovision file
315
+ to use, if empty or the file is missing, the best file installed
316
+ will be used
317
+ bundle_identifier: string, value of CFBundleIdentifier from Info.plist
318
+
319
+ Returns:
320
+ A tuple containing two dictionary: variables substitutions and values
321
+ to overrides when generating the entitlements file.
322
+ """
323
+ source_path, provisioning_data, team_id = self._FindProvisioningProfile(
324
+ profile, bundle_identifier)
325
+ target_path = os.path.join(
326
+ os.environ['BUILT_PRODUCTS_DIR'],
327
+ os.environ['CONTENTS_FOLDER_PATH'],
328
+ 'embedded.mobileprovision')
329
+ shutil.copy2(source_path, target_path)
330
+ substitutions = self._GetSubstitutions(bundle_identifier, team_id + '.')
331
+ return substitutions, provisioning_data['Entitlements']
332
+
333
+ def _FindProvisioningProfile(self, profile, bundle_identifier):
334
+ """Finds the .mobileprovision file to use for signing the bundle.
335
+
336
+ Checks all the installed provisioning profiles (or if the user specified
337
+ the PROVISIONING_PROFILE variable, only consult it) and select the most
338
+ specific that correspond to the bundle identifier.
339
+
340
+ Args:
341
+ profile: string, optional, short name of the .mobileprovision file
342
+ to use, if empty or the file is missing, the best file installed
343
+ will be used
344
+ bundle_identifier: string, value of CFBundleIdentifier from Info.plist
345
+
346
+ Returns:
347
+ A tuple of the path to the selected provisioning profile, the data of
348
+ the embedded plist in the provisioning profile and the team identifier
349
+ to use for code signing.
350
+
351
+ Raises:
352
+ SystemExit: if no .mobileprovision can be used to sign the bundle.
353
+ """
354
+ profiles_dir = os.path.join(
355
+ os.environ['HOME'], 'Library', 'MobileDevice', 'Provisioning Profiles')
356
+ if not os.path.isdir(profiles_dir):
357
+ print >>sys.stderr, (
358
+ 'cannot find mobile provisioning for %s' % bundle_identifier)
359
+ sys.exit(1)
360
+ provisioning_profiles = None
361
+ if profile:
362
+ profile_path = os.path.join(profiles_dir, profile + '.mobileprovision')
363
+ if os.path.exists(profile_path):
364
+ provisioning_profiles = [profile_path]
365
+ if not provisioning_profiles:
366
+ provisioning_profiles = glob.glob(
367
+ os.path.join(profiles_dir, '*.mobileprovision'))
368
+ valid_provisioning_profiles = {}
369
+ for profile_path in provisioning_profiles:
370
+ profile_data = self._LoadProvisioningProfile(profile_path)
371
+ app_id_pattern = profile_data.get(
372
+ 'Entitlements', {}).get('application-identifier', '')
373
+ for team_identifier in profile_data.get('TeamIdentifier', []):
374
+ app_id = '%s.%s' % (team_identifier, bundle_identifier)
375
+ if fnmatch.fnmatch(app_id, app_id_pattern):
376
+ valid_provisioning_profiles[app_id_pattern] = (
377
+ profile_path, profile_data, team_identifier)
378
+ if not valid_provisioning_profiles:
379
+ print >>sys.stderr, (
380
+ 'cannot find mobile provisioning for %s' % bundle_identifier)
381
+ sys.exit(1)
382
+ # If the user has multiple provisioning profiles installed that can be
383
+ # used for ${bundle_identifier}, pick the most specific one (ie. the
384
+ # provisioning profile whose pattern is the longest).
385
+ selected_key = max(valid_provisioning_profiles, key=lambda v: len(v))
386
+ return valid_provisioning_profiles[selected_key]
387
+
388
+ def _LoadProvisioningProfile(self, profile_path):
389
+ """Extracts the plist embedded in a provisioning profile.
390
+
391
+ Args:
392
+ profile_path: string, path to the .mobileprovision file
393
+
394
+ Returns:
395
+ Content of the plist embedded in the provisioning profile as a dictionary.
396
+ """
397
+ with tempfile.NamedTemporaryFile() as temp:
398
+ subprocess.check_call([
399
+ 'security', 'cms', '-D', '-i', profile_path, '-o', temp.name])
400
+ return self._LoadPlistMaybeBinary(temp.name)
401
+
402
+ def _LoadPlistMaybeBinary(self, plist_path):
403
+ """Loads into a memory a plist possibly encoded in binary format.
404
+
405
+ This is a wrapper around plistlib.readPlist that tries to convert the
406
+ plist to the XML format if it can't be parsed (assuming that it is in
407
+ the binary format).
408
+
409
+ Args:
410
+ plist_path: string, path to a plist file, in XML or binary format
411
+
412
+ Returns:
413
+ Content of the plist as a dictionary.
414
+ """
415
+ try:
416
+ # First, try to read the file using plistlib that only supports XML,
417
+ # and if an exception is raised, convert a temporary copy to XML and
418
+ # load that copy.
419
+ return plistlib.readPlist(plist_path)
420
+ except:
421
+ pass
422
+ with tempfile.NamedTemporaryFile() as temp:
423
+ shutil.copy2(plist_path, temp.name)
424
+ subprocess.check_call(['plutil', '-convert', 'xml1', temp.name])
425
+ return plistlib.readPlist(temp.name)
426
+
427
+ def _GetSubstitutions(self, bundle_identifier, app_identifier_prefix):
428
+ """Constructs a dictionary of variable substitutions for Entitlements.plist.
429
+
430
+ Args:
431
+ bundle_identifier: string, value of CFBundleIdentifier from Info.plist
432
+ app_identifier_prefix: string, value for AppIdentifierPrefix
433
+
434
+ Returns:
435
+ Dictionary of substitutions to apply when generating Entitlements.plist.
436
+ """
437
+ return {
438
+ 'CFBundleIdentifier': bundle_identifier,
439
+ 'AppIdentifierPrefix': app_identifier_prefix,
440
+ }
441
+
442
+ def _GetCFBundleIdentifier(self):
443
+ """Extracts CFBundleIdentifier value from Info.plist in the bundle.
444
+
445
+ Returns:
446
+ Value of CFBundleIdentifier in the Info.plist located in the bundle.
447
+ """
448
+ info_plist_path = os.path.join(
449
+ os.environ['TARGET_BUILD_DIR'],
450
+ os.environ['INFOPLIST_PATH'])
451
+ info_plist_data = self._LoadPlistMaybeBinary(info_plist_path)
452
+ return info_plist_data['CFBundleIdentifier']
453
+
454
+ def _InstallEntitlements(self, entitlements, substitutions, overrides):
455
+ """Generates and install the ${BundleName}.xcent entitlements file.
456
+
457
+ Expands variables "$(variable)" pattern in the source entitlements file,
458
+ add extra entitlements defined in the .mobileprovision file and the copy
459
+ the generated plist to "${BundlePath}.xcent".
460
+
461
+ Args:
462
+ entitlements: string, optional, path to the Entitlements.plist template
463
+ to use, defaults to "${SDKROOT}/Entitlements.plist"
464
+ substitutions: dictionary, variable substitutions
465
+ overrides: dictionary, values to add to the entitlements
466
+
467
+ Returns:
468
+ Path to the generated entitlements file.
469
+ """
470
+ source_path = entitlements
471
+ target_path = os.path.join(
472
+ os.environ['BUILT_PRODUCTS_DIR'],
473
+ os.environ['PRODUCT_NAME'] + '.xcent')
474
+ if not source_path:
475
+ source_path = os.path.join(
476
+ os.environ['SDKROOT'],
477
+ 'Entitlements.plist')
478
+ shutil.copy2(source_path, target_path)
479
+ data = self._LoadPlistMaybeBinary(target_path)
480
+ data = self._ExpandVariables(data, substitutions)
481
+ if overrides:
482
+ for key in overrides:
483
+ if key not in data:
484
+ data[key] = overrides[key]
485
+ plistlib.writePlist(data, target_path)
486
+ return target_path
487
+
488
+ def _ExpandVariables(self, data, substitutions):
489
+ """Expands variables "$(variable)" in data.
490
+
491
+ Args:
492
+ data: object, can be either string, list or dictionary
493
+ substitutions: dictionary, variable substitutions to perform
494
+
495
+ Returns:
496
+ Copy of data where each references to "$(variable)" has been replaced
497
+ by the corresponding value found in substitutions, or left intact if
498
+ the key was not found.
499
+ """
500
+ if isinstance(data, str):
501
+ for key, value in substitutions.iteritems():
502
+ data = data.replace('$(%s)' % key, value)
503
+ return data
504
+ if isinstance(data, list):
505
+ return [self._ExpandVariables(v, substitutions) for v in data]
506
+ if isinstance(data, dict):
507
+ return dict((k, self._ExpandVariables(data[k],
508
+ substitutions)) for k in data)
509
+ return data
510
+
511
+ if __name__ == '__main__':
512
+ sys.exit(main(sys.argv[1:]))