sproutit-sproutcore 1.0.0.20090407205609
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Buildfile +115 -0
- data/History.txt +7 -0
- data/README.txt +102 -0
- data/Rakefile +54 -0
- data/Todo.txt +1 -0
- data/bin/sc-build +13 -0
- data/bin/sc-build-number +13 -0
- data/bin/sc-gen +13 -0
- data/bin/sc-init +13 -0
- data/bin/sc-manifest +13 -0
- data/bin/sc-server +13 -0
- data/bin/sproutcore +14 -0
- data/buildtasks/build.rake +73 -0
- data/buildtasks/entry.rake +59 -0
- data/buildtasks/manifest.rake +469 -0
- data/buildtasks/render.rake +21 -0
- data/buildtasks/target.rake +42 -0
- data/gen/Buildfile +16 -0
- data/gen/app/Buildfile +36 -0
- data/gen/app/README +1 -0
- data/gen/app/USAGE +13 -0
- data/gen/app/templates/apps/{target_name}/core.js +27 -0
- data/gen/app/templates/apps/{target_name}/english.lproj/loading.rhtml +9 -0
- data/gen/app/templates/apps/{target_name}/english.lproj/main_page.js +22 -0
- data/gen/app/templates/apps/{target_name}/english.lproj/strings.js +15 -0
- data/gen/app/templates/apps/{target_name}/main.js +30 -0
- data/gen/controller/Buildfile +18 -0
- data/gen/controller/README +1 -0
- data/gen/controller/USAGE +13 -0
- data/gen/controller/templates/controllers/{filename}.js +18 -0
- data/gen/controller/templates/tests/controllers/{filename}.js +15 -0
- data/gen/framework/Buildfile +36 -0
- data/gen/framework/README +1 -0
- data/gen/framework/USAGE +13 -0
- data/gen/framework/templates/frameworks/{target_name}/core.js +21 -0
- data/gen/framework/templates/frameworks/{target_name}/english.lproj/strings.js +15 -0
- data/gen/language/Buildfile +26 -0
- data/gen/language/README +1 -0
- data/gen/language/USAGE +13 -0
- data/gen/language/templates/{filename}/strings.js +14 -0
- data/gen/model/Buildfile +16 -0
- data/gen/model/README +1 -0
- data/gen/model/USAGE +15 -0
- data/gen/model/templates/fixtures/{filename}.js +35 -0
- data/gen/model/templates/models/{filename}.js +19 -0
- data/gen/model/templates/tests/models/{filename}.js +15 -0
- data/gen/project/Buildfile +45 -0
- data/gen/project/INIT +3 -0
- data/gen/project/README +1 -0
- data/gen/project/USAGE +2 -0
- data/gen/project/templates/{filename}/Buildfile +7 -0
- data/gen/project/templates/{filename}/README +7 -0
- data/gen/test/Buildfile +25 -0
- data/gen/test/README +1 -0
- data/gen/test/USAGE +12 -0
- data/gen/test/templates/tests/{filename}.js +15 -0
- data/gen/theme/Buildfile +36 -0
- data/gen/theme/README +1 -0
- data/gen/theme/USAGE +13 -0
- data/gen/theme/templates/themes/{target_name}/english.lproj/strings.js +15 -0
- data/gen/view/Buildfile +18 -0
- data/gen/view/README +1 -0
- data/gen/view/USAGE +13 -0
- data/gen/view/templates/tests/views/{filename}.js +15 -0
- data/gen/view/templates/views/{filename}.js +18 -0
- data/lib/sproutcore.rb +130 -0
- data/lib/sproutcore/builders/base.rb +79 -0
- data/lib/sproutcore/builders/combine.rb +37 -0
- data/lib/sproutcore/builders/html.rb +177 -0
- data/lib/sproutcore/builders/javascript.rb +55 -0
- data/lib/sproutcore/builders/minify.rb +67 -0
- data/lib/sproutcore/builders/sass.rb +55 -0
- data/lib/sproutcore/builders/strings.rb +44 -0
- data/lib/sproutcore/builders/stylesheet.rb +40 -0
- data/lib/sproutcore/builders/test.rb +58 -0
- data/lib/sproutcore/builders/test_index.rb +26 -0
- data/lib/sproutcore/buildfile.rb +483 -0
- data/lib/sproutcore/buildfile/build_task.rb +33 -0
- data/lib/sproutcore/buildfile/buildfile_dsl.rb +162 -0
- data/lib/sproutcore/buildfile/cloneable.rb +34 -0
- data/lib/sproutcore/buildfile/early_time.rb +29 -0
- data/lib/sproutcore/buildfile/invocation_chain.rb +64 -0
- data/lib/sproutcore/buildfile/namespace.rb +33 -0
- data/lib/sproutcore/buildfile/string_ext.rb +198 -0
- data/lib/sproutcore/buildfile/task.rb +304 -0
- data/lib/sproutcore/buildfile/task_arguments.rb +86 -0
- data/lib/sproutcore/buildfile/task_manager.rb +193 -0
- data/lib/sproutcore/deprecated/view_helper.rb +662 -0
- data/lib/sproutcore/helpers/capture_helper.rb +30 -0
- data/lib/sproutcore/helpers/cssmin.rb +202 -0
- data/lib/sproutcore/helpers/dom_id_helper.rb +21 -0
- data/lib/sproutcore/helpers/entry_sorter.rb +105 -0
- data/lib/sproutcore/helpers/packed_optimizer.rb +102 -0
- data/lib/sproutcore/helpers/static_helper.rb +268 -0
- data/lib/sproutcore/helpers/tag_helper.rb +117 -0
- data/lib/sproutcore/helpers/text_helper.rb +303 -0
- data/lib/sproutcore/models/generator.rb +493 -0
- data/lib/sproutcore/models/hash_struct.rb +109 -0
- data/lib/sproutcore/models/manifest.rb +342 -0
- data/lib/sproutcore/models/manifest_entry.rb +232 -0
- data/lib/sproutcore/models/project.rb +270 -0
- data/lib/sproutcore/models/target.rb +403 -0
- data/lib/sproutcore/rack/builder.rb +269 -0
- data/lib/sproutcore/rack/dev.rb +51 -0
- data/lib/sproutcore/rack/docs.rb +24 -0
- data/lib/sproutcore/rack/proxy.rb +92 -0
- data/lib/sproutcore/rack/service.rb +141 -0
- data/lib/sproutcore/rack/test_runner.rb +24 -0
- data/lib/sproutcore/render_engines/erubis.rb +55 -0
- data/lib/sproutcore/render_engines/haml.rb +39 -0
- data/lib/sproutcore/tools.rb +311 -0
- data/lib/sproutcore/tools/build.rb +80 -0
- data/lib/sproutcore/tools/build_number.rb +23 -0
- data/lib/sproutcore/tools/gen.rb +99 -0
- data/lib/sproutcore/tools/init.rb +40 -0
- data/lib/sproutcore/tools/manifest.rb +84 -0
- data/lib/sproutcore/tools/server.rb +45 -0
- data/spec/buildtasks/build/copy_spec.rb +60 -0
- data/spec/buildtasks/build/spec_helper.rb +36 -0
- data/spec/buildtasks/manifest/catalog_spec.rb +48 -0
- data/spec/buildtasks/manifest/hide_buildfiles_spec.rb +125 -0
- data/spec/buildtasks/manifest/localize_spec.rb +97 -0
- data/spec/buildtasks/manifest/prepare_build_tasks/combine_spec.rb +246 -0
- data/spec/buildtasks/manifest/prepare_build_tasks/css_spec.rb +87 -0
- data/spec/buildtasks/manifest/prepare_build_tasks/html_spec.rb +175 -0
- data/spec/buildtasks/manifest/prepare_build_tasks/javascript_spec.rb +65 -0
- data/spec/buildtasks/manifest/prepare_build_tasks/minify_spec.rb +70 -0
- data/spec/buildtasks/manifest/prepare_build_tasks/packed_spec.rb +152 -0
- data/spec/buildtasks/manifest/prepare_build_tasks/sass_spec.rb +98 -0
- data/spec/buildtasks/manifest/prepare_build_tasks/strings_spec.rb +64 -0
- data/spec/buildtasks/manifest/prepare_build_tasks/tests_spec.rb +163 -0
- data/spec/buildtasks/manifest/prepare_spec.rb +43 -0
- data/spec/buildtasks/manifest/spec_helper.rb +35 -0
- data/spec/buildtasks/target_spec.rb +214 -0
- data/spec/fixtures/builder_tests/Buildfile +15 -0
- data/spec/fixtures/builder_tests/apps/combine_test/a.js +1 -0
- data/spec/fixtures/builder_tests/apps/combine_test/b.js +1 -0
- data/spec/fixtures/builder_tests/apps/combine_test/c.js +1 -0
- data/spec/fixtures/builder_tests/apps/combine_test/english.lproj/a.css +1 -0
- data/spec/fixtures/builder_tests/apps/combine_test/english.lproj/b.css +1 -0
- data/spec/fixtures/builder_tests/apps/combine_test/english.lproj/c.css +1 -0
- data/spec/fixtures/builder_tests/apps/html_test/english.lproj/bar1_sample.rhtml +2 -0
- data/spec/fixtures/builder_tests/apps/html_test/english.lproj/erb_sample.html.erb +1 -0
- data/spec/fixtures/builder_tests/apps/html_test/english.lproj/icons/image.png +0 -0
- data/spec/fixtures/builder_tests/apps/html_test/english.lproj/image.jpg +0 -0
- data/spec/fixtures/builder_tests/apps/html_test/english.lproj/rhtml_sample.rhtml +1 -0
- data/spec/fixtures/builder_tests/apps/html_test/english.lproj/strings.js +4 -0
- data/spec/fixtures/builder_tests/apps/html_test/english.lproj/style.css +0 -0
- data/spec/fixtures/builder_tests/apps/html_test/french.lproj/french-icons/fr.png +0 -0
- data/spec/fixtures/builder_tests/apps/html_test/french.lproj/strings.js +4 -0
- data/spec/fixtures/builder_tests/apps/html_test/lib/layout_template.rhtml +1 -0
- data/spec/fixtures/builder_tests/apps/html_test/scripts.js +0 -0
- data/spec/fixtures/builder_tests/apps/javascript_test/sc_static.js +15 -0
- data/spec/fixtures/builder_tests/apps/javascript_test/sc_super.js +4 -0
- data/spec/fixtures/builder_tests/apps/javascript_test/strings.js +7 -0
- data/spec/fixtures/builder_tests/apps/sass_test/sample.sass +3 -0
- data/spec/fixtures/builder_tests/apps/strings_test/lproj/strings.js +8 -0
- data/spec/fixtures/builder_tests/apps/stylesheet_test/build_directives.css +9 -0
- data/spec/fixtures/builder_tests/apps/stylesheet_test/sc_static.css +12 -0
- data/spec/fixtures/builder_tests/apps/test_test/lib/alt_layout.rhtml +1 -0
- data/spec/fixtures/builder_tests/apps/test_test/lib/test_layout.rhtml +3 -0
- data/spec/fixtures/builder_tests/apps/test_test/tests/qunit_test.js +1 -0
- data/spec/fixtures/builder_tests/apps/test_test/tests/qunit_test2.js +1 -0
- data/spec/fixtures/builder_tests/apps/test_test/tests/rhtml_test.rhtml +4 -0
- data/spec/fixtures/builder_tests/frameworks/debug/core.js +0 -0
- data/spec/fixtures/builder_tests/frameworks/debug/english.lproj/dummy.css +0 -0
- data/spec/fixtures/builder_tests/frameworks/qunit/core.js +0 -0
- data/spec/fixtures/builder_tests/frameworks/qunit/english.lproj/dummy.css +0 -0
- data/spec/fixtures/builder_tests/frameworks/req_target_1/english.lproj/req_style_1.css +0 -0
- data/spec/fixtures/builder_tests/frameworks/req_target_1/english.lproj/strings.js +4 -0
- data/spec/fixtures/builder_tests/frameworks/req_target_1/english.lproj/test.rhtml +1 -0
- data/spec/fixtures/builder_tests/frameworks/req_target_1/req_js_1.js +0 -0
- data/spec/fixtures/builder_tests/frameworks/req_target_2/english.lproj/req_style_2.css +0 -0
- data/spec/fixtures/builder_tests/frameworks/req_target_2/english.lproj/test.rhtml +1 -0
- data/spec/fixtures/builder_tests/frameworks/req_target_2/javascript.js +1 -0
- data/spec/fixtures/builder_tests/frameworks/req_target_2/lib/alt_layout.rhtml +0 -0
- data/spec/fixtures/builder_tests/frameworks/req_target_2/req_js_2.js +0 -0
- data/spec/fixtures/builder_tests/themes/sample_theme/Buildfile +1 -0
- data/spec/fixtures/buildfiles/basic/Buildfile +16 -0
- data/spec/fixtures/buildfiles/basic/task_module.rake +6 -0
- data/spec/fixtures/buildfiles/installed/Buildfile +7 -0
- data/spec/fixtures/buildfiles/installed/Buildfile2 +5 -0
- data/spec/fixtures/buildfiles/project_test/Buildfile +4 -0
- data/spec/fixtures/buildfiles/project_test/not_project/Buildfile +2 -0
- data/spec/fixtures/buildfiles/project_test/not_project/child/PLACEHOLDER +0 -0
- data/spec/fixtures/entry_for_project/Buildfile +1 -0
- data/spec/fixtures/entry_for_project/apps/test_app/entry.txt +0 -0
- data/spec/fixtures/entry_for_project/apps/test_app/frameworks/nested/PLACEHOLDER +0 -0
- data/spec/fixtures/entry_for_project/frameworks/shared/PLACEHOLDER +0 -0
- data/spec/fixtures/find_targets/custom/Buildfile +8 -0
- data/spec/fixtures/find_targets/custom/bars/bar1/bars/bar1/PLACEHOLDER +0 -0
- data/spec/fixtures/find_targets/custom/bars/bar1/bars/bar2/PLACEHOLDER +0 -0
- data/spec/fixtures/find_targets/custom/bars/bar1/foos/foo1/PLACEHOLDER +0 -0
- data/spec/fixtures/find_targets/custom/bars/bar1/foos/foo2/PLACEHOLDER +0 -0
- data/spec/fixtures/find_targets/custom/foos/custom_foos/Buildfile +5 -0
- data/spec/fixtures/find_targets/custom/foos/custom_foos/custom_foodir/foo1/PLACEHOLDER +0 -0
- data/spec/fixtures/find_targets/custom/foos/custom_foos/custom_foodir/foo2/PLACEHOLDER +0 -0
- data/spec/fixtures/find_targets/custom/foos/custom_foos/foos/not_foo1/PLACEHOLDER +0 -0
- data/spec/fixtures/find_targets/custom/foos/foo1/bars/bar1/PLACEHOLDER +0 -0
- data/spec/fixtures/find_targets/custom/foos/foo1/bars/bar2/PLACEHOLDER +0 -0
- data/spec/fixtures/find_targets/nested/Buildfile +8 -0
- data/spec/fixtures/find_targets/nested/apps/app1/Buildfile +1 -0
- data/spec/fixtures/find_targets/nested/apps/app1/apps/nested_app/PLACEHOLDER +0 -0
- data/spec/fixtures/find_targets/standard/Apps/app1/frameworks/framework1/PLACEHOLDER +0 -0
- data/spec/fixtures/find_targets/standard/Apps/app1/frameworks/framework2/PLACEHOLDER +0 -0
- data/spec/fixtures/find_targets/standard/clients/client1/PLACEHOLDER +0 -0
- data/spec/fixtures/find_targets/standard/frameworks/framework1/frameworks/framework1/PLACEHOLDER +0 -0
- data/spec/fixtures/find_targets/standard/frameworks/framework2/PLACEHOLDER +0 -0
- data/spec/fixtures/find_targets/standard/themes/theme1/PLACEHOLDER +0 -0
- data/spec/fixtures/find_targets/standard/themes/theme2/PLACEHOLDER +0 -0
- data/spec/fixtures/languages/apps/caps_long_names/English.lproj/PLACEHOLDER +0 -0
- data/spec/fixtures/languages/apps/caps_long_names/FreNCH.lproj/PLACEHOLDER +0 -0
- data/spec/fixtures/languages/apps/caps_long_names/UnknOWN.lproj/PLACEHOLDER +0 -0
- data/spec/fixtures/languages/apps/long_names/english.lproj/PLACEHOLDER +0 -0
- data/spec/fixtures/languages/apps/long_names/french.lproj/PLACEHOLDER +0 -0
- data/spec/fixtures/languages/apps/long_names/german.lproj/PLACEHOLDER +0 -0
- data/spec/fixtures/languages/apps/long_names/italian.lproj/PLACEHOLDER +0 -0
- data/spec/fixtures/languages/apps/long_names/japanese.lproj/PLACEHOLDER +0 -0
- data/spec/fixtures/languages/apps/long_names/spanish.lproj/PLACEHOLDER +0 -0
- data/spec/fixtures/languages/apps/long_names/unknown.lproj/PLACEHOLDER +0 -0
- data/spec/fixtures/languages/apps/no_names/PLACEHOLDER +0 -0
- data/spec/fixtures/languages/apps/short_names/de.lproj/PLACEHOLDER +0 -0
- data/spec/fixtures/languages/apps/short_names/en-CA.lproj/PLACEHOLDER +0 -0
- data/spec/fixtures/languages/apps/short_names/en-GB.lproj/PLACEHOLDER +0 -0
- data/spec/fixtures/languages/apps/short_names/en-US.lproj/PLACEHOLDER +0 -0
- data/spec/fixtures/languages/apps/short_names/en.lproj/PLACEHOLDER +0 -0
- data/spec/fixtures/languages/apps/short_names/es.lproj/PLACEHOLDER +0 -0
- data/spec/fixtures/languages/apps/short_names/foo.lproj/PLACEHOLDER +0 -0
- data/spec/fixtures/languages/apps/short_names/fr.lproj/PLACEHOLDER +0 -0
- data/spec/fixtures/languages/apps/short_names/it.lproj/PLACEHOLDER +0 -0
- data/spec/fixtures/languages/apps/short_names/ja.lproj/PLACEHOLDER +0 -0
- data/spec/fixtures/ordered_entries/apps/no_requires/1.js +1 -0
- data/spec/fixtures/ordered_entries/apps/no_requires/B.js +1 -0
- data/spec/fixtures/ordered_entries/apps/no_requires/a.js +1 -0
- data/spec/fixtures/ordered_entries/apps/no_requires/a/a.js +1 -0
- data/spec/fixtures/ordered_entries/apps/no_requires/a/b.js +1 -0
- data/spec/fixtures/ordered_entries/apps/no_requires/b/a.js +1 -0
- data/spec/fixtures/ordered_entries/apps/no_requires/c.js +1 -0
- data/spec/fixtures/ordered_entries/apps/no_requires/core.js +1 -0
- data/spec/fixtures/ordered_entries/apps/no_requires/english.lproj/B.css +0 -0
- data/spec/fixtures/ordered_entries/apps/no_requires/english.lproj/a.css +0 -0
- data/spec/fixtures/ordered_entries/apps/no_requires/english.lproj/a/a.css +0 -0
- data/spec/fixtures/ordered_entries/apps/no_requires/english.lproj/a/b.css +0 -0
- data/spec/fixtures/ordered_entries/apps/no_requires/english.lproj/b/a.css +0 -0
- data/spec/fixtures/ordered_entries/apps/no_requires/english.lproj/c.css +0 -0
- data/spec/fixtures/ordered_entries/apps/no_requires/lproj/strings.js +1 -0
- data/spec/fixtures/ordered_entries/apps/no_requires/utils.js +1 -0
- data/spec/fixtures/ordered_entries/apps/with_requires/a.js +2 -0
- data/spec/fixtures/ordered_entries/apps/with_requires/b.js +3 -0
- data/spec/fixtures/ordered_entries/apps/with_requires/c.js +2 -0
- data/spec/fixtures/ordered_entries/apps/with_requires/english.lproj/a.css +2 -0
- data/spec/fixtures/ordered_entries/apps/with_requires/english.lproj/b.css +2 -0
- data/spec/fixtures/ordered_entries/apps/with_requires/english.lproj/c.css +2 -0
- data/spec/fixtures/ordered_entries/apps/with_requires/english.lproj/d.js +1 -0
- data/spec/fixtures/real_world/Buildfile +12 -0
- data/spec/fixtures/real_world/apps/account/README +1 -0
- data/spec/fixtures/real_world/apps/calendar/README +1 -0
- data/spec/fixtures/real_world/apps/contacts/README_BEFORE_EDITING +1 -0
- data/spec/fixtures/real_world/apps/files/README +1 -0
- data/spec/fixtures/real_world/apps/mail/README +1 -0
- data/spec/fixtures/real_world/apps/mobile_photos/README +1 -0
- data/spec/fixtures/real_world/apps/photos/README +1 -0
- data/spec/fixtures/real_world/apps/uploader/README +1 -0
- data/spec/fixtures/real_world/frameworks/core_files/PLACEHOLDER +0 -0
- data/spec/fixtures/real_world/frameworks/core_photos/PLACEHOLDER +0 -0
- data/spec/fixtures/real_world/frameworks/shared/PLACEHOLDER +0 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/Buildfile +26 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/README +1 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/apps/docs/PLACEHOLDER +0 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/apps/test_runner/PLACEHOLDER +0 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/core.js +0 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/debug/debug-resource.html +0 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/debug/sample_debug.js +0 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/demo2.js +0 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/english.lproj/debug/sample_debug-loc.js +0 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/english.lproj/demo.css +4 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/english.lproj/demo.html +1 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/english.lproj/demo2.sass +0 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/english.lproj/file_extension_test.haml +0 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/english.lproj/file_extension_test.html.erb +1 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/english.lproj/file_extension_test.rhtml +0 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/english.lproj/fixtures/sample_fixtures-loc.js +0 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/english.lproj/has_require.css +4 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/english.lproj/no_require.css +1 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/english.lproj/no_sc_resource.rhtml +1 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/english.lproj/protocols/sample-loc.js +0 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/english.lproj/sc_resource.css +6 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/english.lproj/sc_resource.rhtml +3 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/english.lproj/strings.js +1 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/english.lproj/tests/sample-loc.js +0 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/fixtures/sample-json-fixture.json +1 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/fixtures/sample_fixtures.js +0 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/frameworks/application/PLACEHOLDER +0 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/frameworks/costello/core.js +0 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/frameworks/data_store/PLACEHOLDER +0 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/frameworks/debug/PLACEHOLDER +0 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/frameworks/desktop/PLACEHOLDER +0 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/frameworks/empty_theme/PLACEHOLDER +0 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/frameworks/foundation/PLACEHOLDER +0 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/frameworks/mobile/PLACEHOLDER +0 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/frameworks/qunit/PLACEHOLDER +0 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/frameworks/uploader/PLACEHOLDER +0 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/french.lproj/french-resource.js +0 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/french.lproj/strings.js +1 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/german.lproj/german-resource.js +0 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/german.lproj/strings.js +0 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/has_require.js +4 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/lib/index.html +1 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/no_require.js +1 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/protocols/sample.js +0 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/sc_resource.js +6 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/tests/nested/sample1.js +0 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/tests/nested/sample2.js +0 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/tests/sample.js +0 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/tests/sample.rhtml +1 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/themes/standard_theme/README +0 -0
- data/spec/fixtures/real_world/frameworks/sproutcore/views/view.js +1 -0
- data/spec/fixtures/real_world/generators/sample_custom/Buildfile +0 -0
- data/spec/fixtures/real_world/generators/sample_custom/templates/{filename}.js +1 -0
- data/spec/fixtures/recursive_project/Buildfile +8 -0
- data/spec/fixtures/recursive_project/frameworks/sproutcore/frameworks/costello/PLACEHOLDER +0 -0
- data/spec/lib/builders/combine_spec.rb +67 -0
- data/spec/lib/builders/html_spec.rb +577 -0
- data/spec/lib/builders/javascript_spec.rb +81 -0
- data/spec/lib/builders/sass_spec.rb +43 -0
- data/spec/lib/builders/spec_helper.rb +30 -0
- data/spec/lib/builders/strings_spec.rb +52 -0
- data/spec/lib/builders/stylesheet_spec.rb +63 -0
- data/spec/lib/builders/test_index_spec.rb +44 -0
- data/spec/lib/builders/test_spec.rb +135 -0
- data/spec/lib/buildfile/config_for_spec.rb +81 -0
- data/spec/lib/buildfile/define_spec.rb +59 -0
- data/spec/lib/buildfile/dup_spec.rb +65 -0
- data/spec/lib/buildfile/invoke_spec.rb +130 -0
- data/spec/lib/buildfile/load_spec.rb +49 -0
- data/spec/lib/buildfile/task/dup_spec.rb +55 -0
- data/spec/lib/buildfile/task_defined_spec.rb +17 -0
- data/spec/lib/buildfile_commands/build_task_spec.rb +19 -0
- data/spec/lib/buildfile_commands/config_spec.rb +97 -0
- data/spec/lib/buildfile_commands/import_spec.rb +17 -0
- data/spec/lib/buildfile_commands/namespace_spec.rb +18 -0
- data/spec/lib/buildfile_commands/proxies_spec.rb +38 -0
- data/spec/lib/buildfile_commands/replace_task_spec.rb +29 -0
- data/spec/lib/buildfile_commands/task_spec.rb +36 -0
- data/spec/lib/helpers/packing_optimizer/optimize_spec.rb +26 -0
- data/spec/lib/models/hash_struct/deep_clone_spec.rb +27 -0
- data/spec/lib/models/hash_struct/has_options_spec.rb +32 -0
- data/spec/lib/models/hash_struct/hash_spec.rb +64 -0
- data/spec/lib/models/hash_struct/merge_spec.rb +26 -0
- data/spec/lib/models/hash_struct/method_missing.rb +41 -0
- data/spec/lib/models/manifest/add_entry_spec.rb +36 -0
- data/spec/lib/models/manifest/add_transform_spec.rb +90 -0
- data/spec/lib/models/manifest/build_spec.rb +78 -0
- data/spec/lib/models/manifest/entry_for_spec.rb +94 -0
- data/spec/lib/models/manifest/find_entry.rb +84 -0
- data/spec/lib/models/manifest/prepare_spec.rb +62 -0
- data/spec/lib/models/manifest_entry/cacheable_url_spec.rb +31 -0
- data/spec/lib/models/manifest_entry/prepare_spec.rb +54 -0
- data/spec/lib/models/project/add_target_spec.rb +44 -0
- data/spec/lib/models/project/buildfile_spec.rb +35 -0
- data/spec/lib/models/project/find_targets_for_spec.rb +77 -0
- data/spec/lib/models/project/load_nearest_project_spec.rb +23 -0
- data/spec/lib/models/project/target_for_spec.rb +33 -0
- data/spec/lib/models/project/targets_spec.rb +62 -0
- data/spec/lib/models/target/compute_build_number_spec.rb +125 -0
- data/spec/lib/models/target/config_spec.rb +30 -0
- data/spec/lib/models/target/expand_required_targets_spec.rb +48 -0
- data/spec/lib/models/target/installed_languages_spec.rb +47 -0
- data/spec/lib/models/target/lproj_for_spec.rb +38 -0
- data/spec/lib/models/target/manifest_for_spec.rb +42 -0
- data/spec/lib/models/target/parent_target_spec.rb +21 -0
- data/spec/lib/models/target/prepare_spec.rb +53 -0
- data/spec/lib/models/target/required_targets_spec.rb +119 -0
- data/spec/lib/models/target/target_for_spec.rb +56 -0
- data/spec/lib/tools/build_number_spec.rb +28 -0
- data/spec/lib/tools/gen_spec.rb +207 -0
- data/spec/lib/tools/tools_spec.rb +78 -0
- data/spec/spec_helper.rb +138 -0
- data/sproutcore.gemspec +47 -0
- data/vendor/github_gem_lint.rb +22 -0
- data/vendor/yui-compressor/yuicompressor-2.4.2.jar +0 -0
- metadata +1084 -0
@@ -0,0 +1,493 @@
|
|
1
|
+
# ===========================================================================
|
2
|
+
# Project: Abbot - SproutCore Build Tools
|
3
|
+
# Copyright: ©2009 Apple, Inc.
|
4
|
+
# portions copyright @2006-2009 Sprout Systems, Inc.
|
5
|
+
# and contributors
|
6
|
+
# ===========================================================================
|
7
|
+
|
8
|
+
require 'extlib'
|
9
|
+
|
10
|
+
module SC
|
11
|
+
|
12
|
+
# A generator is a special kind of project that can process some input
|
13
|
+
# templates to generate some default content in a target project.
|
14
|
+
#
|
15
|
+
# === Setup Process
|
16
|
+
#
|
17
|
+
# When a generator is created, the generator's environment is setup accoding
|
18
|
+
# to the following process:
|
19
|
+
#
|
20
|
+
# 1. Process any passed :arguments hash (also saved as 'arguments')
|
21
|
+
# 2. Invoke any defined generator:prepare task to do further set'
|
22
|
+
# 3. Search the target project for a target with the target_name if set.
|
23
|
+
#
|
24
|
+
#
|
25
|
+
# === Standard Options
|
26
|
+
#
|
27
|
+
# These options are automatically added to the generator if possible. Your
|
28
|
+
# generator code should expect to work with them. The following examples
|
29
|
+
# assume you pass as an argument either "AddressBook.Contact" or
|
30
|
+
# "address_book/contact".
|
31
|
+
#
|
32
|
+
# target_name::
|
33
|
+
# the name of the target to use as the root. Defaults to the snake case
|
34
|
+
# version of the passed namepace. This can be overridden by passing the
|
35
|
+
# "target_name" option to new(). example: "address_book"
|
36
|
+
#
|
37
|
+
# target::
|
38
|
+
# If target_name is not nil and a target is found with a matching name,
|
39
|
+
# then this will be set to that target. example: Target(/address_book)
|
40
|
+
#
|
41
|
+
# build_root::
|
42
|
+
# If target is not nil, set to the source_root for the target. If no
|
43
|
+
# target, set to the project_root for the current target project. If no
|
44
|
+
# project is defined, set to the current working directory. May be
|
45
|
+
# overridden with build_root option to new(). example:
|
46
|
+
# /Users/charles/projects/my_project/apps/address_book
|
47
|
+
#
|
48
|
+
# filename::
|
49
|
+
# The filename as passed in arguments. example: "contact"
|
50
|
+
#
|
51
|
+
# namespace::
|
52
|
+
# The classified version of the target name. example: "AddressBook"
|
53
|
+
#
|
54
|
+
# class_name::
|
55
|
+
# The classified version of the filename. example: "Contact"
|
56
|
+
#
|
57
|
+
# method_name::
|
58
|
+
# If a full three-part Namespace.ClassName.methodName is passed, this
|
59
|
+
# property will be set to the method name. example: nil (no method name
|
60
|
+
# included)
|
61
|
+
#
|
62
|
+
class Generator < HashStruct
|
63
|
+
|
64
|
+
# the target project to build in or nil if no target provided
|
65
|
+
attr_reader :target_project
|
66
|
+
|
67
|
+
attr_reader :logger
|
68
|
+
|
69
|
+
################################################
|
70
|
+
## SETUP
|
71
|
+
##
|
72
|
+
|
73
|
+
# Discover all installed generators for a particular project.
|
74
|
+
def self.installed_generators_for(project)
|
75
|
+
ret = []
|
76
|
+
while project
|
77
|
+
%w(generators sc_generators gen).each do |dirname|
|
78
|
+
Dir.glob(project.project_root / dirname / '**').each do |path|
|
79
|
+
ret << File.basename(path) if File.directory?(path)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
project = project.parent_project
|
83
|
+
end
|
84
|
+
return ret.uniq.compact.sort
|
85
|
+
end
|
86
|
+
|
87
|
+
# Creates a new generator. Expects you to pass at least a generator name
|
88
|
+
# and additional options including the current target project. This will
|
89
|
+
# search for a generator source directory in the target project and any
|
90
|
+
# parent projects. The source directory must live inside a folder called
|
91
|
+
# "gen" or "generators". The source directory must contain a Buildfile
|
92
|
+
# and a templates directory to be considered a valid generator.
|
93
|
+
#
|
94
|
+
# If no valid generator can be found matching the generator name, this
|
95
|
+
# method will return null
|
96
|
+
#
|
97
|
+
def self.load(generator_name, opts={})
|
98
|
+
|
99
|
+
# get the project to search and look for the generator
|
100
|
+
target_project = project = opts[:target_project] || SC.builtin_project
|
101
|
+
path = ret = nil
|
102
|
+
|
103
|
+
# attempt to discover the the generator
|
104
|
+
while project && path.nil?
|
105
|
+
%w(generators sc_generators gen).each do |dirname|
|
106
|
+
path = File.join(project.project_root, dirname, generator_name)
|
107
|
+
if File.directory?(path)
|
108
|
+
has_buildfile = File.exists?(path / 'Buildfile')
|
109
|
+
has_templates = File.directory?(path / 'templates')
|
110
|
+
break if has_buildfile && has_templates
|
111
|
+
end
|
112
|
+
path = nil
|
113
|
+
end
|
114
|
+
project = project.parent_project
|
115
|
+
end
|
116
|
+
|
117
|
+
# Create project if possible
|
118
|
+
ret = self.new(generator_name, opts.merge(:source_root => path, :target_project => target_project)) if path
|
119
|
+
return ret
|
120
|
+
end
|
121
|
+
|
122
|
+
def initialize(generator_name, opts = {})
|
123
|
+
super()
|
124
|
+
|
125
|
+
@target_project = opts[:target_project] || opts['target_project']
|
126
|
+
@logger = opts[:logger] || opts['logger'] || SC.logger
|
127
|
+
@buildfile = nil
|
128
|
+
|
129
|
+
# delete special options
|
130
|
+
%w(target_project logger).each do |key|
|
131
|
+
opts.delete(key)
|
132
|
+
opts.delete(key.to_sym)
|
133
|
+
end
|
134
|
+
|
135
|
+
# copy any remaining options onto generator
|
136
|
+
opts.each { |key, value| self[key] = value }
|
137
|
+
self.generator_name = generator_name
|
138
|
+
|
139
|
+
end
|
140
|
+
|
141
|
+
################################################
|
142
|
+
## Buildfile
|
143
|
+
##
|
144
|
+
|
145
|
+
# The current buildfile for the generator. The buildfile is calculated by
|
146
|
+
# merging the buildfile for the generator with the default generator
|
147
|
+
# buildfile. Buildfiles should be named "Buildfile" and should be placed
|
148
|
+
# in the generator root directory.
|
149
|
+
#
|
150
|
+
# === Returns
|
151
|
+
# Buildfile instance
|
152
|
+
#
|
153
|
+
def buildfile
|
154
|
+
return @buildfile unless @buildfile.nil?
|
155
|
+
|
156
|
+
@buildfile = Buildfile.new
|
157
|
+
|
158
|
+
# First try to load the shared buildfile
|
159
|
+
path = File.join(SC.builtin_project.project_root, 'gen', 'Buildfile')
|
160
|
+
if !@buildfile.load!(path).loaded_paths.include?(path)
|
161
|
+
SC.logger.warn("Could not load shared generator buildfile at #{buildfile_path}")
|
162
|
+
end
|
163
|
+
|
164
|
+
# Then try to load the buildfile for the generator
|
165
|
+
path = File.join(source_root, 'Buildfile')
|
166
|
+
@buildfile.load!(path)
|
167
|
+
|
168
|
+
return @buildfile
|
169
|
+
end
|
170
|
+
|
171
|
+
# The config for the current generator. The config is computed by merging
|
172
|
+
# the config settings for the current buildfile and the current build
|
173
|
+
# environment.
|
174
|
+
#
|
175
|
+
# === Returns
|
176
|
+
# merged HashStruct
|
177
|
+
#
|
178
|
+
def config
|
179
|
+
return @config ||= buildfile.config_for(:templates, SC.build_mode).merge(SC.env)
|
180
|
+
end
|
181
|
+
|
182
|
+
################################################
|
183
|
+
## MAIN ENTRYPOINTS
|
184
|
+
##
|
185
|
+
|
186
|
+
# Prepares the generator state by parsing any passed arguments and then
|
187
|
+
# invokes the 'generator:prepare' task from the Buildfile, if one exists.
|
188
|
+
# Once a generator has been prepared, you can then build it.
|
189
|
+
def prepare!
|
190
|
+
return self if @is_prepared
|
191
|
+
@is_prepared = true
|
192
|
+
|
193
|
+
parse_arguments!
|
194
|
+
|
195
|
+
has_project = target_project && target_project != SC.builtin_project
|
196
|
+
if target_name && has_project && target.nil?
|
197
|
+
self.target = target_project.target_for(target_name)
|
198
|
+
end
|
199
|
+
|
200
|
+
# Attempt to build a reasonable default build_root. Usually this should
|
201
|
+
# be the target path, but if a target can't be found, use the project
|
202
|
+
# path. If a project is not found or the target project is the builtin
|
203
|
+
# project, then use the current working directory
|
204
|
+
if target
|
205
|
+
self.build_root = target.source_root
|
206
|
+
else
|
207
|
+
self.build_root = has_project ? target_project.project_root : Dir.pwd
|
208
|
+
end
|
209
|
+
|
210
|
+
# Execute prepare task - give the generator a chance to fixup defaults
|
211
|
+
buildfile.invoke 'generator:prepare', :generator => self
|
212
|
+
return self
|
213
|
+
end
|
214
|
+
|
215
|
+
# Executes the generator based on the current config options. Raises an
|
216
|
+
# exception if anything failed during the build. This will copy each
|
217
|
+
# file from the source, processing it with the rhtml template.
|
218
|
+
def build!
|
219
|
+
prepare! # if needed
|
220
|
+
buildfile.invoke 'generator:build', :generator => self
|
221
|
+
return self
|
222
|
+
end
|
223
|
+
|
224
|
+
################################################
|
225
|
+
## LOGGING
|
226
|
+
##
|
227
|
+
|
228
|
+
# Helper method. Call this when an acception occurs that is fatal due to
|
229
|
+
# a problem with the user.
|
230
|
+
def fatal!(description)
|
231
|
+
raise description
|
232
|
+
end
|
233
|
+
|
234
|
+
# Helper method. Call this when you want to log an info message. Logs to
|
235
|
+
# the standard logger.
|
236
|
+
def info(description); logger.info(description); end
|
237
|
+
|
238
|
+
# Helper method. Call this when you want to log a debug message.
|
239
|
+
def debug(description); logger.debug(description); end
|
240
|
+
|
241
|
+
# Log this when you need to issue a warning.
|
242
|
+
def warn(description); logger.warn(description); end
|
243
|
+
|
244
|
+
|
245
|
+
# Logs the pass file to the logger after first processing it with Erubis.
|
246
|
+
# This is the code helper method used to log out USAGE and README files.
|
247
|
+
#
|
248
|
+
# === Params
|
249
|
+
# src_path:: the file path for the logger
|
250
|
+
# a_logger:: optional logger to use. defaults to builtin logger
|
251
|
+
#
|
252
|
+
# === Returns
|
253
|
+
# self
|
254
|
+
#
|
255
|
+
def log_file(src_path, a_logger = nil)
|
256
|
+
a_logger = self.logger if a_logger.nil?
|
257
|
+
if !File.exists?(src_path)
|
258
|
+
warn "Could not find #{File.basename(src_path)} in generator source"
|
259
|
+
else
|
260
|
+
require 'erubis'
|
261
|
+
a_logger << Erubis::Eruby.new(File.read(src_path)).result(binding())
|
262
|
+
a_logger << "\n"
|
263
|
+
end
|
264
|
+
return self
|
265
|
+
end
|
266
|
+
|
267
|
+
# Logs the README file in the source_root if found or logs a warning.
|
268
|
+
def log_readme(a_logger=nil)
|
269
|
+
src_path = self.source_root / "README"
|
270
|
+
log_file(src_path, a_logger)
|
271
|
+
end
|
272
|
+
|
273
|
+
# Logs the USAGE file in the source_root if found or logs a warning.
|
274
|
+
def log_usage(a_logger=nil)
|
275
|
+
src_path = self.source_root / 'USAGE'
|
276
|
+
log_file(src_path, a_logger)
|
277
|
+
end
|
278
|
+
|
279
|
+
################################################
|
280
|
+
## UTILITY METHODS
|
281
|
+
##
|
282
|
+
|
283
|
+
# Returns the full namespace and class name if both are defined.
|
284
|
+
def namespace_class_name
|
285
|
+
[self.namespace, self.class_name].compact.join '.'
|
286
|
+
end
|
287
|
+
|
288
|
+
# Returns the full namespace and object name if both are defined.
|
289
|
+
def namespace_instance_name
|
290
|
+
[self.namespace, self.instance_name].compact.join '.'
|
291
|
+
end
|
292
|
+
|
293
|
+
# Verifies that the passed array of keys are defined on the object. If
|
294
|
+
# you pass an optional block, the block will be invoked for each key so
|
295
|
+
# you can validate the value as well. Otherwise, this will raise an error
|
296
|
+
# if any of the properties are nil.
|
297
|
+
def requires!(*properties)
|
298
|
+
properties.flatten.each do |key_name|
|
299
|
+
value = self.send(key_name)
|
300
|
+
is_ok = !value.nil?
|
301
|
+
is_ok = yield(key_name, value) if block_given? && is_ok
|
302
|
+
unless is_ok
|
303
|
+
fatal!("This generator requires a #{Extlib::Inflection.humanize key_name}")
|
304
|
+
end
|
305
|
+
end
|
306
|
+
return self
|
307
|
+
end
|
308
|
+
|
309
|
+
# Converts a path with optional template variables into a regular path
|
310
|
+
# by looking up said variables on the receiver. Variables in the pathname
|
311
|
+
# must appear inside of a pair of {}. (Like the Amazon Search URL spec)
|
312
|
+
def expand_path(path)
|
313
|
+
path = path.gsub(/\{(.*?)\}/) { self.send($1) || $1 }
|
314
|
+
File.expand_path path
|
315
|
+
end
|
316
|
+
|
317
|
+
# Calls your block for each file and directory in the source template
|
318
|
+
# passing the expanded source path and the expanded destination directory
|
319
|
+
#
|
320
|
+
# Expects you to include a block with the following signature:
|
321
|
+
#
|
322
|
+
# block |filename, src_path, dst_path|
|
323
|
+
#
|
324
|
+
# filename:: the filename relative to the source directory
|
325
|
+
# src_path:: the full path to the source
|
326
|
+
# dst_path:: the full destination path
|
327
|
+
#
|
328
|
+
# === Param
|
329
|
+
# source_dir:: optional source directory. Defaults to templates
|
330
|
+
# build_dir:: optional build directory. Defaults to build_root
|
331
|
+
# === Returns
|
332
|
+
# self
|
333
|
+
#
|
334
|
+
def each_template(source_dir = nil, build_dir=nil)
|
335
|
+
source_dir = self.source_root / 'templates' if source_dir.nil?
|
336
|
+
build_dir = self.build_root if build_dir.nil?
|
337
|
+
|
338
|
+
Dir.glob(source_dir / '**' / '*').each do |src_path|
|
339
|
+
filename = src_path.sub(source_dir / '', '')
|
340
|
+
dst_path = build_dir / filename
|
341
|
+
yield(filename, src_path, dst_path) if block_given?
|
342
|
+
end
|
343
|
+
return self
|
344
|
+
end
|
345
|
+
|
346
|
+
# Copies from source to destination, running the contents through ERB
|
347
|
+
# if the file appears to be a text file. The destination file must not
|
348
|
+
# exist or else a warning will be logged.
|
349
|
+
#
|
350
|
+
# === Returns
|
351
|
+
# true if copied successfully. false otherwise
|
352
|
+
#
|
353
|
+
def copy_file(src_path, dst_path)
|
354
|
+
|
355
|
+
# interpolate dst_path to include any variables
|
356
|
+
dst_path = expand_path(dst_path)
|
357
|
+
|
358
|
+
src_filename = src_path.sub(self.source_root / '', '')
|
359
|
+
dst_filename = dst_path.sub(self.build_root / '', '')
|
360
|
+
ret = true
|
361
|
+
|
362
|
+
# if the source path does not exist, just log a warning and return
|
363
|
+
if !File.exist? src_path
|
364
|
+
warn "Did not copy #{src_filename} because the source does not exist."
|
365
|
+
ret = false
|
366
|
+
|
367
|
+
# when copying a directory just make the dir if needed
|
368
|
+
elsif File.directory?(src_path)
|
369
|
+
logger << " ~ Created directory at #{dst_filename}\n" if !File.exist?(dst_path)
|
370
|
+
FileUtils.mkdir_p(dst_path) unless self.dry_run
|
371
|
+
|
372
|
+
# if destination already exists, just log warning
|
373
|
+
elsif File.exist?(dst_path) && !self.force
|
374
|
+
warn "Did not overwrite #{dst_filename} because it already exists."
|
375
|
+
ret = false
|
376
|
+
|
377
|
+
# process file through erubis and copy
|
378
|
+
else
|
379
|
+
require 'erubis'
|
380
|
+
|
381
|
+
input = File.read(src_path)
|
382
|
+
eruby = ::Erubis::Eruby.new input
|
383
|
+
output = eruby.result(binding())
|
384
|
+
|
385
|
+
unless self.dry_run
|
386
|
+
FileUtils.mkdir_p(File.dirname(dst_path))
|
387
|
+
file = File.new(dst_path, 'w')
|
388
|
+
file.write output
|
389
|
+
file.close
|
390
|
+
end
|
391
|
+
|
392
|
+
logger << " ~ Created file at #{dst_filename}\n"
|
393
|
+
end
|
394
|
+
return ret
|
395
|
+
end
|
396
|
+
|
397
|
+
# Converts a string to snake case. This method will accept any variation
|
398
|
+
# of camel case or snake case and normalize it into a format that can be
|
399
|
+
# converted back and forth to camel case.
|
400
|
+
#
|
401
|
+
# === Examples
|
402
|
+
#
|
403
|
+
# snake_case("FooBar") #=> "foo_bar"
|
404
|
+
# snake_case("HeadlineCNNNews") #=> "headline_cnn_news"
|
405
|
+
# snake_case("CNN") #=> "cnn"
|
406
|
+
# snake_case("innerHTML") #=> "inner_html"
|
407
|
+
# snake_case("Foo_Bar") #=> "foo_bar"
|
408
|
+
#
|
409
|
+
# === Params
|
410
|
+
#
|
411
|
+
# str:: the string to snake case
|
412
|
+
#
|
413
|
+
def snake_case(str='')
|
414
|
+
str = str.gsub(/([^A-Z_])([A-Z][^A-Z]?)/,'\1_\2') # most cases
|
415
|
+
str = str.gsub(/([^_])([A-Z][^A-Z])/,'\1_\2') # HeadlineCNNNews
|
416
|
+
str.downcase
|
417
|
+
end
|
418
|
+
|
419
|
+
ABBREVIATIONS = %w(html css xml)
|
420
|
+
|
421
|
+
# Converts a string to CamelCase. If you pass false for the second param
|
422
|
+
# then the first letter will be lower case rather than upper. This will
|
423
|
+
# first snake_case the passed string. This version differs from the
|
424
|
+
# standard camel_case provided by extlib by supporting a few standard
|
425
|
+
# abbreviations that are always make upper case.
|
426
|
+
#
|
427
|
+
# === Examples
|
428
|
+
#
|
429
|
+
# camel_case("foo_bar") #=> "FooBar"
|
430
|
+
# camel_case("headline_cnn_news") #=> "HeadlineCnnNews"
|
431
|
+
# camel_case("html_formatter") #=> "HTMLFormatter"
|
432
|
+
#
|
433
|
+
# === Params
|
434
|
+
#
|
435
|
+
# str:: the string to camel case
|
436
|
+
# capitalize:: capitalize first character if true (def: true)
|
437
|
+
#
|
438
|
+
def camel_case(str, capitalize=true)
|
439
|
+
str = snake_case(str) # normalize
|
440
|
+
str.gsub(capitalize ? /(\A|_+)([^_]+)/ : /(_+)([^_]+)/) do
|
441
|
+
ABBREVIATIONS.include?($2) ? $2.upcase : $2.capitalize
|
442
|
+
end
|
443
|
+
end
|
444
|
+
|
445
|
+
protected
|
446
|
+
|
447
|
+
# Standardized parsing of arguments. This will accept an argument that
|
448
|
+
# is either a class name or a path name and generate both a class name and
|
449
|
+
# a pathname from it.
|
450
|
+
#
|
451
|
+
def parse_arguments!
|
452
|
+
name = (self.arguments || [])[1]
|
453
|
+
parts = name.include?('/') ? name.split('/') : name.split('.')
|
454
|
+
|
455
|
+
# method_name would be extracted from for instance Todos.Task.methodName
|
456
|
+
# for generators that allow it
|
457
|
+
if parts[2] && self.method_name.nil?
|
458
|
+
self.method_name = camel_case(parts[2], false)
|
459
|
+
end
|
460
|
+
|
461
|
+
# target_name is first part snake_cased, unless already defined
|
462
|
+
if parts[0] && self.target_name.nil?
|
463
|
+
self.target_name = snake_case(parts[0])
|
464
|
+
end
|
465
|
+
|
466
|
+
# namespace is first part CamelCases if defined. Otherwise use
|
467
|
+
# target_name if defined
|
468
|
+
if (parts[0] || self.target_name) && self.namespace.nil?
|
469
|
+
self.namespace = camel_case(parts[0] || self.target_name)
|
470
|
+
end
|
471
|
+
|
472
|
+
# filename is second part snake_cased, unless already defined
|
473
|
+
if parts[1] && self.filename.nil?
|
474
|
+
self.filename = snake_case(parts[1])
|
475
|
+
end
|
476
|
+
|
477
|
+
# class_name is second part CamcelCased if defined. Otherwise use
|
478
|
+
# filename if defined.
|
479
|
+
if (parts[1] || self.filename) && self.class_name.nil?
|
480
|
+
self.class_name = camel_case(parts[1] || self.filename)
|
481
|
+
end
|
482
|
+
|
483
|
+
# object_name is class name with first letter lower case. Used in case
|
484
|
+
# the template wants to define an instance instead of class.
|
485
|
+
if self.class_name && self.instance_name.nil?
|
486
|
+
self.instance_name = self.class_name.sub(/^(.)/) { |x| x.downcase }
|
487
|
+
end
|
488
|
+
|
489
|
+
end
|
490
|
+
|
491
|
+
end
|
492
|
+
|
493
|
+
end
|