libv8 6.7.288.46.1 → 7.3.492.27.0beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (408) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +3 -0
  3. data/CHANGELOG.md +4 -0
  4. data/README.md +2 -0
  5. data/ext/libv8/builder.rb +6 -2
  6. data/lib/libv8/version.rb +1 -1
  7. data/vendor/depot_tools/.gitattributes +1 -0
  8. data/vendor/depot_tools/.gitignore +7 -0
  9. data/vendor/depot_tools/CROS_OWNERS +5 -0
  10. data/vendor/depot_tools/OWNERS +12 -1
  11. data/vendor/depot_tools/PRESUBMIT.py +16 -9
  12. data/vendor/depot_tools/README.md +9 -2
  13. data/vendor/depot_tools/autoninja +14 -6
  14. data/vendor/depot_tools/autoninja.bat +11 -1
  15. data/vendor/depot_tools/autoninja.py +40 -18
  16. data/vendor/depot_tools/bb +12 -0
  17. data/vendor/depot_tools/bb.bat +7 -0
  18. data/vendor/depot_tools/bootstrap/win/manifest.txt +1 -1
  19. data/vendor/depot_tools/bootstrap/win/manifest_bleeding_edge.txt +1 -1
  20. data/vendor/depot_tools/bootstrap/win/win_tools.py +2 -1
  21. data/vendor/depot_tools/buildbucket.py +57 -4
  22. data/vendor/depot_tools/cipd +157 -44
  23. data/vendor/depot_tools/cipd.bat +51 -14
  24. data/vendor/depot_tools/cipd.ps1 +104 -42
  25. data/vendor/depot_tools/cipd_client_version +1 -1
  26. data/vendor/depot_tools/cipd_client_version.digests +21 -0
  27. data/vendor/depot_tools/cipd_manifest.txt +19 -6
  28. data/vendor/depot_tools/cipd_manifest.versions +318 -0
  29. data/vendor/depot_tools/clang_format.py +4 -4
  30. data/vendor/depot_tools/cpplint.py +44 -199
  31. data/vendor/depot_tools/dart_format.py +2 -2
  32. data/vendor/depot_tools/detect_host_arch.py +8 -3
  33. data/vendor/depot_tools/download_from_google_storage.py +47 -39
  34. data/vendor/depot_tools/fetch.py +30 -18
  35. data/vendor/depot_tools/fetch_configs/android_internal.py +34 -0
  36. data/vendor/depot_tools/fetch_configs/chromium.py +18 -1
  37. data/vendor/depot_tools/fetch_configs/config_util.py +4 -2
  38. data/vendor/depot_tools/fetch_configs/inspector_protocol.py +40 -0
  39. data/vendor/depot_tools/fetch_configs/node-ci.py +41 -0
  40. data/vendor/depot_tools/fix_encoding.py +3 -3
  41. data/vendor/depot_tools/gclient +1 -1
  42. data/vendor/depot_tools/gclient.py +415 -198
  43. data/vendor/depot_tools/gclient_eval.py +220 -171
  44. data/vendor/depot_tools/gclient_paths.py +142 -0
  45. data/vendor/depot_tools/gclient_scm.py +200 -51
  46. data/vendor/depot_tools/gclient_utils.py +88 -191
  47. data/vendor/depot_tools/gerrit_client.py +13 -0
  48. data/vendor/depot_tools/gerrit_util.py +158 -23
  49. data/vendor/depot_tools/git-nav-upstream +1 -1
  50. data/vendor/depot_tools/git_cache.py +77 -24
  51. data/vendor/depot_tools/git_cl.py +705 -1099
  52. data/vendor/depot_tools/git_common.py +9 -6
  53. data/vendor/depot_tools/git_map_branches.py +19 -2
  54. data/vendor/depot_tools/git_nav_downstream.py +3 -4
  55. data/vendor/depot_tools/git_rebase_update.py +14 -0
  56. data/vendor/depot_tools/git_reparent_branch.py +8 -2
  57. data/vendor/depot_tools/gn.py +38 -3
  58. data/vendor/depot_tools/gsutil.py +8 -3
  59. data/vendor/depot_tools/gsutil.py.bat +15 -0
  60. data/vendor/depot_tools/gsutil.vpython +16 -0
  61. data/vendor/depot_tools/infra/config/OWNERS +0 -1
  62. data/vendor/depot_tools/infra/config/recipes.cfg +3 -2
  63. data/vendor/depot_tools/lucicfg +12 -0
  64. data/vendor/depot_tools/lucicfg.bat +7 -0
  65. data/vendor/depot_tools/man/html/git-map-branches.html +34 -2
  66. data/vendor/depot_tools/man/html/git-new-branch.html +40 -32
  67. data/vendor/depot_tools/man/man1/git-map-branches.1 +24 -5
  68. data/vendor/depot_tools/man/man1/git-new-branch.1 +35 -27
  69. data/vendor/depot_tools/man/src/git-map-branches.demo.1.sh +1 -0
  70. data/vendor/depot_tools/man/src/git-map-branches.txt +10 -0
  71. data/vendor/depot_tools/man/src/git-new-branch.demo.1.sh +9 -4
  72. data/vendor/depot_tools/man/src/git-new-branch.txt +1 -1
  73. data/vendor/depot_tools/metrics.README.md +98 -0
  74. data/vendor/depot_tools/metrics.py +296 -0
  75. data/vendor/depot_tools/metrics_utils.py +303 -0
  76. data/vendor/depot_tools/my_activity.py +91 -29
  77. data/vendor/depot_tools/ninja +1 -1
  78. data/vendor/depot_tools/ninjalog.README.md +64 -0
  79. data/vendor/depot_tools/ninjalog_uploader.py +232 -0
  80. data/vendor/depot_tools/ninjalog_uploader_wrapper.py +116 -0
  81. data/vendor/depot_tools/owners.py +30 -13
  82. data/vendor/depot_tools/owners_finder.py +5 -2
  83. data/vendor/depot_tools/presubmit_canned_checks.py +188 -29
  84. data/vendor/depot_tools/presubmit_support.py +18 -41
  85. data/vendor/depot_tools/pylintrc +23 -19
  86. data/vendor/depot_tools/recipes/OWNERS +2 -0
  87. data/vendor/depot_tools/recipes/README.recipes.md +344 -151
  88. data/vendor/depot_tools/recipes/recipe_modules/bot_update/OWNERS +2 -0
  89. data/vendor/depot_tools/recipes/recipe_modules/bot_update/__init__.py +2 -16
  90. data/vendor/depot_tools/recipes/recipe_modules/bot_update/api.py +141 -99
  91. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/basic.json +5 -8
  92. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/basic_luci.json +5 -8
  93. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/basic_with_branch_heads.json +6 -98
  94. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/clobber.json +4 -9
  95. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/deprecated_got_revision_mapping.json +45 -5
  96. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/gerrit_no_rebase_patch_ref.json +4 -9
  97. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/gerrit_no_reset.json +4 -9
  98. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/{tryjob.json → input_commit_with_id_without_repo.json} +6 -11
  99. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/{tryjob_empty_revision.json → multiple_patch_refs.json} +8 -9
  100. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/no_apply_patch_on_gclient.json +19 -29
  101. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/{trychange.json → refs.json} +4 -9
  102. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/reset_root_solution_revision.json +4 -9
  103. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_fail.json +51 -6
  104. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_fail_patch.json +50 -6
  105. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_fail_patch_download.json +51 -6
  106. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_gerrit_angle.json +17 -25
  107. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_gerrit_branch_heads.json +17 -25
  108. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_gerrit_feature_branch.json +18 -26
  109. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_gerrit_v8_feature_branch.json +18 -26
  110. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_gerrit_webrtc.json +26 -28
  111. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_v8.json +45 -5
  112. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_v8_head_by_default.json +17 -25
  113. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/unrecognized_commit_repo.json +13 -0
  114. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/with_manifest_name.json +13 -152
  115. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/with_tags.json +4 -9
  116. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.py +185 -202
  117. data/vendor/depot_tools/recipes/recipe_modules/bot_update/resources/bot_update.py +52 -157
  118. data/vendor/depot_tools/recipes/recipe_modules/bot_update/test_api.py +5 -14
  119. data/vendor/depot_tools/recipes/recipe_modules/bot_update/tests/ensure_checkout.py +34 -0
  120. data/vendor/depot_tools/recipes/recipe_modules/cipd/api.py +14 -2
  121. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/basic.json +4 -5
  122. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/basic_pkg.json +4 -5
  123. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/describe-failed.json +7 -5
  124. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/describe-many-instances.json +4 -5
  125. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/mac64.json +4 -5
  126. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/pkg_bad_file.json +9 -3
  127. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/pkg_bad_mode.json +9 -3
  128. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/pkg_bad_verfile.json +9 -3
  129. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/win64.json +4 -5
  130. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/junk arch.json +2 -3
  131. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/junk bits.json +2 -3
  132. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/linux_arm_32.json +2 -3
  133. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/linux_arm_64.json +2 -3
  134. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/linux_intel_32.json +2 -3
  135. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/linux_intel_64.json +2 -3
  136. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/linux_mips_64.json +2 -3
  137. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/mac_intel_64.json +2 -3
  138. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/win_intel_32.json +2 -3
  139. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/win_intel_64.json +2 -3
  140. data/vendor/depot_tools/recipes/recipe_modules/depot_tools/api.py +13 -8
  141. data/vendor/depot_tools/recipes/recipe_modules/depot_tools/examples/full.expected/basic.json +18 -12
  142. data/vendor/depot_tools/recipes/recipe_modules/depot_tools/examples/full.expected/basic_luci.json +18 -12
  143. data/vendor/depot_tools/recipes/recipe_modules/depot_tools/examples/full.expected/win.json +18 -12
  144. data/vendor/depot_tools/recipes/recipe_modules/depot_tools/examples/full.py +3 -0
  145. data/vendor/depot_tools/recipes/recipe_modules/gclient/__init__.py +1 -0
  146. data/vendor/depot_tools/recipes/recipe_modules/gclient/api.py +58 -46
  147. data/vendor/depot_tools/recipes/recipe_modules/gclient/config.py +65 -22
  148. data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.expected/basic.json +20 -21
  149. data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.expected/buildbot.json +20 -21
  150. data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.expected/revision.json +20 -21
  151. data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.expected/tryserver.json +20 -21
  152. data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.py +5 -2
  153. data/vendor/depot_tools/recipes/recipe_modules/gclient/tests/patch_project.py +62 -14
  154. data/vendor/depot_tools/recipes/recipe_modules/gerrit/api.py +24 -38
  155. data/vendor/depot_tools/recipes/recipe_modules/gerrit/examples/full.expected/basic.json +56 -50
  156. data/vendor/depot_tools/recipes/recipe_modules/gerrit/examples/full.py +15 -9
  157. data/vendor/depot_tools/recipes/recipe_modules/git/__init__.py +4 -1
  158. data/vendor/depot_tools/recipes/recipe_modules/git/api.py +34 -22
  159. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic.json +5 -6
  160. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic_branch.json +5 -6
  161. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic_file_name.json +5 -6
  162. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic_hash.json +5 -6
  163. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic_luci.json +222 -0
  164. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic_ref.json +5 -6
  165. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic_submodule_update_force.json +5 -6
  166. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic_tags.json +224 -0
  167. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/can_fail_build.json +10 -6
  168. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/cannot_fail_build.json +5 -7
  169. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/cat-file_test.json +5 -6
  170. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/count-objects_delta.json +5 -6
  171. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/count-objects_failed.json +5 -7
  172. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/count-objects_with_bad_output.json +5 -6
  173. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/count-objects_with_bad_output_fails_build.json +10 -5
  174. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/curl_trace_file.json +5 -6
  175. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/git-cache-checkout.json +8 -9
  176. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/platform_win.json +5 -6
  177. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/rebase_failed.json +12 -8
  178. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/remote_not_origin.json +5 -6
  179. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/set_got_revision.json +5 -6
  180. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.py +27 -11
  181. data/vendor/depot_tools/recipes/recipe_modules/git_cl/api.py +1 -1
  182. data/vendor/depot_tools/recipes/recipe_modules/git_cl/examples/full.expected/basic.json +12 -13
  183. data/vendor/depot_tools/recipes/recipe_modules/gitiles/__init__.py +5 -0
  184. data/vendor/depot_tools/recipes/recipe_modules/gitiles/api.py +120 -5
  185. data/vendor/depot_tools/recipes/recipe_modules/gitiles/examples/full.expected/basic.json +45 -3
  186. data/vendor/depot_tools/recipes/recipe_modules/gitiles/examples/full.py +25 -0
  187. data/vendor/depot_tools/recipes/recipe_modules/gitiles/resources/gerrit_client.py +56 -4
  188. data/vendor/depot_tools/recipes/recipe_modules/gitiles/tests/parse_repo_url.expected/basic.json +6 -0
  189. data/vendor/depot_tools/recipes/recipe_modules/gitiles/tests/parse_repo_url.py +49 -0
  190. data/vendor/depot_tools/recipes/recipe_modules/gsutil/api.py +24 -13
  191. data/vendor/depot_tools/recipes/recipe_modules/gsutil/examples/full.expected/basic.json +13 -14
  192. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/basic.json +2 -3
  193. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/paths_buildbot_linux.json +2 -3
  194. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/paths_buildbot_mac.json +2 -3
  195. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/paths_buildbot_win.json +2 -3
  196. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/paths_generic_linux.json +2 -3
  197. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/paths_generic_mac.json +2 -3
  198. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/paths_generic_win.json +2 -3
  199. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/paths_kitchen_linux.json +2 -3
  200. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/paths_kitchen_mac.json +2 -3
  201. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/paths_kitchen_win.json +2 -3
  202. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/path_config.py +1 -2
  203. data/vendor/depot_tools/recipes/recipe_modules/osx_sdk/__init__.py +35 -0
  204. data/vendor/depot_tools/recipes/recipe_modules/osx_sdk/api.py +116 -0
  205. data/vendor/depot_tools/recipes/recipe_modules/osx_sdk/examples/full.expected/linux.json +22 -0
  206. data/vendor/depot_tools/recipes/recipe_modules/osx_sdk/examples/full.expected/mac.json +82 -0
  207. data/vendor/depot_tools/recipes/recipe_modules/osx_sdk/examples/full.expected/win.json +22 -0
  208. data/vendor/depot_tools/recipes/recipe_modules/osx_sdk/examples/full.py +23 -0
  209. data/vendor/depot_tools/recipes/recipe_modules/presubmit/__init__.py +1 -0
  210. data/vendor/depot_tools/recipes/recipe_modules/presubmit/api.py +2 -7
  211. data/vendor/depot_tools/recipes/recipe_modules/presubmit/examples/full.expected/basic.json +7 -6
  212. data/vendor/depot_tools/recipes/recipe_modules/tryserver/__init__.py +1 -0
  213. data/vendor/depot_tools/recipes/recipe_modules/tryserver/api.py +117 -8
  214. data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/basic_tags.json +4 -5
  215. data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/set_failure_hash_with_no_steps.json +7 -4
  216. data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_gerrit_patch.json +98 -7
  217. data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_gerrit_patch_and_target_ref.json +147 -0
  218. data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_git_patch.json +8 -5
  219. data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_git_patch_luci.json +8 -5
  220. data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_wrong_patch.json +9 -6
  221. data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_wrong_patch_new.json +9 -6
  222. data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.py +27 -2
  223. data/vendor/depot_tools/recipes/recipe_modules/tryserver/test_api.py +14 -0
  224. data/vendor/depot_tools/recipes/recipe_modules/windows_sdk/__init__.py +25 -0
  225. data/vendor/depot_tools/recipes/recipe_modules/windows_sdk/api.py +137 -0
  226. data/vendor/depot_tools/recipes/recipe_modules/windows_sdk/examples/full.expected/linux.json +22 -0
  227. data/vendor/depot_tools/recipes/recipe_modules/windows_sdk/examples/full.expected/mac.json +22 -0
  228. data/vendor/depot_tools/recipes/recipe_modules/windows_sdk/examples/full.expected/win.json +107 -0
  229. data/vendor/depot_tools/recipes/recipe_modules/windows_sdk/examples/full.py +26 -0
  230. data/vendor/depot_tools/recipes/recipes.py +37 -27
  231. data/vendor/depot_tools/recipes/recipes/fetch_end_to_end_test.expected/basic.json +7 -10
  232. data/vendor/depot_tools/repo +34 -8
  233. data/vendor/depot_tools/roll_dep.py +52 -49
  234. data/vendor/depot_tools/scm.py +38 -23
  235. data/vendor/depot_tools/setup_color.py +4 -2
  236. data/vendor/depot_tools/split_cl.py +32 -4
  237. data/vendor/depot_tools/subprocess2.py +22 -4
  238. data/vendor/depot_tools/third_party/httplib2/README.chromium +2 -2
  239. data/vendor/depot_tools/third_party/httplib2/__init__.py +242 -158
  240. data/vendor/depot_tools/third_party/httplib2/cacerts.txt +57 -44
  241. data/vendor/depot_tools/third_party/httplib2/socks.py +15 -5
  242. data/vendor/depot_tools/third_party/logilab/README.chromium +2 -4
  243. data/vendor/depot_tools/third_party/logilab/astroid/README.chromium +2 -1
  244. data/vendor/depot_tools/third_party/logilab/astroid/__init__.py +10 -5
  245. data/vendor/depot_tools/third_party/logilab/astroid/__pkginfo__.py +5 -5
  246. data/vendor/depot_tools/third_party/logilab/astroid/arguments.py +233 -0
  247. data/vendor/depot_tools/third_party/logilab/astroid/as_string.py +82 -33
  248. data/vendor/depot_tools/third_party/logilab/astroid/bases.py +137 -153
  249. data/vendor/depot_tools/third_party/logilab/astroid/brain/{builtin_inference.py → brain_builtin_inference.py} +117 -26
  250. data/vendor/depot_tools/third_party/logilab/astroid/brain/brain_dateutil.py +15 -0
  251. data/vendor/depot_tools/third_party/logilab/astroid/brain/{py2gi.py → brain_gi.py} +48 -8
  252. data/vendor/depot_tools/third_party/logilab/astroid/brain/{py2mechanize.py → brain_mechanize.py} +0 -0
  253. data/vendor/depot_tools/third_party/logilab/astroid/brain/{pynose.py → brain_nose.py} +4 -1
  254. data/vendor/depot_tools/third_party/logilab/astroid/brain/brain_numpy.py +62 -0
  255. data/vendor/depot_tools/third_party/logilab/astroid/brain/brain_pytest.py +76 -0
  256. data/vendor/depot_tools/third_party/logilab/astroid/brain/brain_qt.py +44 -0
  257. data/vendor/depot_tools/third_party/logilab/astroid/brain/{pysix_moves.py → brain_six.py} +28 -1
  258. data/vendor/depot_tools/third_party/logilab/astroid/brain/brain_ssl.py +65 -0
  259. data/vendor/depot_tools/third_party/logilab/astroid/brain/brain_stdlib.py +473 -0
  260. data/vendor/depot_tools/third_party/logilab/astroid/builder.py +104 -81
  261. data/vendor/depot_tools/third_party/logilab/astroid/context.py +81 -0
  262. data/vendor/depot_tools/third_party/logilab/astroid/decorators.py +75 -0
  263. data/vendor/depot_tools/third_party/logilab/astroid/exceptions.py +20 -0
  264. data/vendor/depot_tools/third_party/logilab/astroid/inference.py +137 -183
  265. data/vendor/depot_tools/third_party/logilab/astroid/manager.py +45 -169
  266. data/vendor/depot_tools/third_party/logilab/astroid/mixins.py +37 -14
  267. data/vendor/depot_tools/third_party/logilab/astroid/modutils.py +112 -41
  268. data/vendor/depot_tools/third_party/logilab/astroid/node_classes.py +243 -156
  269. data/vendor/depot_tools/third_party/logilab/astroid/nodes.py +35 -22
  270. data/vendor/depot_tools/third_party/logilab/astroid/objects.py +186 -0
  271. data/vendor/depot_tools/third_party/logilab/astroid/protocols.py +157 -102
  272. data/vendor/depot_tools/third_party/logilab/astroid/raw_building.py +32 -8
  273. data/vendor/depot_tools/third_party/logilab/astroid/rebuilder.py +372 -309
  274. data/vendor/depot_tools/third_party/logilab/astroid/scoped_nodes.py +652 -420
  275. data/vendor/depot_tools/third_party/logilab/astroid/test_utils.py +4 -21
  276. data/vendor/depot_tools/third_party/logilab/astroid/transforms.py +96 -0
  277. data/vendor/depot_tools/third_party/logilab/astroid/util.py +89 -0
  278. data/vendor/depot_tools/third_party/logilab/lazy_object_proxy/LICENSE +19 -0
  279. data/vendor/depot_tools/third_party/logilab/lazy_object_proxy/README.chromium +11 -0
  280. data/vendor/depot_tools/third_party/logilab/lazy_object_proxy/__init__.py +20 -0
  281. data/vendor/depot_tools/third_party/logilab/lazy_object_proxy/cext.c +1421 -0
  282. data/vendor/depot_tools/third_party/logilab/lazy_object_proxy/compat.py +9 -0
  283. data/vendor/depot_tools/third_party/logilab/lazy_object_proxy/simple.py +246 -0
  284. data/vendor/depot_tools/third_party/logilab/lazy_object_proxy/slots.py +414 -0
  285. data/vendor/depot_tools/third_party/logilab/lazy_object_proxy/utils.py +13 -0
  286. data/vendor/depot_tools/third_party/logilab/wrapt/LICENSE +24 -0
  287. data/vendor/depot_tools/third_party/logilab/wrapt/README.chromium +11 -0
  288. data/vendor/depot_tools/third_party/logilab/wrapt/__init__.py +19 -0
  289. data/vendor/depot_tools/third_party/logilab/wrapt/_wrappers.c +2729 -0
  290. data/vendor/depot_tools/third_party/logilab/wrapt/arguments.py +96 -0
  291. data/vendor/depot_tools/third_party/logilab/wrapt/decorators.py +512 -0
  292. data/vendor/depot_tools/third_party/logilab/wrapt/importer.py +228 -0
  293. data/vendor/depot_tools/third_party/logilab/wrapt/wrappers.py +901 -0
  294. data/vendor/depot_tools/third_party/pylint/README.chromium +2 -25
  295. data/vendor/depot_tools/third_party/pylint/__pkginfo__.py +13 -3
  296. data/vendor/depot_tools/third_party/pylint/checkers/__init__.py +1 -2
  297. data/vendor/depot_tools/third_party/pylint/checkers/async.py +82 -0
  298. data/vendor/depot_tools/third_party/pylint/checkers/base.py +893 -119
  299. data/vendor/depot_tools/third_party/pylint/checkers/classes.py +342 -204
  300. data/vendor/depot_tools/third_party/pylint/checkers/design_analysis.py +51 -34
  301. data/vendor/depot_tools/third_party/pylint/checkers/exceptions.py +84 -47
  302. data/vendor/depot_tools/third_party/pylint/checkers/format.py +55 -30
  303. data/vendor/depot_tools/third_party/pylint/checkers/imports.py +314 -73
  304. data/vendor/depot_tools/third_party/pylint/checkers/logging.py +10 -8
  305. data/vendor/depot_tools/third_party/pylint/checkers/misc.py +2 -1
  306. data/vendor/depot_tools/third_party/pylint/checkers/newstyle.py +45 -48
  307. data/vendor/depot_tools/third_party/pylint/checkers/python3.py +31 -21
  308. data/vendor/depot_tools/third_party/pylint/checkers/raw_metrics.py +3 -3
  309. data/vendor/depot_tools/third_party/pylint/checkers/similar.py +4 -5
  310. data/vendor/depot_tools/third_party/pylint/checkers/spelling.py +24 -10
  311. data/vendor/depot_tools/third_party/pylint/checkers/stdlib.py +120 -56
  312. data/vendor/depot_tools/third_party/pylint/checkers/strings.py +38 -35
  313. data/vendor/depot_tools/third_party/pylint/checkers/typecheck.py +485 -138
  314. data/vendor/depot_tools/third_party/pylint/checkers/utils.py +319 -142
  315. data/vendor/depot_tools/third_party/pylint/checkers/variables.py +329 -207
  316. data/vendor/depot_tools/third_party/pylint/config.py +739 -76
  317. data/vendor/depot_tools/third_party/pylint/epylint.py +9 -5
  318. data/vendor/depot_tools/third_party/pylint/extensions/__init__.py +0 -0
  319. data/vendor/depot_tools/third_party/pylint/extensions/check_docs.py +311 -0
  320. data/vendor/depot_tools/third_party/pylint/extensions/check_elif.py +62 -0
  321. data/vendor/depot_tools/third_party/{logilab/common → pylint}/graph.py +30 -133
  322. data/vendor/depot_tools/third_party/pylint/gui.py +2 -2
  323. data/vendor/depot_tools/third_party/pylint/interfaces.py +21 -3
  324. data/vendor/depot_tools/third_party/pylint/lint.py +123 -140
  325. data/vendor/depot_tools/third_party/pylint/pyreverse/diadefslib.py +10 -13
  326. data/vendor/depot_tools/third_party/pylint/pyreverse/diagrams.py +15 -4
  327. data/vendor/depot_tools/third_party/pylint/pyreverse/inspector.py +372 -0
  328. data/vendor/depot_tools/third_party/pylint/pyreverse/main.py +30 -7
  329. data/vendor/depot_tools/third_party/pylint/pyreverse/utils.py +80 -2
  330. data/vendor/depot_tools/third_party/{logilab/common → pylint/pyreverse}/vcgutils.py +19 -37
  331. data/vendor/depot_tools/third_party/pylint/pyreverse/writer.py +3 -4
  332. data/vendor/depot_tools/third_party/pylint/reporters/__init__.py +34 -18
  333. data/vendor/depot_tools/third_party/pylint/reporters/guireporter.py +1 -1
  334. data/vendor/depot_tools/third_party/pylint/reporters/html.py +10 -3
  335. data/vendor/depot_tools/third_party/pylint/reporters/json.py +10 -4
  336. data/vendor/depot_tools/third_party/pylint/reporters/text.py +94 -3
  337. data/vendor/depot_tools/third_party/pylint/reporters/ureports/__init__.py +106 -0
  338. data/vendor/depot_tools/third_party/{logilab/common → pylint/reporters}/ureports/html_writer.py +17 -57
  339. data/vendor/depot_tools/third_party/{logilab/common → pylint/reporters}/ureports/nodes.py +52 -74
  340. data/vendor/depot_tools/third_party/{logilab/common → pylint/reporters}/ureports/text_writer.py +14 -60
  341. data/vendor/depot_tools/third_party/pylint/testutils.py +22 -20
  342. data/vendor/depot_tools/third_party/pylint/utils.py +268 -44
  343. data/vendor/depot_tools/third_party/repo/progress.py +42 -0
  344. data/vendor/depot_tools/update_depot_tools +1 -1
  345. data/vendor/depot_tools/upload_metrics.py +25 -0
  346. data/vendor/depot_tools/win_toolchain/get_toolchain_if_necessary.py +45 -15
  347. data/vendor/depot_tools/win_toolchain/package_from_installed.py +71 -24
  348. data/vendor/depot_tools/yapf +1 -1
  349. data/vendor/depot_tools/yapf.bat +1 -1
  350. metadata +92 -77
  351. data/vendor/depot_tools/git-crsync +0 -3
  352. data/vendor/depot_tools/infra/config/cq.cfg +0 -32
  353. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/apply_gerrit_ref.json +0 -29
  354. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/apply_gerrit_ref_custom.json +0 -29
  355. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/buildbot.json +0 -105
  356. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/shallow.json +0 -195
  357. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_gerrit_angle_deprecated.json +0 -248
  358. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_gerrit_v8.json +0 -248
  359. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/with_manifest_name_no_patch.json +0 -105
  360. data/vendor/depot_tools/recipes/recipe_modules/bot_update/resources/apply_gerrit.py +0 -33
  361. data/vendor/depot_tools/third_party/logilab/astroid/brain/py2pytest.py +0 -31
  362. data/vendor/depot_tools/third_party/logilab/astroid/brain/py2qt4.py +0 -22
  363. data/vendor/depot_tools/third_party/logilab/astroid/brain/py2stdlib.py +0 -334
  364. data/vendor/depot_tools/third_party/logilab/astroid/inspector.py +0 -273
  365. data/vendor/depot_tools/third_party/logilab/astroid/utils.py +0 -239
  366. data/vendor/depot_tools/third_party/logilab/common/LICENSE.txt +0 -339
  367. data/vendor/depot_tools/third_party/logilab/common/README.chromium +0 -11
  368. data/vendor/depot_tools/third_party/logilab/common/__init__.py +0 -175
  369. data/vendor/depot_tools/third_party/logilab/common/__pkginfo__.py +0 -57
  370. data/vendor/depot_tools/third_party/logilab/common/cache.py +0 -114
  371. data/vendor/depot_tools/third_party/logilab/common/changelog.py +0 -238
  372. data/vendor/depot_tools/third_party/logilab/common/clcommands.py +0 -334
  373. data/vendor/depot_tools/third_party/logilab/common/cli.py +0 -211
  374. data/vendor/depot_tools/third_party/logilab/common/compat.py +0 -78
  375. data/vendor/depot_tools/third_party/logilab/common/configuration.py +0 -1105
  376. data/vendor/depot_tools/third_party/logilab/common/contexts.py +0 -5
  377. data/vendor/depot_tools/third_party/logilab/common/corbautils.py +0 -117
  378. data/vendor/depot_tools/third_party/logilab/common/daemon.py +0 -101
  379. data/vendor/depot_tools/third_party/logilab/common/date.py +0 -335
  380. data/vendor/depot_tools/third_party/logilab/common/dbf.py +0 -231
  381. data/vendor/depot_tools/third_party/logilab/common/debugger.py +0 -214
  382. data/vendor/depot_tools/third_party/logilab/common/decorators.py +0 -281
  383. data/vendor/depot_tools/third_party/logilab/common/deprecation.py +0 -189
  384. data/vendor/depot_tools/third_party/logilab/common/fileutils.py +0 -404
  385. data/vendor/depot_tools/third_party/logilab/common/interface.py +0 -71
  386. data/vendor/depot_tools/third_party/logilab/common/logging_ext.py +0 -195
  387. data/vendor/depot_tools/third_party/logilab/common/modutils.py +0 -702
  388. data/vendor/depot_tools/third_party/logilab/common/optik_ext.py +0 -392
  389. data/vendor/depot_tools/third_party/logilab/common/optparser.py +0 -92
  390. data/vendor/depot_tools/third_party/logilab/common/proc.py +0 -277
  391. data/vendor/depot_tools/third_party/logilab/common/pyro_ext.py +0 -180
  392. data/vendor/depot_tools/third_party/logilab/common/pytest.py +0 -1199
  393. data/vendor/depot_tools/third_party/logilab/common/registry.py +0 -1119
  394. data/vendor/depot_tools/third_party/logilab/common/shellutils.py +0 -462
  395. data/vendor/depot_tools/third_party/logilab/common/sphinx_ext.py +0 -87
  396. data/vendor/depot_tools/third_party/logilab/common/sphinxutils.py +0 -122
  397. data/vendor/depot_tools/third_party/logilab/common/table.py +0 -929
  398. data/vendor/depot_tools/third_party/logilab/common/tasksqueue.py +0 -101
  399. data/vendor/depot_tools/third_party/logilab/common/testlib.py +0 -1392
  400. data/vendor/depot_tools/third_party/logilab/common/textutils.py +0 -537
  401. data/vendor/depot_tools/third_party/logilab/common/tree.py +0 -369
  402. data/vendor/depot_tools/third_party/logilab/common/umessage.py +0 -194
  403. data/vendor/depot_tools/third_party/logilab/common/ureports/__init__.py +0 -172
  404. data/vendor/depot_tools/third_party/logilab/common/ureports/docbook_writer.py +0 -140
  405. data/vendor/depot_tools/third_party/logilab/common/urllib2ext.py +0 -89
  406. data/vendor/depot_tools/third_party/logilab/common/visitor.py +0 -109
  407. data/vendor/depot_tools/third_party/logilab/common/xmlrpcutils.py +0 -131
  408. data/vendor/depot_tools/third_party/logilab/common/xmlutils.py +0 -61
@@ -1,211 +0,0 @@
1
- # copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
2
- # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
3
- #
4
- # This file is part of logilab-common.
5
- #
6
- # logilab-common is free software: you can redistribute it and/or modify it under
7
- # the terms of the GNU Lesser General Public License as published by the Free
8
- # Software Foundation, either version 2.1 of the License, or (at your option) any
9
- # later version.
10
- #
11
- # logilab-common is distributed in the hope that it will be useful, but WITHOUT
12
- # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13
- # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
14
- # details.
15
- #
16
- # You should have received a copy of the GNU Lesser General Public License along
17
- # with logilab-common. If not, see <http://www.gnu.org/licenses/>.
18
- """Command line interface helper classes.
19
-
20
- It provides some default commands, a help system, a default readline
21
- configuration with completion and persistent history.
22
-
23
- Example::
24
-
25
- class BookShell(CLIHelper):
26
-
27
- def __init__(self):
28
- # quit and help are builtins
29
- # CMD_MAP keys are commands, values are topics
30
- self.CMD_MAP['pionce'] = _("Sommeil")
31
- self.CMD_MAP['ronfle'] = _("Sommeil")
32
- CLIHelper.__init__(self)
33
-
34
- help_do_pionce = ("pionce", "pionce duree", _("met ton corps en veille"))
35
- def do_pionce(self):
36
- print('nap is good')
37
-
38
- help_do_ronfle = ("ronfle", "ronfle volume", _("met les autres en veille"))
39
- def do_ronfle(self):
40
- print('fuuuuuuuuuuuu rhhhhhrhrhrrh')
41
-
42
- cl = BookShell()
43
- """
44
-
45
- from __future__ import print_function
46
-
47
- __docformat__ = "restructuredtext en"
48
-
49
- from six.moves import builtins, input
50
-
51
- if not hasattr(builtins, '_'):
52
- builtins._ = str
53
-
54
-
55
- def init_readline(complete_method, histfile=None):
56
- """Init the readline library if available."""
57
- try:
58
- import readline
59
- readline.parse_and_bind("tab: complete")
60
- readline.set_completer(complete_method)
61
- string = readline.get_completer_delims().replace(':', '')
62
- readline.set_completer_delims(string)
63
- if histfile is not None:
64
- try:
65
- readline.read_history_file(histfile)
66
- except IOError:
67
- pass
68
- import atexit
69
- atexit.register(readline.write_history_file, histfile)
70
- except:
71
- print('readline is not available :-(')
72
-
73
-
74
- class Completer :
75
- """Readline completer."""
76
-
77
- def __init__(self, commands):
78
- self.list = commands
79
-
80
- def complete(self, text, state):
81
- """Hook called by readline when <tab> is pressed."""
82
- n = len(text)
83
- matches = []
84
- for cmd in self.list :
85
- if cmd[:n] == text :
86
- matches.append(cmd)
87
- try:
88
- return matches[state]
89
- except IndexError:
90
- return None
91
-
92
-
93
- class CLIHelper:
94
- """An abstract command line interface client which recognize commands
95
- and provide an help system.
96
- """
97
-
98
- CMD_MAP = {'help': _("Others"),
99
- 'quit': _("Others"),
100
- }
101
- CMD_PREFIX = ''
102
-
103
- def __init__(self, histfile=None) :
104
- self._topics = {}
105
- self.commands = None
106
- self._completer = Completer(self._register_commands())
107
- init_readline(self._completer.complete, histfile)
108
-
109
- def run(self):
110
- """loop on user input, exit on EOF"""
111
- while True:
112
- try:
113
- line = input('>>> ')
114
- except EOFError:
115
- print
116
- break
117
- s_line = line.strip()
118
- if not s_line:
119
- continue
120
- args = s_line.split()
121
- if args[0] in self.commands:
122
- try:
123
- cmd = 'do_%s' % self.commands[args[0]]
124
- getattr(self, cmd)(*args[1:])
125
- except EOFError:
126
- break
127
- except:
128
- import traceback
129
- traceback.print_exc()
130
- else:
131
- try:
132
- self.handle_line(s_line)
133
- except:
134
- import traceback
135
- traceback.print_exc()
136
-
137
- def handle_line(self, stripped_line):
138
- """Method to overload in the concrete class (should handle
139
- lines which are not commands).
140
- """
141
- raise NotImplementedError()
142
-
143
-
144
- # private methods #########################################################
145
-
146
- def _register_commands(self):
147
- """ register available commands method and return the list of
148
- commands name
149
- """
150
- self.commands = {}
151
- self._command_help = {}
152
- commands = [attr[3:] for attr in dir(self) if attr[:3] == 'do_']
153
- for command in commands:
154
- topic = self.CMD_MAP[command]
155
- help_method = getattr(self, 'help_do_%s' % command)
156
- self._topics.setdefault(topic, []).append(help_method)
157
- self.commands[self.CMD_PREFIX + command] = command
158
- self._command_help[command] = help_method
159
- return self.commands.keys()
160
-
161
- def _print_help(self, cmd, syntax, explanation):
162
- print(_('Command %s') % cmd)
163
- print(_('Syntax: %s') % syntax)
164
- print('\t', explanation)
165
- print()
166
-
167
-
168
- # predefined commands #####################################################
169
-
170
- def do_help(self, command=None) :
171
- """base input of the help system"""
172
- if command in self._command_help:
173
- self._print_help(*self._command_help[command])
174
- elif command is None or command not in self._topics:
175
- print(_("Use help <topic> or help <command>."))
176
- print(_("Available topics are:"))
177
- topics = sorted(self._topics.keys())
178
- for topic in topics:
179
- print('\t', topic)
180
- print()
181
- print(_("Available commands are:"))
182
- commands = self.commands.keys()
183
- commands.sort()
184
- for command in commands:
185
- print('\t', command[len(self.CMD_PREFIX):])
186
-
187
- else:
188
- print(_('Available commands about %s:') % command)
189
- print
190
- for command_help_method in self._topics[command]:
191
- try:
192
- if callable(command_help_method):
193
- self._print_help(*command_help_method())
194
- else:
195
- self._print_help(*command_help_method)
196
- except:
197
- import traceback
198
- traceback.print_exc()
199
- print('ERROR in help method %s'% (
200
- command_help_method.__name__))
201
-
202
- help_do_help = ("help", "help [topic|command]",
203
- _("print help message for the given topic/command or \
204
- available topics when no argument"))
205
-
206
- def do_quit(self):
207
- """quit the CLI"""
208
- raise EOFError()
209
-
210
- def help_do_quit(self):
211
- return ("quit", "quit", _("quit the application"))
@@ -1,78 +0,0 @@
1
- # pylint: disable=E0601,W0622,W0611
2
- # copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
3
- # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
4
- #
5
- # This file is part of logilab-common.
6
- #
7
- # logilab-common is free software: you can redistribute it and/or modify it under
8
- # the terms of the GNU Lesser General Public License as published by the Free
9
- # Software Foundation, either version 2.1 of the License, or (at your option) any
10
- # later version.
11
- #
12
- # logilab-common is distributed in the hope that it will be useful, but WITHOUT
13
- # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14
- # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
15
- # details.
16
- #
17
- # You should have received a copy of the GNU Lesser General Public License along
18
- # with logilab-common. If not, see <http://www.gnu.org/licenses/>.
19
- """Wrappers around some builtins introduced in python 2.3, 2.4 and
20
- 2.5, making them available in for earlier versions of python.
21
-
22
- See another compatibility snippets from other projects:
23
-
24
- :mod:`lib2to3.fixes`
25
- :mod:`coverage.backward`
26
- :mod:`unittest2.compatibility`
27
- """
28
-
29
-
30
- __docformat__ = "restructuredtext en"
31
-
32
- import os
33
- import sys
34
- import types
35
- from warnings import warn
36
-
37
- # not used here, but imported to preserve API
38
- from six.moves import builtins
39
-
40
- if sys.version_info < (3, 0):
41
- str_to_bytes = str
42
- def str_encode(string, encoding):
43
- if isinstance(string, unicode):
44
- return string.encode(encoding)
45
- return str(string)
46
- else:
47
- def str_to_bytes(string):
48
- return str.encode(string)
49
- # we have to ignore the encoding in py3k to be able to write a string into a
50
- # TextIOWrapper or like object (which expect an unicode string)
51
- def str_encode(string, encoding):
52
- return str(string)
53
-
54
- # See also http://bugs.python.org/issue11776
55
- if sys.version_info[0] == 3:
56
- def method_type(callable, instance, klass):
57
- # api change. klass is no more considered
58
- return types.MethodType(callable, instance)
59
- else:
60
- # alias types otherwise
61
- method_type = types.MethodType
62
-
63
- # Pythons 2 and 3 differ on where to get StringIO
64
- if sys.version_info < (3, 0):
65
- from cStringIO import StringIO
66
- FileIO = file
67
- BytesIO = StringIO
68
- reload = reload
69
- else:
70
- from io import FileIO, BytesIO, StringIO
71
- from imp import reload
72
-
73
- from logilab.common.deprecation import deprecated
74
-
75
- # Other projects import these from here, keep providing them for
76
- # backwards compat
77
- any = deprecated('use builtin "any"')(any)
78
- all = deprecated('use builtin "all"')(all)
@@ -1,1105 +0,0 @@
1
- # copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
2
- # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
3
- #
4
- # This file is part of logilab-common.
5
- #
6
- # logilab-common is free software: you can redistribute it and/or modify it under
7
- # the terms of the GNU Lesser General Public License as published by the Free
8
- # Software Foundation, either version 2.1 of the License, or (at your option) any
9
- # later version.
10
- #
11
- # logilab-common is distributed in the hope that it will be useful, but WITHOUT
12
- # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13
- # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
14
- # details.
15
- #
16
- # You should have received a copy of the GNU Lesser General Public License along
17
- # with logilab-common. If not, see <http://www.gnu.org/licenses/>.
18
- """Classes to handle advanced configuration in simple to complex applications.
19
-
20
- Allows to load the configuration from a file or from command line
21
- options, to generate a sample configuration file or to display
22
- program's usage. Fills the gap between optik/optparse and ConfigParser
23
- by adding data types (which are also available as a standalone optik
24
- extension in the `optik_ext` module).
25
-
26
-
27
- Quick start: simplest usage
28
- ---------------------------
29
-
30
- .. python ::
31
-
32
- >>> import sys
33
- >>> from logilab.common.configuration import Configuration
34
- >>> options = [('dothis', {'type':'yn', 'default': True, 'metavar': '<y or n>'}),
35
- ... ('value', {'type': 'string', 'metavar': '<string>'}),
36
- ... ('multiple', {'type': 'csv', 'default': ('yop',),
37
- ... 'metavar': '<comma separated values>',
38
- ... 'help': 'you can also document the option'}),
39
- ... ('number', {'type': 'int', 'default':2, 'metavar':'<int>'}),
40
- ... ]
41
- >>> config = Configuration(options=options, name='My config')
42
- >>> print config['dothis']
43
- True
44
- >>> print config['value']
45
- None
46
- >>> print config['multiple']
47
- ('yop',)
48
- >>> print config['number']
49
- 2
50
- >>> print config.help()
51
- Usage: [options]
52
-
53
- Options:
54
- -h, --help show this help message and exit
55
- --dothis=<y or n>
56
- --value=<string>
57
- --multiple=<comma separated values>
58
- you can also document the option [current: none]
59
- --number=<int>
60
-
61
- >>> f = open('myconfig.ini', 'w')
62
- >>> f.write('''[MY CONFIG]
63
- ... number = 3
64
- ... dothis = no
65
- ... multiple = 1,2,3
66
- ... ''')
67
- >>> f.close()
68
- >>> config.load_file_configuration('myconfig.ini')
69
- >>> print config['dothis']
70
- False
71
- >>> print config['value']
72
- None
73
- >>> print config['multiple']
74
- ['1', '2', '3']
75
- >>> print config['number']
76
- 3
77
- >>> sys.argv = ['mon prog', '--value', 'bacon', '--multiple', '4,5,6',
78
- ... 'nonoptionargument']
79
- >>> print config.load_command_line_configuration()
80
- ['nonoptionargument']
81
- >>> print config['value']
82
- bacon
83
- >>> config.generate_config()
84
- # class for simple configurations which don't need the
85
- # manager / providers model and prefer delegation to inheritance
86
- #
87
- # configuration values are accessible through a dict like interface
88
- #
89
- [MY CONFIG]
90
-
91
- dothis=no
92
-
93
- value=bacon
94
-
95
- # you can also document the option
96
- multiple=4,5,6
97
-
98
- number=3
99
-
100
- Note : starting with Python 2.7 ConfigParser is able to take into
101
- account the order of occurrences of the options into a file (by
102
- using an OrderedDict). If you have two options changing some common
103
- state, like a 'disable-all-stuff' and a 'enable-some-stuff-a', their
104
- order of appearance will be significant : the last specified in the
105
- file wins. For earlier version of python and logilab.common newer
106
- than 0.61 the behaviour is unspecified.
107
-
108
- """
109
-
110
- from __future__ import print_function
111
-
112
- __docformat__ = "restructuredtext en"
113
-
114
- __all__ = ('OptionsManagerMixIn', 'OptionsProviderMixIn',
115
- 'ConfigurationMixIn', 'Configuration',
116
- 'OptionsManager2ConfigurationAdapter')
117
-
118
- import os
119
- import sys
120
- import re
121
- from os.path import exists, expanduser
122
- from copy import copy
123
- from warnings import warn
124
-
125
- from six import string_types
126
- from six.moves import range, configparser as cp, input
127
-
128
- from logilab.common.compat import str_encode as _encode
129
- from logilab.common.deprecation import deprecated
130
- from logilab.common.textutils import normalize_text, unquote
131
- from logilab.common import optik_ext
132
-
133
- OptionError = optik_ext.OptionError
134
-
135
- REQUIRED = []
136
-
137
- class UnsupportedAction(Exception):
138
- """raised by set_option when it doesn't know what to do for an action"""
139
-
140
-
141
- def _get_encoding(encoding, stream):
142
- encoding = encoding or getattr(stream, 'encoding', None)
143
- if not encoding:
144
- import locale
145
- encoding = locale.getpreferredencoding()
146
- return encoding
147
-
148
-
149
- # validation functions ########################################################
150
-
151
- # validators will return the validated value or raise optparse.OptionValueError
152
- # XXX add to documentation
153
-
154
- def choice_validator(optdict, name, value):
155
- """validate and return a converted value for option of type 'choice'
156
- """
157
- if not value in optdict['choices']:
158
- msg = "option %s: invalid value: %r, should be in %s"
159
- raise optik_ext.OptionValueError(msg % (name, value, optdict['choices']))
160
- return value
161
-
162
- def multiple_choice_validator(optdict, name, value):
163
- """validate and return a converted value for option of type 'choice'
164
- """
165
- choices = optdict['choices']
166
- values = optik_ext.check_csv(None, name, value)
167
- for value in values:
168
- if not value in choices:
169
- msg = "option %s: invalid value: %r, should be in %s"
170
- raise optik_ext.OptionValueError(msg % (name, value, choices))
171
- return values
172
-
173
- def csv_validator(optdict, name, value):
174
- """validate and return a converted value for option of type 'csv'
175
- """
176
- return optik_ext.check_csv(None, name, value)
177
-
178
- def yn_validator(optdict, name, value):
179
- """validate and return a converted value for option of type 'yn'
180
- """
181
- return optik_ext.check_yn(None, name, value)
182
-
183
- def named_validator(optdict, name, value):
184
- """validate and return a converted value for option of type 'named'
185
- """
186
- return optik_ext.check_named(None, name, value)
187
-
188
- def file_validator(optdict, name, value):
189
- """validate and return a filepath for option of type 'file'"""
190
- return optik_ext.check_file(None, name, value)
191
-
192
- def color_validator(optdict, name, value):
193
- """validate and return a valid color for option of type 'color'"""
194
- return optik_ext.check_color(None, name, value)
195
-
196
- def password_validator(optdict, name, value):
197
- """validate and return a string for option of type 'password'"""
198
- return optik_ext.check_password(None, name, value)
199
-
200
- def date_validator(optdict, name, value):
201
- """validate and return a mx DateTime object for option of type 'date'"""
202
- return optik_ext.check_date(None, name, value)
203
-
204
- def time_validator(optdict, name, value):
205
- """validate and return a time object for option of type 'time'"""
206
- return optik_ext.check_time(None, name, value)
207
-
208
- def bytes_validator(optdict, name, value):
209
- """validate and return an integer for option of type 'bytes'"""
210
- return optik_ext.check_bytes(None, name, value)
211
-
212
-
213
- VALIDATORS = {'string': unquote,
214
- 'int': int,
215
- 'float': float,
216
- 'file': file_validator,
217
- 'font': unquote,
218
- 'color': color_validator,
219
- 'regexp': re.compile,
220
- 'csv': csv_validator,
221
- 'yn': yn_validator,
222
- 'bool': yn_validator,
223
- 'named': named_validator,
224
- 'password': password_validator,
225
- 'date': date_validator,
226
- 'time': time_validator,
227
- 'bytes': bytes_validator,
228
- 'choice': choice_validator,
229
- 'multiple_choice': multiple_choice_validator,
230
- }
231
-
232
- def _call_validator(opttype, optdict, option, value):
233
- if opttype not in VALIDATORS:
234
- raise Exception('Unsupported type "%s"' % opttype)
235
- try:
236
- return VALIDATORS[opttype](optdict, option, value)
237
- except TypeError:
238
- try:
239
- return VALIDATORS[opttype](value)
240
- except optik_ext.OptionValueError:
241
- raise
242
- except:
243
- raise optik_ext.OptionValueError('%s value (%r) should be of type %s' %
244
- (option, value, opttype))
245
-
246
- # user input functions ########################################################
247
-
248
- # user input functions will ask the user for input on stdin then validate
249
- # the result and return the validated value or raise optparse.OptionValueError
250
- # XXX add to documentation
251
-
252
- def input_password(optdict, question='password:'):
253
- from getpass import getpass
254
- while True:
255
- value = getpass(question)
256
- value2 = getpass('confirm: ')
257
- if value == value2:
258
- return value
259
- print('password mismatch, try again')
260
-
261
- def input_string(optdict, question):
262
- value = input(question).strip()
263
- return value or None
264
-
265
- def _make_input_function(opttype):
266
- def input_validator(optdict, question):
267
- while True:
268
- value = input(question)
269
- if not value.strip():
270
- return None
271
- try:
272
- return _call_validator(opttype, optdict, None, value)
273
- except optik_ext.OptionValueError as ex:
274
- msg = str(ex).split(':', 1)[-1].strip()
275
- print('bad value: %s' % msg)
276
- return input_validator
277
-
278
- INPUT_FUNCTIONS = {
279
- 'string': input_string,
280
- 'password': input_password,
281
- }
282
-
283
- for opttype in VALIDATORS.keys():
284
- INPUT_FUNCTIONS.setdefault(opttype, _make_input_function(opttype))
285
-
286
- # utility functions ############################################################
287
-
288
- def expand_default(self, option):
289
- """monkey patch OptionParser.expand_default since we have a particular
290
- way to handle defaults to avoid overriding values in the configuration
291
- file
292
- """
293
- if self.parser is None or not self.default_tag:
294
- return option.help
295
- optname = option._long_opts[0][2:]
296
- try:
297
- provider = self.parser.options_manager._all_options[optname]
298
- except KeyError:
299
- value = None
300
- else:
301
- optdict = provider.get_option_def(optname)
302
- optname = provider.option_attrname(optname, optdict)
303
- value = getattr(provider.config, optname, optdict)
304
- value = format_option_value(optdict, value)
305
- if value is optik_ext.NO_DEFAULT or not value:
306
- value = self.NO_DEFAULT_VALUE
307
- return option.help.replace(self.default_tag, str(value))
308
-
309
-
310
- def _validate(value, optdict, name=''):
311
- """return a validated value for an option according to its type
312
-
313
- optional argument name is only used for error message formatting
314
- """
315
- try:
316
- _type = optdict['type']
317
- except KeyError:
318
- # FIXME
319
- return value
320
- return _call_validator(_type, optdict, name, value)
321
- convert = deprecated('[0.60] convert() was renamed _validate()')(_validate)
322
-
323
- # format and output functions ##################################################
324
-
325
- def comment(string):
326
- """return string as a comment"""
327
- lines = [line.strip() for line in string.splitlines()]
328
- return '# ' + ('%s# ' % os.linesep).join(lines)
329
-
330
- def format_time(value):
331
- if not value:
332
- return '0'
333
- if value != int(value):
334
- return '%.2fs' % value
335
- value = int(value)
336
- nbmin, nbsec = divmod(value, 60)
337
- if nbsec:
338
- return '%ss' % value
339
- nbhour, nbmin_ = divmod(nbmin, 60)
340
- if nbmin_:
341
- return '%smin' % nbmin
342
- nbday, nbhour_ = divmod(nbhour, 24)
343
- if nbhour_:
344
- return '%sh' % nbhour
345
- return '%sd' % nbday
346
-
347
- def format_bytes(value):
348
- if not value:
349
- return '0'
350
- if value != int(value):
351
- return '%.2fB' % value
352
- value = int(value)
353
- prevunit = 'B'
354
- for unit in ('KB', 'MB', 'GB', 'TB'):
355
- next, remain = divmod(value, 1024)
356
- if remain:
357
- return '%s%s' % (value, prevunit)
358
- prevunit = unit
359
- value = next
360
- return '%s%s' % (value, unit)
361
-
362
- def format_option_value(optdict, value):
363
- """return the user input's value from a 'compiled' value"""
364
- if isinstance(value, (list, tuple)):
365
- value = ','.join(value)
366
- elif isinstance(value, dict):
367
- value = ','.join(['%s:%s' % (k, v) for k, v in value.items()])
368
- elif hasattr(value, 'match'): # optdict.get('type') == 'regexp'
369
- # compiled regexp
370
- value = value.pattern
371
- elif optdict.get('type') == 'yn':
372
- value = value and 'yes' or 'no'
373
- elif isinstance(value, string_types) and value.isspace():
374
- value = "'%s'" % value
375
- elif optdict.get('type') == 'time' and isinstance(value, (float, int, long)):
376
- value = format_time(value)
377
- elif optdict.get('type') == 'bytes' and hasattr(value, '__int__'):
378
- value = format_bytes(value)
379
- return value
380
-
381
- def ini_format_section(stream, section, options, encoding=None, doc=None):
382
- """format an options section using the INI format"""
383
- encoding = _get_encoding(encoding, stream)
384
- if doc:
385
- print(_encode(comment(doc), encoding), file=stream)
386
- print('[%s]' % section, file=stream)
387
- ini_format(stream, options, encoding)
388
-
389
- def ini_format(stream, options, encoding):
390
- """format options using the INI format"""
391
- for optname, optdict, value in options:
392
- value = format_option_value(optdict, value)
393
- help = optdict.get('help')
394
- if help:
395
- help = normalize_text(help, line_len=79, indent='# ')
396
- print(file=stream)
397
- print(_encode(help, encoding), file=stream)
398
- else:
399
- print(file=stream)
400
- if value is None:
401
- print('#%s=' % optname, file=stream)
402
- else:
403
- value = _encode(value, encoding).strip()
404
- print('%s=%s' % (optname, value), file=stream)
405
-
406
- format_section = ini_format_section
407
-
408
- def rest_format_section(stream, section, options, encoding=None, doc=None):
409
- """format an options section using as ReST formatted output"""
410
- encoding = _get_encoding(encoding, stream)
411
- if section:
412
- print('%s\n%s' % (section, "'"*len(section)), file=stream)
413
- if doc:
414
- print(_encode(normalize_text(doc, line_len=79, indent=''), encoding), file=stream)
415
- print(file=stream)
416
- for optname, optdict, value in options:
417
- help = optdict.get('help')
418
- print(':%s:' % optname, file=stream)
419
- if help:
420
- help = normalize_text(help, line_len=79, indent=' ')
421
- print(_encode(help, encoding), file=stream)
422
- if value:
423
- value = _encode(format_option_value(optdict, value), encoding)
424
- print(file=stream)
425
- print(' Default: ``%s``' % value.replace("`` ", "```` ``"), file=stream)
426
-
427
- # Options Manager ##############################################################
428
-
429
- class OptionsManagerMixIn(object):
430
- """MixIn to handle a configuration from both a configuration file and
431
- command line options
432
- """
433
-
434
- def __init__(self, usage, config_file=None, version=None, quiet=0):
435
- self.config_file = config_file
436
- self.reset_parsers(usage, version=version)
437
- # list of registered options providers
438
- self.options_providers = []
439
- # dictionary associating option name to checker
440
- self._all_options = {}
441
- self._short_options = {}
442
- self._nocallback_options = {}
443
- self._mygroups = dict()
444
- # verbosity
445
- self.quiet = quiet
446
- self._maxlevel = 0
447
-
448
- def reset_parsers(self, usage='', version=None):
449
- # configuration file parser
450
- self.cfgfile_parser = cp.ConfigParser()
451
- # command line parser
452
- self.cmdline_parser = optik_ext.OptionParser(usage=usage, version=version)
453
- self.cmdline_parser.options_manager = self
454
- self._optik_option_attrs = set(self.cmdline_parser.option_class.ATTRS)
455
-
456
- def register_options_provider(self, provider, own_group=True):
457
- """register an options provider"""
458
- assert provider.priority <= 0, "provider's priority can't be >= 0"
459
- for i in range(len(self.options_providers)):
460
- if provider.priority > self.options_providers[i].priority:
461
- self.options_providers.insert(i, provider)
462
- break
463
- else:
464
- self.options_providers.append(provider)
465
- non_group_spec_options = [option for option in provider.options
466
- if 'group' not in option[1]]
467
- groups = getattr(provider, 'option_groups', ())
468
- if own_group and non_group_spec_options:
469
- self.add_option_group(provider.name.upper(), provider.__doc__,
470
- non_group_spec_options, provider)
471
- else:
472
- for opt, optdict in non_group_spec_options:
473
- self.add_optik_option(provider, self.cmdline_parser, opt, optdict)
474
- for gname, gdoc in groups:
475
- gname = gname.upper()
476
- goptions = [option for option in provider.options
477
- if option[1].get('group', '').upper() == gname]
478
- self.add_option_group(gname, gdoc, goptions, provider)
479
-
480
- def add_option_group(self, group_name, doc, options, provider):
481
- """add an option group including the listed options
482
- """
483
- assert options
484
- # add option group to the command line parser
485
- if group_name in self._mygroups:
486
- group = self._mygroups[group_name]
487
- else:
488
- group = optik_ext.OptionGroup(self.cmdline_parser,
489
- title=group_name.capitalize())
490
- self.cmdline_parser.add_option_group(group)
491
- group.level = provider.level
492
- self._mygroups[group_name] = group
493
- # add section to the config file
494
- if group_name != "DEFAULT":
495
- self.cfgfile_parser.add_section(group_name)
496
- # add provider's specific options
497
- for opt, optdict in options:
498
- self.add_optik_option(provider, group, opt, optdict)
499
-
500
- def add_optik_option(self, provider, optikcontainer, opt, optdict):
501
- if 'inputlevel' in optdict:
502
- warn('[0.50] "inputlevel" in option dictionary for %s is deprecated,'
503
- ' use "level"' % opt, DeprecationWarning)
504
- optdict['level'] = optdict.pop('inputlevel')
505
- args, optdict = self.optik_option(provider, opt, optdict)
506
- option = optikcontainer.add_option(*args, **optdict)
507
- self._all_options[opt] = provider
508
- self._maxlevel = max(self._maxlevel, option.level or 0)
509
-
510
- def optik_option(self, provider, opt, optdict):
511
- """get our personal option definition and return a suitable form for
512
- use with optik/optparse
513
- """
514
- optdict = copy(optdict)
515
- others = {}
516
- if 'action' in optdict:
517
- self._nocallback_options[provider] = opt
518
- else:
519
- optdict['action'] = 'callback'
520
- optdict['callback'] = self.cb_set_provider_option
521
- # default is handled here and *must not* be given to optik if you
522
- # want the whole machinery to work
523
- if 'default' in optdict:
524
- if ('help' in optdict
525
- and optdict.get('default') is not None
526
- and not optdict['action'] in ('store_true', 'store_false')):
527
- optdict['help'] += ' [current: %default]'
528
- del optdict['default']
529
- args = ['--' + str(opt)]
530
- if 'short' in optdict:
531
- self._short_options[optdict['short']] = opt
532
- args.append('-' + optdict['short'])
533
- del optdict['short']
534
- # cleanup option definition dict before giving it to optik
535
- for key in list(optdict.keys()):
536
- if not key in self._optik_option_attrs:
537
- optdict.pop(key)
538
- return args, optdict
539
-
540
- def cb_set_provider_option(self, option, opt, value, parser):
541
- """optik callback for option setting"""
542
- if opt.startswith('--'):
543
- # remove -- on long option
544
- opt = opt[2:]
545
- else:
546
- # short option, get its long equivalent
547
- opt = self._short_options[opt[1:]]
548
- # trick since we can't set action='store_true' on options
549
- if value is None:
550
- value = 1
551
- self.global_set_option(opt, value)
552
-
553
- def global_set_option(self, opt, value):
554
- """set option on the correct option provider"""
555
- self._all_options[opt].set_option(opt, value)
556
-
557
- def generate_config(self, stream=None, skipsections=(), encoding=None):
558
- """write a configuration file according to the current configuration
559
- into the given stream or stdout
560
- """
561
- options_by_section = {}
562
- sections = []
563
- for provider in self.options_providers:
564
- for section, options in provider.options_by_section():
565
- if section is None:
566
- section = provider.name
567
- if section in skipsections:
568
- continue
569
- options = [(n, d, v) for (n, d, v) in options
570
- if d.get('type') is not None]
571
- if not options:
572
- continue
573
- if not section in sections:
574
- sections.append(section)
575
- alloptions = options_by_section.setdefault(section, [])
576
- alloptions += options
577
- stream = stream or sys.stdout
578
- encoding = _get_encoding(encoding, stream)
579
- printed = False
580
- for section in sections:
581
- if printed:
582
- print('\n', file=stream)
583
- format_section(stream, section.upper(), options_by_section[section],
584
- encoding)
585
- printed = True
586
-
587
- def generate_manpage(self, pkginfo, section=1, stream=None):
588
- """write a man page for the current configuration into the given
589
- stream or stdout
590
- """
591
- self._monkeypatch_expand_default()
592
- try:
593
- optik_ext.generate_manpage(self.cmdline_parser, pkginfo,
594
- section, stream=stream or sys.stdout,
595
- level=self._maxlevel)
596
- finally:
597
- self._unmonkeypatch_expand_default()
598
-
599
- # initialization methods ##################################################
600
-
601
- def load_provider_defaults(self):
602
- """initialize configuration using default values"""
603
- for provider in self.options_providers:
604
- provider.load_defaults()
605
-
606
- def load_file_configuration(self, config_file=None):
607
- """load the configuration from file"""
608
- self.read_config_file(config_file)
609
- self.load_config_file()
610
-
611
- def read_config_file(self, config_file=None):
612
- """read the configuration file but do not load it (i.e. dispatching
613
- values to each options provider)
614
- """
615
- helplevel = 1
616
- while helplevel <= self._maxlevel:
617
- opt = '-'.join(['long'] * helplevel) + '-help'
618
- if opt in self._all_options:
619
- break # already processed
620
- def helpfunc(option, opt, val, p, level=helplevel):
621
- print(self.help(level))
622
- sys.exit(0)
623
- helpmsg = '%s verbose help.' % ' '.join(['more'] * helplevel)
624
- optdict = {'action' : 'callback', 'callback' : helpfunc,
625
- 'help' : helpmsg}
626
- provider = self.options_providers[0]
627
- self.add_optik_option(provider, self.cmdline_parser, opt, optdict)
628
- provider.options += ( (opt, optdict), )
629
- helplevel += 1
630
- if config_file is None:
631
- config_file = self.config_file
632
- if config_file is not None:
633
- config_file = expanduser(config_file)
634
- if config_file and exists(config_file):
635
- parser = self.cfgfile_parser
636
- parser.read([config_file])
637
- # normalize sections'title
638
- for sect, values in parser._sections.items():
639
- if not sect.isupper() and values:
640
- parser._sections[sect.upper()] = values
641
- elif not self.quiet:
642
- msg = 'No config file found, using default configuration'
643
- print(msg, file=sys.stderr)
644
- return
645
-
646
- def input_config(self, onlysection=None, inputlevel=0, stream=None):
647
- """interactively get configuration values by asking to the user and generate
648
- a configuration file
649
- """
650
- if onlysection is not None:
651
- onlysection = onlysection.upper()
652
- for provider in self.options_providers:
653
- for section, option, optdict in provider.all_options():
654
- if onlysection is not None and section != onlysection:
655
- continue
656
- if not 'type' in optdict:
657
- # ignore action without type (callback, store_true...)
658
- continue
659
- provider.input_option(option, optdict, inputlevel)
660
- # now we can generate the configuration file
661
- if stream is not None:
662
- self.generate_config(stream)
663
-
664
- def load_config_file(self):
665
- """dispatch values previously read from a configuration file to each
666
- options provider)
667
- """
668
- parser = self.cfgfile_parser
669
- for section in parser.sections():
670
- for option, value in parser.items(section):
671
- try:
672
- self.global_set_option(option, value)
673
- except (KeyError, OptionError):
674
- # TODO handle here undeclared options appearing in the config file
675
- continue
676
-
677
- def load_configuration(self, **kwargs):
678
- """override configuration according to given parameters
679
- """
680
- for opt, opt_value in kwargs.items():
681
- opt = opt.replace('_', '-')
682
- provider = self._all_options[opt]
683
- provider.set_option(opt, opt_value)
684
-
685
- def load_command_line_configuration(self, args=None):
686
- """override configuration according to command line parameters
687
-
688
- return additional arguments
689
- """
690
- self._monkeypatch_expand_default()
691
- try:
692
- if args is None:
693
- args = sys.argv[1:]
694
- else:
695
- args = list(args)
696
- (options, args) = self.cmdline_parser.parse_args(args=args)
697
- for provider in self._nocallback_options.keys():
698
- config = provider.config
699
- for attr in config.__dict__.keys():
700
- value = getattr(options, attr, None)
701
- if value is None:
702
- continue
703
- setattr(config, attr, value)
704
- return args
705
- finally:
706
- self._unmonkeypatch_expand_default()
707
-
708
-
709
- # help methods ############################################################
710
-
711
- def add_help_section(self, title, description, level=0):
712
- """add a dummy option section for help purpose """
713
- group = optik_ext.OptionGroup(self.cmdline_parser,
714
- title=title.capitalize(),
715
- description=description)
716
- group.level = level
717
- self._maxlevel = max(self._maxlevel, level)
718
- self.cmdline_parser.add_option_group(group)
719
-
720
- def _monkeypatch_expand_default(self):
721
- # monkey patch optik_ext to deal with our default values
722
- try:
723
- self.__expand_default_backup = optik_ext.HelpFormatter.expand_default
724
- optik_ext.HelpFormatter.expand_default = expand_default
725
- except AttributeError:
726
- # python < 2.4: nothing to be done
727
- pass
728
- def _unmonkeypatch_expand_default(self):
729
- # remove monkey patch
730
- if hasattr(optik_ext.HelpFormatter, 'expand_default'):
731
- # unpatch optik_ext to avoid side effects
732
- optik_ext.HelpFormatter.expand_default = self.__expand_default_backup
733
-
734
- def help(self, level=0):
735
- """return the usage string for available options """
736
- self.cmdline_parser.formatter.output_level = level
737
- self._monkeypatch_expand_default()
738
- try:
739
- return self.cmdline_parser.format_help()
740
- finally:
741
- self._unmonkeypatch_expand_default()
742
-
743
-
744
- class Method(object):
745
- """used to ease late binding of default method (so you can define options
746
- on the class using default methods on the configuration instance)
747
- """
748
- def __init__(self, methname):
749
- self.method = methname
750
- self._inst = None
751
-
752
- def bind(self, instance):
753
- """bind the method to its instance"""
754
- if self._inst is None:
755
- self._inst = instance
756
-
757
- def __call__(self, *args, **kwargs):
758
- assert self._inst, 'unbound method'
759
- return getattr(self._inst, self.method)(*args, **kwargs)
760
-
761
- # Options Provider #############################################################
762
-
763
- class OptionsProviderMixIn(object):
764
- """Mixin to provide options to an OptionsManager"""
765
-
766
- # those attributes should be overridden
767
- priority = -1
768
- name = 'default'
769
- options = ()
770
- level = 0
771
-
772
- def __init__(self):
773
- self.config = optik_ext.Values()
774
- for option in self.options:
775
- try:
776
- option, optdict = option
777
- except ValueError:
778
- raise Exception('Bad option: %r' % option)
779
- if isinstance(optdict.get('default'), Method):
780
- optdict['default'].bind(self)
781
- elif isinstance(optdict.get('callback'), Method):
782
- optdict['callback'].bind(self)
783
- self.load_defaults()
784
-
785
- def load_defaults(self):
786
- """initialize the provider using default values"""
787
- for opt, optdict in self.options:
788
- action = optdict.get('action')
789
- if action != 'callback':
790
- # callback action have no default
791
- default = self.option_default(opt, optdict)
792
- if default is REQUIRED:
793
- continue
794
- self.set_option(opt, default, action, optdict)
795
-
796
- def option_default(self, opt, optdict=None):
797
- """return the default value for an option"""
798
- if optdict is None:
799
- optdict = self.get_option_def(opt)
800
- default = optdict.get('default')
801
- if callable(default):
802
- default = default()
803
- return default
804
-
805
- def option_attrname(self, opt, optdict=None):
806
- """get the config attribute corresponding to opt
807
- """
808
- if optdict is None:
809
- optdict = self.get_option_def(opt)
810
- return optdict.get('dest', opt.replace('-', '_'))
811
- option_name = deprecated('[0.60] OptionsProviderMixIn.option_name() was renamed to option_attrname()')(option_attrname)
812
-
813
- def option_value(self, opt):
814
- """get the current value for the given option"""
815
- return getattr(self.config, self.option_attrname(opt), None)
816
-
817
- def set_option(self, opt, value, action=None, optdict=None):
818
- """method called to set an option (registered in the options list)
819
- """
820
- if optdict is None:
821
- optdict = self.get_option_def(opt)
822
- if value is not None:
823
- value = _validate(value, optdict, opt)
824
- if action is None:
825
- action = optdict.get('action', 'store')
826
- if optdict.get('type') == 'named': # XXX need specific handling
827
- optname = self.option_attrname(opt, optdict)
828
- currentvalue = getattr(self.config, optname, None)
829
- if currentvalue:
830
- currentvalue.update(value)
831
- value = currentvalue
832
- if action == 'store':
833
- setattr(self.config, self.option_attrname(opt, optdict), value)
834
- elif action in ('store_true', 'count'):
835
- setattr(self.config, self.option_attrname(opt, optdict), 0)
836
- elif action == 'store_false':
837
- setattr(self.config, self.option_attrname(opt, optdict), 1)
838
- elif action == 'append':
839
- opt = self.option_attrname(opt, optdict)
840
- _list = getattr(self.config, opt, None)
841
- if _list is None:
842
- if isinstance(value, (list, tuple)):
843
- _list = value
844
- elif value is not None:
845
- _list = []
846
- _list.append(value)
847
- setattr(self.config, opt, _list)
848
- elif isinstance(_list, tuple):
849
- setattr(self.config, opt, _list + (value,))
850
- else:
851
- _list.append(value)
852
- elif action == 'callback':
853
- optdict['callback'](None, opt, value, None)
854
- else:
855
- raise UnsupportedAction(action)
856
-
857
- def input_option(self, option, optdict, inputlevel=99):
858
- default = self.option_default(option, optdict)
859
- if default is REQUIRED:
860
- defaultstr = '(required): '
861
- elif optdict.get('level', 0) > inputlevel:
862
- return
863
- elif optdict['type'] == 'password' or default is None:
864
- defaultstr = ': '
865
- else:
866
- defaultstr = '(default: %s): ' % format_option_value(optdict, default)
867
- print(':%s:' % option)
868
- print(optdict.get('help') or option)
869
- inputfunc = INPUT_FUNCTIONS[optdict['type']]
870
- value = inputfunc(optdict, defaultstr)
871
- while default is REQUIRED and not value:
872
- print('please specify a value')
873
- value = inputfunc(optdict, '%s: ' % option)
874
- if value is None and default is not None:
875
- value = default
876
- self.set_option(option, value, optdict=optdict)
877
-
878
- def get_option_def(self, opt):
879
- """return the dictionary defining an option given it's name"""
880
- assert self.options
881
- for option in self.options:
882
- if option[0] == opt:
883
- return option[1]
884
- raise OptionError('no such option %s in section %r'
885
- % (opt, self.name), opt)
886
-
887
-
888
- def all_options(self):
889
- """return an iterator on available options for this provider
890
- option are actually described by a 3-uple:
891
- (section, option name, option dictionary)
892
- """
893
- for section, options in self.options_by_section():
894
- if section is None:
895
- if self.name is None:
896
- continue
897
- section = self.name.upper()
898
- for option, optiondict, value in options:
899
- yield section, option, optiondict
900
-
901
- def options_by_section(self):
902
- """return an iterator on options grouped by section
903
-
904
- (section, [list of (optname, optdict, optvalue)])
905
- """
906
- sections = {}
907
- for optname, optdict in self.options:
908
- sections.setdefault(optdict.get('group'), []).append(
909
- (optname, optdict, self.option_value(optname)))
910
- if None in sections:
911
- yield None, sections.pop(None)
912
- for section, options in sections.items():
913
- yield section.upper(), options
914
-
915
- def options_and_values(self, options=None):
916
- if options is None:
917
- options = self.options
918
- for optname, optdict in options:
919
- yield (optname, optdict, self.option_value(optname))
920
-
921
- # configuration ################################################################
922
-
923
- class ConfigurationMixIn(OptionsManagerMixIn, OptionsProviderMixIn):
924
- """basic mixin for simple configurations which don't need the
925
- manager / providers model
926
- """
927
- def __init__(self, *args, **kwargs):
928
- if not args:
929
- kwargs.setdefault('usage', '')
930
- kwargs.setdefault('quiet', 1)
931
- OptionsManagerMixIn.__init__(self, *args, **kwargs)
932
- OptionsProviderMixIn.__init__(self)
933
- if not getattr(self, 'option_groups', None):
934
- self.option_groups = []
935
- for option, optdict in self.options:
936
- try:
937
- gdef = (optdict['group'].upper(), '')
938
- except KeyError:
939
- continue
940
- if not gdef in self.option_groups:
941
- self.option_groups.append(gdef)
942
- self.register_options_provider(self, own_group=False)
943
-
944
- def register_options(self, options):
945
- """add some options to the configuration"""
946
- options_by_group = {}
947
- for optname, optdict in options:
948
- options_by_group.setdefault(optdict.get('group', self.name.upper()), []).append((optname, optdict))
949
- for group, options in options_by_group.items():
950
- self.add_option_group(group, None, options, self)
951
- self.options += tuple(options)
952
-
953
- def load_defaults(self):
954
- OptionsProviderMixIn.load_defaults(self)
955
-
956
- def __iter__(self):
957
- return iter(self.config.__dict__.iteritems())
958
-
959
- def __getitem__(self, key):
960
- try:
961
- return getattr(self.config, self.option_attrname(key))
962
- except (optik_ext.OptionValueError, AttributeError):
963
- raise KeyError(key)
964
-
965
- def __setitem__(self, key, value):
966
- self.set_option(key, value)
967
-
968
- def get(self, key, default=None):
969
- try:
970
- return getattr(self.config, self.option_attrname(key))
971
- except (OptionError, AttributeError):
972
- return default
973
-
974
-
975
- class Configuration(ConfigurationMixIn):
976
- """class for simple configurations which don't need the
977
- manager / providers model and prefer delegation to inheritance
978
-
979
- configuration values are accessible through a dict like interface
980
- """
981
-
982
- def __init__(self, config_file=None, options=None, name=None,
983
- usage=None, doc=None, version=None):
984
- if options is not None:
985
- self.options = options
986
- if name is not None:
987
- self.name = name
988
- if doc is not None:
989
- self.__doc__ = doc
990
- super(Configuration, self).__init__(config_file=config_file, usage=usage, version=version)
991
-
992
-
993
- class OptionsManager2ConfigurationAdapter(object):
994
- """Adapt an option manager to behave like a
995
- `logilab.common.configuration.Configuration` instance
996
- """
997
- def __init__(self, provider):
998
- self.config = provider
999
-
1000
- def __getattr__(self, key):
1001
- return getattr(self.config, key)
1002
-
1003
- def __getitem__(self, key):
1004
- provider = self.config._all_options[key]
1005
- try:
1006
- return getattr(provider.config, provider.option_attrname(key))
1007
- except AttributeError:
1008
- raise KeyError(key)
1009
-
1010
- def __setitem__(self, key, value):
1011
- self.config.global_set_option(self.config.option_attrname(key), value)
1012
-
1013
- def get(self, key, default=None):
1014
- provider = self.config._all_options[key]
1015
- try:
1016
- return getattr(provider.config, provider.option_attrname(key))
1017
- except AttributeError:
1018
- return default
1019
-
1020
- # other functions ##############################################################
1021
-
1022
- def read_old_config(newconfig, changes, configfile):
1023
- """initialize newconfig from a deprecated configuration file
1024
-
1025
- possible changes:
1026
- * ('renamed', oldname, newname)
1027
- * ('moved', option, oldgroup, newgroup)
1028
- * ('typechanged', option, oldtype, newvalue)
1029
- """
1030
- # build an index of changes
1031
- changesindex = {}
1032
- for action in changes:
1033
- if action[0] == 'moved':
1034
- option, oldgroup, newgroup = action[1:]
1035
- changesindex.setdefault(option, []).append((action[0], oldgroup, newgroup))
1036
- continue
1037
- if action[0] == 'renamed':
1038
- oldname, newname = action[1:]
1039
- changesindex.setdefault(newname, []).append((action[0], oldname))
1040
- continue
1041
- if action[0] == 'typechanged':
1042
- option, oldtype, newvalue = action[1:]
1043
- changesindex.setdefault(option, []).append((action[0], oldtype, newvalue))
1044
- continue
1045
- if action[1] in ('added', 'removed'):
1046
- continue # nothing to do here
1047
- raise Exception('unknown change %s' % action[0])
1048
- # build a config object able to read the old config
1049
- options = []
1050
- for optname, optdef in newconfig.options:
1051
- for action in changesindex.pop(optname, ()):
1052
- if action[0] == 'moved':
1053
- oldgroup, newgroup = action[1:]
1054
- optdef = optdef.copy()
1055
- optdef['group'] = oldgroup
1056
- elif action[0] == 'renamed':
1057
- optname = action[1]
1058
- elif action[0] == 'typechanged':
1059
- oldtype = action[1]
1060
- optdef = optdef.copy()
1061
- optdef['type'] = oldtype
1062
- options.append((optname, optdef))
1063
- if changesindex:
1064
- raise Exception('unapplied changes: %s' % changesindex)
1065
- oldconfig = Configuration(options=options, name=newconfig.name)
1066
- # read the old config
1067
- oldconfig.load_file_configuration(configfile)
1068
- # apply values reverting changes
1069
- changes.reverse()
1070
- done = set()
1071
- for action in changes:
1072
- if action[0] == 'renamed':
1073
- oldname, newname = action[1:]
1074
- newconfig[newname] = oldconfig[oldname]
1075
- done.add(newname)
1076
- elif action[0] == 'typechanged':
1077
- optname, oldtype, newvalue = action[1:]
1078
- newconfig[optname] = newvalue
1079
- done.add(optname)
1080
- for optname, optdef in newconfig.options:
1081
- if optdef.get('type') and not optname in done:
1082
- newconfig.set_option(optname, oldconfig[optname], optdict=optdef)
1083
-
1084
-
1085
- def merge_options(options, optgroup=None):
1086
- """preprocess a list of options and remove duplicates, returning a new list
1087
- (tuple actually) of options.
1088
-
1089
- Options dictionaries are copied to avoid later side-effect. Also, if
1090
- `otpgroup` argument is specified, ensure all options are in the given group.
1091
- """
1092
- alloptions = {}
1093
- options = list(options)
1094
- for i in range(len(options)-1, -1, -1):
1095
- optname, optdict = options[i]
1096
- if optname in alloptions:
1097
- options.pop(i)
1098
- alloptions[optname].update(optdict)
1099
- else:
1100
- optdict = optdict.copy()
1101
- options[i] = (optname, optdict)
1102
- alloptions[optname] = optdict
1103
- if optgroup is not None:
1104
- alloptions[optname]['group'] = optgroup
1105
- return tuple(options)