├── .gitignore ├── .yardopts ├── Gemfile ├── MIT-LICENSE ├── README.textile ├── VERSION ├── bin ├── sprout ├── sprout-class ├── sprout-generator ├── sprout-library ├── sprout-ruby ├── sprout-suite ├── sprout-test └── sprout-tool ├── lib ├── sprout.rb └── sprout │ ├── archive_unpacker.rb │ ├── command_line.rb │ ├── concern.rb │ ├── dir.rb │ ├── errors.rb │ ├── executable.rb │ ├── executable │ ├── base.rb │ ├── boolean.rb │ ├── collection_param.rb │ ├── file_param.rb │ ├── files.rb │ ├── number.rb │ ├── param.rb │ ├── parameter_factory.rb │ ├── path.rb │ ├── paths.rb │ ├── session.rb │ ├── string_param.rb │ ├── strings.rb │ ├── url.rb │ └── urls.rb │ ├── file_target.rb │ ├── generator.rb │ ├── generator │ ├── base.rb │ ├── command.rb │ ├── directory_manifest.rb │ ├── file_manifest.rb │ ├── manifest.rb │ └── template_manifest.rb │ ├── generators │ ├── generator │ │ ├── generator_generator.rb │ │ └── templates │ │ │ ├── generator_class.erb │ │ │ ├── generator_executable │ │ │ ├── generator_gemfile │ │ │ ├── generator_template │ │ │ ├── generator_test.erb │ │ │ └── generator_test_helper.erb │ ├── library │ │ ├── library_generator.rb │ │ └── templates │ │ │ ├── library.erb │ │ │ └── library.gemspec │ ├── ruby │ │ ├── ruby_generator.rb │ │ └── templates │ │ │ ├── ruby_base.erb │ │ │ ├── ruby_executable │ │ │ ├── ruby_gemfile │ │ │ ├── ruby_gemspec │ │ │ ├── ruby_input.erb │ │ │ ├── ruby_rakefile │ │ │ ├── ruby_test_case.erb │ │ │ └── ruby_test_helper.erb │ └── tool │ │ ├── templates │ │ ├── Gemfile │ │ ├── tool.erb │ │ └── tool.gemspec │ │ └── tool_generator.rb │ ├── library.rb │ ├── output_buffer.rb │ ├── platform.rb │ ├── process_runner.rb │ ├── progress_bar.rb │ ├── rdoc_parser.rb │ ├── remote_file_loader.rb │ ├── remote_file_target.rb │ ├── ruby_feature.rb │ ├── specification.rb │ ├── string.rb │ ├── system.rb │ ├── system │ ├── base_system.rb │ ├── java_system.rb │ ├── osx_system.rb │ ├── unix_system.rb │ ├── vista_system.rb │ ├── win_nix_system.rb │ └── win_system.rb │ ├── test_helper.rb │ └── version.rb ├── rakefile.rb ├── script ├── add_param_handler.rb ├── console ├── destroy ├── generate ├── google_analytics_footer.rb └── templates │ └── default │ └── layout │ └── html │ └── footer.erb ├── sprout.gemspec └── test ├── fixtures ├── archive_unpacker │ ├── copyable │ │ ├── some_file.exe │ │ ├── some_file.rb │ │ └── some_file.swc │ ├── tgz │ │ ├── some folder.tgz │ │ └── some_file.tgz │ └── zip │ │ ├── some folder.zip │ │ └── some_file.zip ├── examples │ ├── app_generator.rb │ ├── echo_inputs.rb │ └── rakefile.rb ├── executable │ ├── echochamber_gem │ │ ├── bin │ │ │ └── echochamber │ │ └── echo_chamber.rb │ ├── fdb.rb │ ├── flex3sdk_gem │ │ ├── fdb │ │ ├── fdb.bat │ │ ├── flex3sdk.rb │ │ ├── mxmlc │ │ └── mxmlc.bat │ ├── mxmlc.rb │ ├── params │ │ ├── input.as │ │ ├── input2.as │ │ ├── input3.as │ │ └── mxmlc │ ├── path with spaces │ │ ├── input.as │ │ ├── input2.as │ │ └── input3.as │ ├── paths │ │ ├── folder1 │ │ │ ├── file1 │ │ │ ├── file2 │ │ │ └── file3 │ │ ├── folder2 │ │ │ ├── file4 │ │ │ └── file5 │ │ └── folder3 │ │ │ └── file6 │ ├── src │ │ └── Main.as │ └── subclass │ │ ├── executable_subclass.rb │ │ └── executable_superclass.rb ├── generators │ ├── song_generator.rb │ ├── song_subclass │ │ ├── least_favorite.rb │ │ └── templates │ │ │ └── Song.txt │ ├── temp_generator.rb │ └── templates │ │ ├── Main.as │ │ ├── OtherFileTemplate │ │ ├── SomeFile │ │ ├── SomeSubclassFile │ │ ├── Song.txt │ │ ├── destroy │ │ └── generate ├── library │ └── sources │ │ ├── lib │ │ ├── a │ │ │ └── A.as │ │ └── b │ │ │ └── B.as │ │ └── src │ │ └── Source.as ├── process_runner │ ├── chmod_script.sh │ ├── dir with spaces │ │ └── chmod_script.sh │ ├── failure │ └── success ├── remote_file_loader │ └── md5 │ │ ├── echochamber-test.zip │ │ └── file_with_known_md5 ├── remote_file_target │ ├── bin │ │ ├── echochamber │ │ └── echochamber.bat │ └── echochamber-test.zip └── specification │ ├── asunit4.rb │ ├── ext │ └── AsUnit-4.1.pre.swc │ ├── flashplayer.rb │ ├── flex4sdk.rb │ ├── flexunit4.sproutspec │ ├── lib │ └── as3reflection │ │ └── Reflection.as │ └── src │ └── AsUnit.as └── unit ├── archive_unpacker_test.rb ├── boolean_param_test.rb ├── command_line_test.rb ├── executable_option_parser_test.rb ├── executable_param_test.rb ├── executable_session_test.rb ├── executable_test.rb ├── fake_executable_task.rb ├── fake_other_executable.rb ├── fake_process_runner.rb ├── file_param_test.rb ├── file_target_test.rb ├── files_param_test.rb ├── generator_generator_test.rb ├── generator_test.rb ├── library_generator_test.rb ├── library_test.rb ├── osx_system_test.rb ├── path_param_test.rb ├── paths_param_test.rb ├── platform_test.rb ├── process_runner_test.rb ├── rdoc_parser_test.rb ├── remote_file_loader_test.rb ├── remote_file_target_test.rb ├── ruby_feature_test.rb ├── ruby_generator_test.rb ├── specification_test.rb ├── sprout_test.rb ├── string_param_test.rb ├── string_test.rb ├── strings_param_test.rb ├── test_helper.rb ├── tool_generator_test.rb ├── unix_system_test.rb ├── user_test.rb ├── vista_system_test.rb ├── win_nix_system_test.rb └── win_system_test.rb /.gitignore: -------------------------------------------------------------------------------- 1 | .svn 2 | .DS_Store 3 | *.gem 4 | *.log 5 | pkg 6 | doc 7 | doc/**/**/* 8 | *_documentation.rb 9 | bundles/as3/samples/mxmlc/bin/*.swf 10 | bundles/as3/samples/mxmlc/doc 11 | bundles/as3/samples/mxmlc/bin/*.swc 12 | media 13 | .yardoc 14 | .bundle 15 | .coverage 16 | coverage 17 | tmp 18 | coverage.data 19 | Gemfile.lock 20 | -------------------------------------------------------------------------------- /.yardopts: -------------------------------------------------------------------------------- 1 | --files=README.textile 2 | --exclude=templates/* 3 | --protected 4 | --load=./script/add_param_handler.rb 5 | --title='Sprouts v.1.0.34.pre' 6 | lib/**/*.rb 7 | 8 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "http://rubygems.org" 2 | 3 | gem "bundler", ">= 0.9.19" 4 | gem "rake", ">= 0.9.2" 5 | gem "rubyzip", "~> 1.2.1" 6 | gem "archive-tar-minitar", "0.5.2" 7 | 8 | if RUBY_PLATFORM =~ /mswin/i 9 | gem "win32-open3", "0.2.5" # Win32 only 10 | else 11 | gem "open4", ">= 0.9.6" # All others 12 | end 13 | 14 | group :development do 15 | gem "yard" 16 | #gem "RedCloth" # This doesn't work Windows for some reason... 17 | gem "shoulda" 18 | gem "mocha" 19 | gem "flay" 20 | gem "flog" 21 | gem "heckle" 22 | end 23 | 24 | -------------------------------------------------------------------------------- /MIT-LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2007-2010 Pattern Park 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | -------------------------------------------------------------------------------- /README.textile: -------------------------------------------------------------------------------- 1 | h1. IMPORTANT NOTE 2 | 3 | The mainline of this repository represents the next major release of Sprouts which involves a nearly complete rewrite. 4 | 5 | To see, or edit the source code for the currently-released version (0.7.x), please check out the "release branch":http://github.com/lukebayes/project-sprouts/tree/release. 6 | 7 | h1. Project Sprouts 8 | 9 | Project Sprouts is an open-source, cross-platform project generation and configuration tool for whatever technology you use. At the time of this writing, we have support for ActionScript 2, ActionScript 3, Flex and AIR projects. 10 | 11 | Sprouts includes support for project and code templates, automated build scripts, remote managed libraries, and automatic installation of executable dependencies like runtimes, compilers and other utilities. 12 | 13 | Sprouts works on OS X, Windows XP, Windows Vista and many flavors of *nix (including Solaris thanks to lots of patience from Armaghan Chaudhary). 14 | 15 | h2. Installation 16 | 17 | # "Install Ruby":http://www.ruby-lang.org/en/downloads/ _(>= v 1.9.2)_ 18 | # "Install RubyGems":http://rubyforge.org/frs/?group_id=126 _(>= v 1.3.7)_ 19 | # Install the Sprout gem: 20 | 21 | gem install sprout 22 | 23 | To get started with Sprouts in *Flash*, follow the directions provided by the "Flash SDK":http://github.com/lukebayes/sprout-flashsdk. 24 | 25 | h2. Some Links 26 | 27 | * "Web Site":http://projectsprouts.org 28 | * "See the Documentation":http://projectsprouts.org/docs/1.1/frames.html ("No Frames":http://projectsprouts.org/docs/1.1) 29 | * "Meet the Community":http://groups.google.com/group/projectsprouts 30 | 31 | h1. MIT License 32 | 33 |
34 | Copyright (c) 2007-2011 Pattern Park
35 | 
36 | Permission is hereby granted, free of charge, to any person obtaining
37 | a copy of this software and associated documentation files (the
38 | "Software"), to deal in the Software without restriction, including
39 | without limitation the rights to use, copy, modify, merge, publish,
40 | distribute, sublicense, and/or sell copies of the Software, and to
41 | permit persons to whom the Software is furnished to do so, subject to
42 | the following conditions:
43 | 
44 | The above copyright notice and this permission notice shall be
45 | included in all copies or substantial portions of the Software.
46 | 
47 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
48 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
49 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
50 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
51 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
52 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
53 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
54 | 
55 | -------------------------------------------------------------------------------- /VERSION: -------------------------------------------------------------------------------- 1 | 1.1.18.pre 2 | -------------------------------------------------------------------------------- /bin/sprout: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require 'rubygems' 4 | require 'sprout' 5 | 6 | generator = Sprout::CommandLine.new 7 | generator.parse! ARGV 8 | generator.execute 9 | 10 | -------------------------------------------------------------------------------- /bin/sprout-class: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require 'rubygems' 4 | require 'bundler' 5 | Bundler.require 6 | 7 | generator = Sprout::Generator.create_instance :class 8 | generator.parse! ARGV 9 | generator.execute 10 | 11 | -------------------------------------------------------------------------------- /bin/sprout-generator: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require 'rubygems' 4 | require 'sprout' 5 | require 'sprout/generators/generator/generator_generator' 6 | 7 | generator = Sprout::GeneratorGenerator.new 8 | generator.parse! ARGV 9 | generator.execute 10 | 11 | -------------------------------------------------------------------------------- /bin/sprout-library: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require 'rubygems' 4 | require 'sprout' 5 | require 'sprout/generators/library/library_generator' 6 | 7 | generator = Sprout::LibraryGenerator.new 8 | generator.parse! ARGV 9 | generator.execute 10 | 11 | 12 | -------------------------------------------------------------------------------- /bin/sprout-ruby: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require 'rubygems' 4 | require 'sprout' 5 | require 'sprout/generators/ruby/ruby_generator' 6 | 7 | generator = Sprout::RubyGenerator.new 8 | generator.parse! ARGV 9 | generator.execute 10 | 11 | -------------------------------------------------------------------------------- /bin/sprout-suite: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require 'rubygems' 4 | require 'bundler' 5 | Bundler.require 6 | 7 | generator = Sprout::Generator.create_instance :suite_class 8 | generator.parse! ARGV 9 | generator.execute 10 | 11 | -------------------------------------------------------------------------------- /bin/sprout-test: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require 'rubygems' 4 | require 'bundler' 5 | Bundler.require 6 | 7 | generator = Sprout::Generator.create_instance :test_class 8 | generator.parse! ARGV 9 | generator.execute 10 | 11 | -------------------------------------------------------------------------------- /bin/sprout-tool: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require 'rubygems' 4 | require 'sprout' 5 | require 'sprout/generators/tool/tool_generator' 6 | 7 | generator = Sprout::ToolGenerator.new 8 | generator.parse! ARGV 9 | generator.execute 10 | 11 | -------------------------------------------------------------------------------- /lib/sprout.rb: -------------------------------------------------------------------------------- 1 | 2 | lib = File.expand_path File.dirname(__FILE__) 3 | $:.unshift lib unless $:.include?(lib) 4 | 5 | # External tools and std libs: 6 | require 'rake' 7 | require 'delegate' 8 | require 'logger' 9 | 10 | # Core, Process and Platform support: 11 | require 'sprout/version' 12 | require 'sprout/output_buffer' 13 | require 'sprout/progress_bar' 14 | require 'sprout/dir' 15 | require 'sprout/string' 16 | require 'sprout/errors' 17 | require 'sprout/platform' 18 | require 'sprout/process_runner' 19 | require 'sprout/system' 20 | require 'sprout/concern' 21 | require 'sprout/ruby_feature' 22 | 23 | ## 24 | # This is a fix for Issue #106 25 | # http://code.google.com/p/projectsprouts/issues/detail?id=106 26 | # Which is created because the new version (1.0.1) of RubyGems 27 | # includes open-uri, while older versions do not. 28 | # When open-uri is included twice, we get a bunch of nasty 29 | # warnings because constants are being overwritten. 30 | gem_version = Gem::Version.new(Gem::RubyGemsVersion) 31 | if(gem_version != Gem::Version.new('1.0.1')) 32 | require 'open-uri' 33 | end 34 | 35 | # File, Archive and Network support: 36 | require 'sprout/archive_unpacker' 37 | require 'sprout/file_target' 38 | require 'sprout/remote_file_loader' 39 | require 'sprout/remote_file_target' 40 | 41 | # External Packaging and distribution support: 42 | require 'sprout/rdoc_parser' 43 | require 'sprout/specification' 44 | require 'sprout/executable' 45 | require 'sprout/command_line' 46 | 47 | # Generators 48 | require 'sprout/generator' 49 | 50 | # Libraries 51 | require 'sprout/library' 52 | 53 | module Sprout 54 | 55 | class << self 56 | 57 | ## 58 | # @return [Dir] The system-specific path to the writeable cache directory 59 | # where Sprouts will look for downloaded archives. 60 | # 61 | # puts ">> Sprout Cache: #{Sprout.cache}" 62 | # 63 | def cache 64 | File.join(home, 'cache') 65 | end 66 | 67 | ## 68 | # @return [Dir] The location where the currently-running version of Sprouts 69 | # will write files and generators and their templates. 70 | # 71 | # puts ">> Sprout home: #{Sprout.home}" 72 | # 73 | def home 74 | File.join(current_system.application_home('sprouts'), Sprout::VERSION::MAJOR_MINOR) 75 | end 76 | 77 | ## 78 | # @return [Dir] The location where Sprouts will look for generators and their 79 | # templates. 80 | # 81 | # puts ">> Generator Cache: #{Sprout.generator_cache}" 82 | # 83 | def generator_cache 84 | File.join cache, 'generators' 85 | end 86 | 87 | ## 88 | # @return [Sprout::System] That is currently being used to 89 | # determine features like the cache path and how external processes 90 | # are executed. 91 | # 92 | # system = Sprout.current_system 93 | # puts ">> System: #{system.inspect}" 94 | # 95 | def current_system 96 | Sprout::System.create 97 | end 98 | 99 | def stdout=(out) 100 | @stdout = out 101 | end 102 | 103 | def stdout 104 | @stdout ||= $stdout 105 | end 106 | 107 | def stderr=(err) 108 | @stderr = err 109 | end 110 | 111 | def stderr 112 | @stderr ||= $stderr 113 | end 114 | 115 | ## 116 | # @return [File] Path to the file from the 'caller' property of 117 | # a Ruby exception. 118 | # 119 | # Note: It's a real bummer that this string is colon delimited - 120 | # The value on Windows often includes a colon... 121 | # Once again, Windows is dissed by fundamental Ruby decisions. 122 | def file_from_caller caller_string 123 | parts = caller_string.split(':') 124 | str = parts.shift 125 | while(parts.size > 0 && !File.exists?(str)) 126 | str << ":#{parts.shift}" 127 | end 128 | str 129 | end 130 | end 131 | end 132 | 133 | -------------------------------------------------------------------------------- /lib/sprout/command_line.rb: -------------------------------------------------------------------------------- 1 | module Sprout 2 | 3 | class CommandLine < Sprout::Executable::Base 4 | 5 | ## 6 | # Get the version of the Sprout gem 7 | add_param :version, Boolean, :default => false, :hidden_value => true 8 | 9 | add_param_alias :v, :version 10 | 11 | ## 12 | # @return [IO] default $stdout, Replace value in test context. 13 | attr_accessor :logger 14 | 15 | def initialize 16 | super 17 | @logger = $stdout 18 | end 19 | 20 | def parse! options 21 | if options.empty? 22 | handle_parse_error Sprout::Errors::UsageError.new("At least one parameter is required.") 23 | end 24 | super 25 | end 26 | 27 | def execute 28 | if version 29 | logger.puts "sprout #{Sprout::VERSION::STRING}" 30 | end 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /lib/sprout/concern.rb: -------------------------------------------------------------------------------- 1 | module Sprout 2 | 3 | ## 4 | # This class was copied from Rails source code and enhances 5 | # Ruby's native mixin functionality for our Sprout::RubyFeature. 6 | # 7 | # I'd like to work to get rid of this class, and the confusion 8 | # that it introduces. 9 | # 10 | module Concern 11 | 12 | ## 13 | # Callback handler when a class is extended. This 14 | # handler will set the @_dependencies array on the 15 | # concrete class that just extended a 16 | # 'Concern'. 17 | # 18 | # This callback is often triggered with: 19 | # 20 | # class Foo 21 | # extend Concern 22 | # end 23 | # 24 | def self.extended(base) 25 | base.instance_variable_set("@_dependencies", []) 26 | end 27 | 28 | ## 29 | # Apply both class and instance features found in the 30 | # base class to the new subclass. 31 | def append_features(base) 32 | if base.instance_variable_defined?("@_dependencies") 33 | base.instance_variable_get("@_dependencies") << self 34 | return false 35 | else 36 | return false if base < self 37 | @_dependencies.each { |dep| base.send(:include, dep) } 38 | super 39 | base.extend const_get("ClassMethods") if const_defined?("ClassMethods") 40 | base.send :include, const_get("InstanceMethods") if const_defined?("InstanceMethods") 41 | base.class_eval(&@_included_block) if instance_variable_defined?("@_included_block") 42 | end 43 | end 44 | 45 | ## 46 | # Handle inclusion of this module. 47 | def included(base = nil, &block) 48 | if base.nil? 49 | @_included_block = block 50 | else 51 | super 52 | end 53 | end 54 | end 55 | end 56 | 57 | =begin 58 | Copyright (c) 2004-2010 David Heinemeier Hansson 59 | 60 | Permission is hereby granted, free of charge, to any person obtaining 61 | a copy of this software and associated documentation files (the 62 | "Software"), to deal in the Software without restriction, including 63 | without limitation the rights to use, copy, modify, merge, publish, 64 | distribute, sublicense, and/or sell copies of the Software, and to 65 | permit persons to whom the Software is furnished to do so, subject to 66 | the following conditions: 67 | 68 | The above copyright notice and this permission notice shall be 69 | included in all copies or substantial portions of the Software. 70 | 71 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 72 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 73 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 74 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 75 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 76 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 77 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 78 | =end 79 | 80 | -------------------------------------------------------------------------------- /lib/sprout/dir.rb: -------------------------------------------------------------------------------- 1 | 2 | class Dir 3 | 4 | ## 5 | # Return true if the directory has no children. 6 | # 7 | # Code found here: http://www.ruby-forum.com/topic/84762 8 | def empty? 9 | Dir.glob("#{ path }/*", File::FNM_DOTMATCH) do |e| 10 | return false unless %w( . .. ).include?(File::basename(e)) 11 | end 12 | return true 13 | end 14 | 15 | ## 16 | # Return true if the provided path has no children. 17 | # 18 | # Code found here: http://www.ruby-forum.com/topic/84762 19 | def self.empty? path 20 | new(path).empty? 21 | end 22 | end 23 | 24 | -------------------------------------------------------------------------------- /lib/sprout/errors.rb: -------------------------------------------------------------------------------- 1 | 2 | module Sprout 3 | 4 | ## 5 | # A module, below which, all errors should be found. 6 | # 7 | module Errors 8 | 9 | ## 10 | # A general Sprout Error was encountered. 11 | class SproutError < StandardError; end 12 | 13 | ## 14 | # An error in the Executable was encountered. 15 | class ExecutableError < SproutError; end 16 | 17 | ## 18 | # An error in a Generator was encountered. 19 | class GeneratorError < SproutError; end 20 | 21 | ## 22 | # Unable to find the expected template for a Generator. 23 | class MissingGeneratorError < GeneratorError; end 24 | 25 | ## 26 | # Unable to find the expected template for a Generator. 27 | class MissingTemplateError < GeneratorError; end 28 | 29 | ## 30 | # There was a problem with the requested 31 | # unpack operation. 32 | class ArchiveUnpackerError < SproutError; end 33 | 34 | ## 35 | # The unpacked file was already found in the destination 36 | # directory and the ArchiveUnpacker was not asked to clobber. 37 | class DestinationExistsError < ArchiveUnpackerError; end 38 | 39 | ## 40 | # Sprouts was unable to accomplish the request. 41 | class ExecutionError < SproutError; end 42 | 43 | ## 44 | # Requested parameter or accessor already exists. 45 | class DuplicateMemberError < ExecutableError; end 46 | 47 | ## 48 | # Error when registering executables. 49 | class ExecutableRegistrationError < ExecutableError; end 50 | 51 | ## 52 | # Could not find requested ExecutableTarget 53 | class MissingExecutableError < ExecutableError; end 54 | 55 | ## 56 | # Required argument was not provided 57 | class MissingArgumentError < ExecutableError; end 58 | 59 | ## 60 | # An argument was provided that was not valid 61 | class InvalidArgumentError < ExecutableError; end 62 | 63 | ## 64 | # There was an error in ProcessRunner 65 | class ProcessRunnerError < SproutError; end 66 | 67 | ## 68 | # There was a problem requiring a requested file 69 | class LoadError < SproutError; end 70 | 71 | ## 72 | # Error on remote file download 73 | class RemoteFileLoaderError < StandardError; end 74 | 75 | ## 76 | # An unexpected input was used or method was called. 77 | class UsageError < SproutError; end 78 | 79 | ## 80 | # Can't figure out how to unpack this type of file. 81 | # Try again with a .zip, .tgz, or .tar.gz 82 | class UnknownArchiveType < SproutError; end 83 | 84 | ## 85 | # Error when a feature is not in a valid state 86 | class ValidationError < SproutError; end 87 | 88 | ## 89 | # Could not meet the requested version requirement. 90 | class VersionRequirementNotMetError < SproutError; end 91 | 92 | end 93 | end 94 | 95 | -------------------------------------------------------------------------------- /lib/sprout/executable.rb: -------------------------------------------------------------------------------- 1 | require 'sprout/executable/param' 2 | require 'sprout/executable/collection_param' 3 | require 'sprout/executable/boolean' 4 | require 'sprout/executable/number' 5 | require 'sprout/executable/string_param' 6 | require 'sprout/executable/strings' 7 | require 'sprout/executable/file_param' 8 | require 'sprout/executable/files' 9 | require 'sprout/executable/path' 10 | require 'sprout/executable/paths' 11 | require 'sprout/executable/url' 12 | require 'sprout/executable/urls' 13 | require 'sprout/executable/parameter_factory' 14 | require 'rake/clean' 15 | require 'sprout/executable/base' 16 | require 'sprout/executable/session' 17 | 18 | module Sprout 19 | 20 | ## 21 | # The Sprout::Executable module exposes a Domain Specific Language 22 | # for describing Command Line Interface (CLI) applications. 23 | # 24 | # This module can be included by any class, and depending on how that class 25 | # is used, one can either parse command line arguments into meaningful, 26 | # structured data, or delegate ruby code and configuration to an existing, 27 | # external command line process. 28 | # 29 | # Following is an example of how one could define an executable Ruby 30 | # application using this module: 31 | # 32 | # :include: ../../test/fixtures/examples/echo_inputs.rb 33 | # 34 | module Executable 35 | include RubyFeature 36 | 37 | DEFAULT_FILE_EXPRESSION = '/**/**/*' 38 | DEFAULT_PREFIX = '--' 39 | DEFAULT_SHORT_PREFIX = '-' 40 | 41 | end 42 | end 43 | 44 | -------------------------------------------------------------------------------- /lib/sprout/executable/boolean.rb: -------------------------------------------------------------------------------- 1 | module Sprout 2 | 3 | module Executable 4 | 5 | ## 6 | # Concrete Sprout::Executable::Param object for Boolean values. 7 | # 8 | # By default Boolean parameters have their value set to false and 9 | # :hidden_value set to true. This means that when they are serialized 10 | # to the shell, they will usually be represented like: 11 | # 12 | # --name 13 | # 14 | # Rather than: 15 | # 16 | # --name=true 17 | # 18 | # The following example demonstrates a simple use of the Boolean 19 | # parameter: 20 | # 21 | # class Foo 22 | # include Sprout::Executable 23 | # 24 | # add_param :visible, Boolean 25 | # end 26 | # 27 | # @see Sprout::Executable::Param 28 | # 29 | class Boolean < Param 30 | 31 | ## 32 | # By default, the Boolean parameter will only 33 | # be displayed when it's value is +true+. 34 | # 35 | # Set :show_on_false to true in order to reverse 36 | # this rule. 37 | # 38 | # add_param :visible, Boolean, :show_on_false => true 39 | # 40 | # Will make the following: 41 | # 42 | # foo :name do |t| 43 | # t.visible = false 44 | # end 45 | # 46 | # Serialize to the shell with: 47 | # 48 | # foo -visible=false 49 | # 50 | attr_accessor :show_on_false 51 | 52 | def initialize 53 | super 54 | @delimiter = ' ' 55 | @option_parser_type_name = 'BOOL' 56 | @show_on_false = false 57 | @value = false 58 | @hidden_value = true 59 | end 60 | 61 | def default_option_parser_declaration 62 | return [prefix, '[no-]', option_parser_name] if default == true 63 | super 64 | end 65 | 66 | ## 67 | # Convert string representations of falsiness 68 | # to something more Booleaney. 69 | def value=(value) 70 | value = (value == "false" || value == false) ? false : true 71 | super value 72 | end 73 | 74 | def visible? 75 | @visible ||= value 76 | if(show_on_false) 77 | return true unless value 78 | else 79 | return @visible 80 | end 81 | end 82 | 83 | end 84 | end 85 | end 86 | 87 | -------------------------------------------------------------------------------- /lib/sprout/executable/collection_param.rb: -------------------------------------------------------------------------------- 1 | module Sprout 2 | 3 | module Executable 4 | 5 | ## 6 | # Included by any parameters that represent 7 | # a collection of values, rather than a single 8 | # value. 9 | # 10 | # Should only be included by classes that 11 | # extend Sprout::Executable::Param. 12 | # 13 | # @see Sprout::Executable::Files 14 | # @see Sprout::Executable::Paths 15 | # @see Sprout::Executable::Strings 16 | # @see Sprout::Executable::Urls 17 | # 18 | module CollectionParam 19 | 20 | def initialize 21 | super 22 | @value = [] 23 | @delimiter = "+=" 24 | @option_parser_type_name = 'a,b,c' 25 | end 26 | 27 | ## 28 | # Assign the value and raise if a collection wasn't provided. 29 | # 30 | # This customization was added so that Rake tasks could help 31 | # users avoid accidentally clobbering a collection with equals assignments. 32 | # 33 | # The following example is incorrect and will raise an exception: 34 | # 35 | # foo :name do |t| 36 | # t.collection = 'A' 37 | # end 38 | # 39 | # The following example is correct and should not raise an exception: 40 | # 41 | # foo :name do |t| 42 | # t.collection << 'A' 43 | # end 44 | # 45 | # The following example is also correct and should not raise an exception: 46 | # 47 | # foo :name do |t| 48 | # t.collection = ['A'] 49 | # end 50 | # 51 | def value=(val) 52 | if(val.is_a?(String) || !val.is_a?(Enumerable)) 53 | message = "The #{name} property is an Enumerable. It looks like you may have used the assignment operator (=) with (#{value.inspect}) where the append operator (<<) was expected." 54 | raise Sprout::Errors::ExecutableError.new(message) 55 | end 56 | @value = val 57 | end 58 | 59 | ## 60 | # Hide the collection param if no items 61 | # have been added to it. 62 | def visible? 63 | (!value.nil? && value.size > 0) 64 | end 65 | 66 | ## 67 | # Returns a shell formatted string of the collection 68 | def to_shell 69 | prepare if !prepared? 70 | validate 71 | return '' if !visible? 72 | return @to_shell_proc.call(self) unless @to_shell_proc.nil? 73 | return value.join(' ') if hidden_name? 74 | return to_shell_value.collect { |val| 75 | "#{shell_name}#{delimiter}#{val}" 76 | }.join(' ') 77 | end 78 | 79 | def to_shell_value 80 | value 81 | end 82 | end 83 | end 84 | end 85 | 86 | -------------------------------------------------------------------------------- /lib/sprout/executable/file_param.rb: -------------------------------------------------------------------------------- 1 | module Sprout 2 | 3 | module Executable 4 | 5 | ## 6 | # Concrete Sprout::Executable::Param object for File values. 7 | # 8 | # This class is used in Sprout::Excecutable s with: 9 | # 10 | # add_param :some_name, File 11 | # 12 | # This parameter is truly special in that whatever values 13 | # are sent to the File parameter will be added to the underlying 14 | # Rake task as prerequisites and must exist before +Sprout::Executable.execute+ 15 | # is called - _unless_ the parameter value 16 | # matches the Sprout::Executable instance's +output+ value. 17 | # 18 | # Of course this will only be the case if there is a Rake 19 | # task wrapper for the Executable, if the Sprout::Executable 20 | # is being used to create a Ruby executable, then these File 21 | # parameters will only be validated before execution. 22 | # 23 | # @see Sprout::Executable::Param 24 | # 25 | class FileParam < Param 26 | 27 | attr_accessor :file_task_name 28 | 29 | def initialize 30 | super 31 | @option_parser_type_name = 'FILE' 32 | end 33 | 34 | def shell_value 35 | clean_path value 36 | end 37 | 38 | def prepare_prerequisites 39 | if file_task_name 40 | self.value ||= belongs_to.rake_task_name 41 | return 42 | end 43 | 44 | if prerequisite?(value) 45 | Rake::FileTask.define_task value 46 | belongs_to.prerequisites << value 47 | end 48 | end 49 | 50 | def validate 51 | super 52 | 53 | if(!file_task_name && !value.nil? && !File.exists?(value)) 54 | raise Sprout::Errors::InvalidArgumentError.new "No such file or directory - #{value}" 55 | end 56 | end 57 | 58 | private 59 | 60 | def prerequisite?(file) 61 | file && !file_is_output?(file) 62 | end 63 | end 64 | end 65 | end 66 | 67 | -------------------------------------------------------------------------------- /lib/sprout/executable/files.rb: -------------------------------------------------------------------------------- 1 | module Sprout 2 | 3 | module Executable 4 | 5 | ## 6 | # Concrete param object for collections of files 7 | # 8 | # @see Sprout::Executable::FileParam 9 | # @see Sprout::Executable::Param 10 | # @see Sprout::Executable::CollectionParam 11 | # 12 | class Files < Executable::Param 13 | include CollectionParam 14 | 15 | def to_shell_value 16 | value.collect do |path| 17 | clean_path path 18 | end 19 | end 20 | 21 | def prepare_prerequisites 22 | value.each do |f| 23 | Rake::FileTask.define_task f 24 | belongs_to.prerequisites << f 25 | end 26 | end 27 | 28 | end 29 | end 30 | end 31 | 32 | -------------------------------------------------------------------------------- /lib/sprout/executable/number.rb: -------------------------------------------------------------------------------- 1 | 2 | module Sprout 3 | 4 | module Executable 5 | 6 | ## 7 | # Concrete Sprout::Executable::Param object for numeric values. 8 | # 9 | # @see Sprout::Executable::Param 10 | # 11 | class Number < Param; end 12 | end 13 | end 14 | 15 | -------------------------------------------------------------------------------- /lib/sprout/executable/parameter_factory.rb: -------------------------------------------------------------------------------- 1 | 2 | module Sprout::Executable 3 | 4 | ## 5 | # A factory to create concrete Sprout::Executable::Param 6 | # entities from a set of known types. 7 | # 8 | # If an unrecognized Class reference is provided 9 | # we will instantiate it and ensure that it 10 | # responds to the public members of the 11 | # Executable::Param interface. 12 | # 13 | # This Factory gives you the ability to create new, 14 | # custom parameter types by simply ensuring they are 15 | # available to Ruby before your executable is 16 | # interpreted. 17 | # 18 | # Following is an example of a custom Parameter: 19 | # 20 | # class CustomParam < Sprout::Executable::Param 21 | # 22 | # def to_shell 23 | # "--foo-bar=#{value}" 24 | # end 25 | # end 26 | # 27 | # Following is an example Executable that can consume 28 | # the above parameter: 29 | # 30 | # require 'custom_param' 31 | # 32 | # class Foo 33 | # include Sprout::Executable 34 | # 35 | # add_param :name, CustomParam 36 | # 37 | # end 38 | # 39 | # That's it, there is no need to register your custom types 40 | # with the Factory, just get it into your load path and 41 | # require it. 42 | # 43 | class ParameterFactory 44 | 45 | class << self 46 | 47 | ## 48 | # This factory allows us to use classes by 49 | # reference in the Executable interface. 50 | # Since there are already Ruby primitives for 51 | # String and File and we don't want to clobber 52 | # them, we use this factory to convert those 53 | # to the appropriate types. 54 | def create type 55 | # Didn't want to clobber the stdlib references 56 | # to these two important data types... 57 | # But wanted to keep the add_param interface 58 | # clean and simple. 59 | return StringParam.new if type == String 60 | return FileParam.new if type == File 61 | type.new 62 | end 63 | end 64 | end 65 | end 66 | 67 | -------------------------------------------------------------------------------- /lib/sprout/executable/path.rb: -------------------------------------------------------------------------------- 1 | module Sprout 2 | 3 | module Executable 4 | 5 | ## 6 | # Concrete Sprout::Executable::Param object for Path values. 7 | # 8 | # Path parameters will create a FileList of prerequisites by concatenating the value with 9 | # the +file_expression+ that is set on the parameter or Sprout::Executable. 10 | # 11 | # @see Sprout::Executable::Param 12 | # 13 | class Path < Executable::Param 14 | 15 | def prepare_prerequisites 16 | if(value && !file_is_output?(value)) 17 | files = FileList[value + file_expression] 18 | files.each do |f| 19 | Rake::FileTask.define_task f 20 | belongs_to.prerequisites << f 21 | end 22 | end 23 | end 24 | end 25 | end 26 | end 27 | 28 | -------------------------------------------------------------------------------- /lib/sprout/executable/paths.rb: -------------------------------------------------------------------------------- 1 | module Sprout 2 | 3 | module Executable 4 | 5 | ## 6 | # A collection of Paths. 7 | # 8 | # @see Sprout::Executable::Path 9 | # @see Sprout::Executable::Param 10 | # @see Sprout::Executable::CollectionParam 11 | # 12 | class Paths < Files 13 | 14 | def prepare_prerequisites 15 | value.each do |path| 16 | files = FileList[path + file_expression] 17 | files.each do |f| 18 | Rake::FileTask.define_task f 19 | belongs_to.prerequisites << f 20 | end 21 | end 22 | end 23 | end 24 | end 25 | end 26 | 27 | -------------------------------------------------------------------------------- /lib/sprout/executable/string_param.rb: -------------------------------------------------------------------------------- 1 | module Sprout 2 | 3 | module Executable 4 | 5 | ## 6 | # A parameter with a String value. 7 | # 8 | # Any spaces in the value will be escaped when 9 | # returned to a shell. 10 | # 11 | # @see Sprout::Executable::Param 12 | # 13 | class StringParam < Executable::Param 14 | 15 | def shell_value 16 | value.gsub(/ /, '\ ') 17 | end 18 | 19 | end 20 | end 21 | end 22 | 23 | -------------------------------------------------------------------------------- /lib/sprout/executable/strings.rb: -------------------------------------------------------------------------------- 1 | module Sprout 2 | 3 | module Executable 4 | 5 | ## 6 | # A collection of String values. 7 | # 8 | # @see Sprout::Executable::String 9 | # @see Sprout::Executable::Param 10 | # @see Sprout::Executable::CollectionParam 11 | # 12 | class Strings < Executable::Param 13 | include CollectionParam 14 | end 15 | end 16 | end 17 | 18 | -------------------------------------------------------------------------------- /lib/sprout/executable/url.rb: -------------------------------------------------------------------------------- 1 | module Sprout 2 | 3 | module Executable 4 | 5 | ## 6 | # A parameter that represents a URL. 7 | # 8 | # @see Sprout::Executable::Param 9 | # 10 | # TODO: Should provide some custom validations for values 11 | # that should be a URL. 12 | # 13 | class Url < StringParam 14 | end 15 | end 16 | end 17 | 18 | -------------------------------------------------------------------------------- /lib/sprout/executable/urls.rb: -------------------------------------------------------------------------------- 1 | module Sprout 2 | 3 | module Executable 4 | 5 | ## 6 | # Collection of URL values. 7 | # 8 | # @see Sprout::Executable::Url 9 | # @see Sprout::Executable::Param 10 | # @see Sprout::Executable::CollectionParam 11 | # 12 | class Urls < Strings 13 | end 14 | end 15 | end 16 | 17 | -------------------------------------------------------------------------------- /lib/sprout/file_target.rb: -------------------------------------------------------------------------------- 1 | 2 | module Sprout 3 | 4 | # This is a class that is generally used by the Sprout::Specification::add_file_target method. 5 | # 6 | # File targets are files that are embedded into (or referred to by) a RubyGem in such a way 7 | # that Sprouts can use them as a library or executable. 8 | # 9 | # A given FileTarget may be configured to work on a specific platform, or it may be 10 | # universal. 11 | # 12 | class FileTarget 13 | 14 | attr_accessor :load_path 15 | attr_accessor :pkg_name 16 | attr_accessor :pkg_version 17 | attr_accessor :platform 18 | 19 | attr_reader :executables 20 | attr_reader :libraries 21 | 22 | def initialize 23 | @executables = [] 24 | @libraries = [] 25 | @load_path = '.' 26 | @platform = :universal 27 | yield self if block_given? 28 | end 29 | 30 | ## 31 | # This is a template method that will be called 32 | # so that RemoteFileTarget subclasses and load 33 | # the appropriate files at the appropriate time. 34 | # Admittedly kind of smelly, other ideas welcome... 35 | def resolve 36 | end 37 | 38 | ## 39 | # Add a library to the package. 40 | # 41 | # @return [Sprout::Library] The newly created library that was added. 42 | # @param name [Symbol] Name that will be used to retrieve this library on +load+. 43 | # @param path [File, Path, Array] File or files that will be associated with 44 | # this library and copied into the target project library folder when loaded. 45 | # (If the path is a directory, all files forward of that directory will be included.) 46 | def add_library name, path 47 | if path.is_a?(Array) 48 | path = path.collect { |p| expand_local_path(p) } 49 | else 50 | path = expand_local_path path 51 | end 52 | library = Sprout::Library.new( :name => name, :path => path, :file_target => self ) 53 | libraries << library 54 | library 55 | end 56 | 57 | ## 58 | # Add an executable to the RubyGem package. 59 | # 60 | # @param name [Symbol] that will be used to retrieve this executable later. 61 | # @param path [File] relative path to the executable that will be associated 62 | # with this name. 63 | # 64 | def add_executable name, path 65 | path = expand_local_path path 66 | executables << OpenStruct.new( :name => name, :path => path, :file_target => self ) 67 | end 68 | 69 | def to_s 70 | "[FileTarget pkg_name=#{pkg_name} pkg_version=#{pkg_version} platform=#{platform}]" 71 | end 72 | 73 | def validate 74 | raise Sprout::Errors::UsageError.new "FileTarget.pkg_name is required" if pkg_name.nil? 75 | raise Sprout::Errors::UsageError.new "FileTarget.pkg_version is required" if pkg_version.nil? 76 | end 77 | 78 | ## 79 | # This is a template method that is overridden 80 | # by RemoteFileTarget. 81 | def expand_local_path path 82 | File.join load_path, path 83 | end 84 | 85 | end 86 | end 87 | 88 | -------------------------------------------------------------------------------- /lib/sprout/generator/base.rb: -------------------------------------------------------------------------------- 1 | module Sprout 2 | module Generator 3 | 4 | class Base < Sprout::Executable::Base 5 | 6 | def self.inherited base 7 | # NOTE: We can NOT instantiate the class here, 8 | # because only it's first line has been interpreted, if we 9 | # instantiate here, none of the code declared in the class body will 10 | # be associated with this instance. 11 | # 12 | # Go ahead and register the class and update instances later... 13 | Sprout::Generator.register base, template_from_caller(caller.first) 14 | end 15 | 16 | ## 17 | # The directory where files will be created. 18 | add_param :path, Path, { :default => Dir.pwd } 19 | 20 | ## 21 | # Insteast of creating, destroy the files. 22 | add_param :destroy, Boolean 23 | 24 | ## 25 | # Force the creation of files without prompting. 26 | add_param :force, Boolean 27 | 28 | ## 29 | # Run the generator in Quiet mode - do not write 30 | # status to standard output. 31 | add_param :quiet, Boolean 32 | 33 | ## 34 | # Display the paths this generator will use to look 35 | # for templates on this system and exit. 36 | add_param :show_template_paths, Boolean 37 | 38 | ## 39 | # A collection of paths to look in for named templates. 40 | add_param :templates, Paths 41 | 42 | ## 43 | # The primary input for the application or component. 44 | add_param :input, String, { :hidden_name => true, :required => true } 45 | 46 | ## 47 | # Set the default name for generators. 48 | set :name, :application 49 | 50 | ## 51 | # The symbol name for which this generator is most 52 | # appropriate. 53 | # 54 | # This value defaults to :application so, if you're working on an 55 | # application generator, you can leave it as the default. 56 | # 57 | # For all other generator types, you'll want to select the most 58 | # general project type that this generator may be useful in. 59 | # 60 | # Following are some example values: 61 | # 62 | # :as3, :flex3, :flex4, :air2 63 | # 64 | # or core libraries: 65 | # 66 | # :asunit4, :flexunit4 67 | # 68 | # or even other libraries: 69 | # 70 | # :puremvc, :robotlegs, :swizz 71 | # 72 | attr_accessor :name 73 | attr_accessor :logger 74 | attr_accessor :pkg_name 75 | attr_accessor :pkg_version 76 | 77 | ## 78 | # Record the actions and trigger them 79 | def execute 80 | return do_show_template_paths if show_template_paths 81 | return prepare_command.unexecute if destroy 82 | prepare_command.execute 83 | end 84 | 85 | def validate 86 | return true if show_template_paths 87 | super 88 | end 89 | 90 | ## 91 | # Rollback the generator 92 | def unexecute 93 | prepare_command.unexecute 94 | end 95 | 96 | def say message 97 | logger.puts message.gsub("#{path}", '.') unless quiet 98 | end 99 | 100 | ## 101 | # TODO: Add support for arbitrary templating languages. 102 | # For now, just support ERB... 103 | # 104 | # TODO: This is also a possible spot where those of you that don't want 105 | # to snuggle might put pretty-print code or some such 106 | # modifiers... 107 | def resolve_template content 108 | require 'erb' 109 | ERB.new(content, nil, '>').result(binding) 110 | end 111 | 112 | ## 113 | # Returns a collection of templates that were provided on the 114 | # command line, followed by templates that are created by a 115 | # concrete generator, followed by the 116 | # Sprout::Generator.search_paths + 'templates' folders. 117 | # 118 | def template_paths 119 | create_template_paths 120 | end 121 | 122 | def create_template_paths 123 | paths = templates.dup 124 | paths = paths.concat Sprout::Generator.search_paths 125 | paths << Sprout::Generator::template_folder_for(self) 126 | end 127 | 128 | protected 129 | 130 | def do_show_template_paths 131 | @logger ||= $stdout 132 | message = "The following paths will be checked for templates:\n" 133 | 134 | paths = ["--templates+=[value]"] 135 | paths = paths.concat Sprout::Generator.create_search_paths 136 | paths << "ENV['SPROUT_GENERATORS']" 137 | paths << Sprout::Generator::template_folder_for(self) 138 | 139 | message << " * " 140 | message << paths.join("\n * ") 141 | say message 142 | message 143 | end 144 | 145 | def default_search_paths 146 | Sprout::Generator.search_paths.collect { |path| File.join(path, 'templates') } 147 | end 148 | 149 | def prepare_command 150 | @logger ||= $stdout 151 | @command = Command.new self 152 | @command.logger = logger 153 | manifest 154 | @command 155 | end 156 | 157 | def directory name, &block 158 | @command.directory name, &block 159 | end 160 | 161 | def file name, template=nil 162 | @command.file name, template 163 | end 164 | 165 | def template name, template=nil 166 | @command.template name, template 167 | end 168 | 169 | def generator name, options={} 170 | @command.generator name, to_hash.merge(options) 171 | end 172 | 173 | private 174 | 175 | def self.template_from_caller caller_string 176 | file = Sprout.file_from_caller caller_string 177 | File.join(File.dirname(file), 'templates') 178 | end 179 | 180 | end 181 | end 182 | end 183 | 184 | -------------------------------------------------------------------------------- /lib/sprout/generator/command.rb: -------------------------------------------------------------------------------- 1 | 2 | module Sprout::Generator 3 | class Command 4 | attr_accessor :logger 5 | attr_accessor :working_dir 6 | 7 | def initialize generator 8 | @generator = generator 9 | @working_dir = DirectoryManifest.new 10 | @working_dir.generator = generator 11 | @working_dir.path = generator.path 12 | end 13 | 14 | def directory path, &block 15 | raise Sprout::Errors::GeneratorError.new "Cannot create directory with nil path" if path.nil? 16 | manifest = DirectoryManifest.new 17 | manifest.generator = @generator 18 | manifest.path = File.join(@working_dir.path, path) 19 | @working_dir.children << manifest 20 | parent = @working_dir 21 | @working_dir = manifest 22 | yield if block_given? 23 | @working_dir = parent 24 | end 25 | 26 | def template path, template=nil 27 | raise Sprout::Errors::GeneratorError.new "Cannot create file with nil path" if path.nil? 28 | manifest = TemplateManifest.new 29 | manifest.generator = @generator 30 | manifest.path = File.join( working_dir.path, path ) 31 | manifest.template = template 32 | manifest.templates = @generator.template_paths 33 | working_dir.children << manifest 34 | end 35 | 36 | def file path, template=nil 37 | raise Sprout::Errors::GeneratorError.new "Cannot create file with nil path" if path.nil? 38 | manifest = FileManifest.new 39 | manifest.generator = @generator 40 | manifest.path = File.join( working_dir.path, path ) 41 | manifest.template = template 42 | manifest.templates = @generator.template_paths 43 | working_dir.children << manifest 44 | end 45 | 46 | def generator name, options={} 47 | raise Sprout::Errors::GeneratorError.new "Cannot call another generator with nil name" if name.nil? 48 | instance = Sprout::Generator.create_instance name, options 49 | instance.logger = logger 50 | instance.path = working_dir.path 51 | instance.from_hash options 52 | working_dir.generators << instance 53 | end 54 | 55 | def execute 56 | begin 57 | working_dir.create 58 | rescue StandardError => e 59 | @generator.say "[#{e.class}] #{e.message}" 60 | working_dir.children.each do |child| 61 | child.destroy 62 | end 63 | raise e 64 | end 65 | end 66 | 67 | def unexecute 68 | working_dir.destroy 69 | end 70 | end 71 | end 72 | 73 | -------------------------------------------------------------------------------- /lib/sprout/generator/directory_manifest.rb: -------------------------------------------------------------------------------- 1 | module Sprout::Generator 2 | class DirectoryManifest < Manifest 3 | attr_reader :children 4 | attr_reader :generators 5 | 6 | def initialize 7 | super 8 | @children = [] 9 | @generators = [] 10 | end 11 | 12 | def create 13 | if !File.directory?(path) 14 | FileUtils.mkdir_p path 15 | say "Created directory: #{path}" 16 | else 17 | say "Skipped directory: #{path}" unless(path == Dir.pwd) 18 | end 19 | create_children 20 | execute_generators 21 | end 22 | 23 | def destroy 24 | unexecute_generators 25 | success = destroy_children 26 | 27 | if success && can_remove? 28 | FileUtils.rmdir path 29 | say "Removed directory: #{path}" 30 | true 31 | else 32 | say "Skipped remove directory: #{path}" 33 | false 34 | end 35 | end 36 | 37 | private 38 | 39 | def can_remove? 40 | File.directory?(path) && Dir.empty?(path) 41 | end 42 | 43 | def create_children 44 | created = children.select { |child| child.create } 45 | return (created.size == children.size) 46 | end 47 | 48 | def destroy_children 49 | destroyed = children.reverse.select { |child| child.destroy } 50 | return (destroyed.size == children.size) 51 | end 52 | 53 | def execute_generators 54 | generators.each do |generator| 55 | generator.execute 56 | end 57 | end 58 | 59 | def unexecute_generators 60 | generators.each do |generator| 61 | generator.unexecute 62 | end 63 | end 64 | 65 | end 66 | end 67 | -------------------------------------------------------------------------------- /lib/sprout/generator/file_manifest.rb: -------------------------------------------------------------------------------- 1 | module Sprout::Generator 2 | 3 | class FileManifest < Manifest 4 | attr_accessor :template 5 | attr_accessor :templates 6 | 7 | def create 8 | content = resolve_template 9 | 10 | if File.exists?(path) 11 | if generator.force 12 | write_file path, content 13 | say "Replaced file: #{path}" 14 | true 15 | else 16 | say "Skipped file: #{path}" 17 | false 18 | end 19 | else 20 | write_file path, content 21 | say "Created file: #{path}" 22 | true 23 | end 24 | end 25 | 26 | def destroy 27 | if !File.exists?(path) 28 | say "Skipped remove missing file: #{path}" 29 | return true 30 | end 31 | expected_content = resolve_template 32 | actual_content = File.read path 33 | if generator.force || actual_content == expected_content 34 | FileUtils.rm path 35 | say "Removed file: #{path}" 36 | true 37 | else 38 | say "Skipped remove file: #{path}" 39 | false 40 | end 41 | end 42 | 43 | protected 44 | 45 | def write_file path, content 46 | File.open path, 'w+' do |file| 47 | file.write content 48 | end 49 | end 50 | 51 | def resolve_template 52 | read_source 53 | end 54 | 55 | def read_source 56 | templates.each do |template_path| 57 | path = File.join template_path, source_name 58 | if File.exists?(path) 59 | return File.read path 60 | end 61 | end 62 | raise Sprout::Errors::MissingTemplateError.new "Could not find template (#{source_name}) in any of the following paths:\n\n (#{templates.inspect})\n\n" 63 | end 64 | 65 | def source_name 66 | template || File.basename(path) 67 | end 68 | end 69 | end 70 | 71 | -------------------------------------------------------------------------------- /lib/sprout/generator/manifest.rb: -------------------------------------------------------------------------------- 1 | 2 | module Sprout::Generator 3 | 4 | class Manifest 5 | attr_accessor :generator 6 | attr_accessor :path 7 | attr_accessor :parent 8 | 9 | def say message 10 | generator.say message 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/sprout/generator/template_manifest.rb: -------------------------------------------------------------------------------- 1 | module Sprout::Generator 2 | 3 | class TemplateManifest < FileManifest 4 | 5 | protected 6 | 7 | def resolve_template 8 | generator.resolve_template read_source 9 | end 10 | end 11 | end 12 | 13 | -------------------------------------------------------------------------------- /lib/sprout/generators/generator/generator_generator.rb: -------------------------------------------------------------------------------- 1 | 2 | module Sprout 3 | class GeneratorGenerator < Generator::Base 4 | 5 | ## 6 | # The default module that classes will be added 7 | # to. 8 | add_param :namespace, String, { :default => ''} 9 | 10 | ## 11 | # The name of the folder where external libraries 12 | # will be installed. 13 | add_param :lib, String, { :default => 'lib' } 14 | 15 | ## 16 | # The name of the folder where custom generators and templates 17 | # will be found. 18 | add_param :generators, String, { :default => 'generators' } 19 | 20 | ## 21 | # The name of the folder where tests should be generated. 22 | add_param :test, String, { :default => 'test' } 23 | 24 | ## 25 | # The name of the child folder of the test folder where 26 | # unit tests should be generated. 27 | add_param :unit, String, { :default => 'unit' } 28 | 29 | ## 30 | # The name of the child folder of the test folder where 31 | # fixtures should be generated. 32 | add_param :fixtures, String, { :default => 'fixtures' } 33 | 34 | ## 35 | # The name of the folder where external source code 36 | # should be placed. 37 | add_param :vendor, String, { :default => 'vendor' } 38 | 39 | ## 40 | # The name of the folder where binary or executable 41 | # artifacts should be created by compiler tasks. 42 | add_param :bin, String, { :default => 'bin' } 43 | 44 | ## 45 | # The default (primary) file extension for generated source 46 | # files. This should hint at the project type. 47 | add_param :extension, String, { :default => '.as' } 48 | 49 | def manifest 50 | massage_input 51 | 52 | directory bin do 53 | template "#{input.dash_case}", "generator_executable" 54 | end 55 | 56 | directory lib do 57 | #We need to add a folder with the same name as the module to be used in order to faux namespace our generators to avoid collisions from super classes 58 | directory namespace do 59 | directory generators do 60 | template "#{input.snake_case}_generator.rb", "generator_class.erb" 61 | directory "templates" do 62 | template "#{input.camel_case}#{extension}", "generator_template" 63 | end 64 | end 65 | end 66 | end 67 | 68 | directory test do 69 | directory unit do 70 | template "#{input.snake_case}_generator_test.rb", "generator_test.erb" 71 | template "test_helper.rb", "generator_test_helper.erb" 72 | end 73 | directory fixtures do 74 | directory "generators" 75 | end 76 | end 77 | 78 | if !File.exists? 'Gemfile' 79 | template 'Gemfile', 'generator_gemfile' 80 | else 81 | say "[INFO] It seems you already have a Gemfile in this project, please be sure it has the following content:" 82 | say '' 83 | say ' gem "sprout", ">= #{Sprout::VERSION::STRING}"' 84 | say '' 85 | say ' group :development do' 86 | say ' gem "shoulda"' 87 | say ' gem "mocha"' 88 | say ' end' 89 | say '' 90 | end 91 | end 92 | 93 | protected 94 | 95 | def massage_input 96 | self.input = input.gsub(/_generator$/, '') 97 | self.input = input.gsub(/Generator$/, '') 98 | end 99 | 100 | end 101 | end 102 | -------------------------------------------------------------------------------- /lib/sprout/generators/generator/templates/generator_class.erb: -------------------------------------------------------------------------------- 1 | 2 | module Sprout 3 | ## 4 | # This is where you describe your new Generator. 5 | class <%= input.camel_case %>Generator < Generator::Base 6 | 7 | ## 8 | # This is how you add a parameter to your generator 9 | # 10 | # # @return [String] Say fwee! 11 | # add_param :fwee, String, { :default => "fwee" } 12 | # 13 | def manifest 14 | directory input.snake_case do 15 | template "#{input.camel_case}<%= extension %>" 16 | end 17 | end 18 | 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /lib/sprout/generators/generator/templates/generator_executable: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'sprout' 3 | require 'generators/<%= input.snake_case %>_generator' 4 | 5 | generator = <%= input.camel_case %>Generator.new 6 | generator.parse! ARGV 7 | generator.execute 8 | -------------------------------------------------------------------------------- /lib/sprout/generators/generator/templates/generator_gemfile: -------------------------------------------------------------------------------- 1 | source "http://rubygems.org" 2 | 3 | gem "sprout", ">= <%= Sprout::VERSION::STRING %>" 4 | 5 | group :development do 6 | gem "shoulda" 7 | gem "mocha" 8 | end 9 | 10 | -------------------------------------------------------------------------------- /lib/sprout/generators/generator/templates/generator_template: -------------------------------------------------------------------------------- 1 | This is your generator template -------------------------------------------------------------------------------- /lib/sprout/generators/generator/templates/generator_test.erb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | require 'generators/<%= input.snake_case %>_generator' 4 | 5 | class <%= input.camel_case %>GeneratorTest < Test::Unit::TestCase 6 | include Sprout::TestHelper 7 | 8 | context "A new <%= input.camel_case %> generator" do 9 | 10 | setup do 11 | # Create a temporary directory the generator can 12 | # add files to: 13 | @temp = File.join(fixtures, 'generators', 'tmp') 14 | FileUtils.mkdir_p @temp 15 | 16 | # Instantiate the generator: 17 | @generator = Sprout::<%= input.camel_case %>Generator.new 18 | 19 | # Tell the generator to use the new temp path: 20 | @generator.path = @temp 21 | 22 | # Hide generator output from terminal: 23 | # (uncomment to see output) 24 | @generator.logger = StringIO.new 25 | end 26 | 27 | teardown do 28 | # Remove the temp directory after each test method: 29 | remove_file @temp 30 | end 31 | 32 | # Run all test methods with: 33 | # 34 | # ruby -I test/unit test/unit/<%= input.snake_case %>_generator_test.rb 35 | # 36 | # Run just this test method with: 37 | # 38 | # ruby -I test/unit test/unit/<%= input.snake_case %>_generator_test.rb -n '/generate a new/' 39 | # 40 | should "generate a new <%= input.camel_case %>" do 41 | # provide example input: 42 | @generator.input = "<%= input.camel_case %>" 43 | @generator.execute 44 | 45 | input_dir = File.join @temp, "<%= input.snake_case %>" 46 | assert_directory input_dir 47 | 48 | input_file = File.join input_dir, "<%= input.camel_case %><%= extension %>" 49 | # Custom Sprout::TestHelper assertion, optional block 50 | # yields the file content as a String 51 | assert_file input_file do |content| 52 | # Custom Sprout::TestHelper assertion, update the Regex 53 | # with your expectation. 54 | assert_matches /Your content to assert here/, content 55 | end 56 | end 57 | 58 | end 59 | end 60 | -------------------------------------------------------------------------------- /lib/sprout/generators/generator/templates/generator_test_helper.erb: -------------------------------------------------------------------------------- 1 | require "rubygems" 2 | require "bundler" 3 | Bundler.require :default, :development 4 | 5 | # These require statments *must* be in this order: 6 | # http://bit.ly/bCC0Ew 7 | # Somewhat surprised they're not being required by Bundler... 8 | require 'shoulda' 9 | require 'mocha' 10 | 11 | lib = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'lib')) 12 | $:.unshift lib unless $:.include? lib 13 | 14 | test = File.expand_path(File.join(File.dirname(__FILE__), '..')) 15 | $:.unshift test unless $:.include? test 16 | 17 | require 'sprout' 18 | require 'sprout/test_helper' 19 | 20 | -------------------------------------------------------------------------------- /lib/sprout/generators/library/library_generator.rb: -------------------------------------------------------------------------------- 1 | 2 | module Sprout 3 | class LibraryGenerator < Generator::Base 4 | #TODO: The library generator needs to: 5 | #Create the outer folder with the input passed in as the library name if no outer folder exists 6 | #Create a lib dir and put the file generated from the library.rb template in it 7 | #Create a vendor folder 8 | 9 | ## 10 | # Set the version string to use. 11 | add_param :version, String, { :default => '0.0.1' } 12 | 13 | def manifest 14 | template "#{input.snake_case}.gemspec", 'library.gemspec' 15 | template "#{input.snake_case}.rb", 'library.erb' 16 | end 17 | 18 | end 19 | end 20 | 21 | -------------------------------------------------------------------------------- /lib/sprout/generators/library/templates/library.erb: -------------------------------------------------------------------------------- 1 | require 'sprout' 2 | 3 | module <%= input.camel_case %> 4 | NAME = '<%= input.snake_case %>' 5 | VERSION = '<%= version %>' 6 | end 7 | 8 | Sprout::Specification.new do |s| 9 | s.name = <%= input.camel_case %>::NAME 10 | s.version = <%= input.camel_case %>::VERSION 11 | s.add_file_target do |f| 12 | f.add_library :swc, 'bin/<%= input.camel_case %>-<%= version %>.swc' 13 | f.add_library :src, 'src' 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/sprout/generators/library/templates/library.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | 3 | require File.dirname(__FILE__) + '/<%= input.snake_case %>' 4 | require 'rake' 5 | 6 | Gem::Specification.new do |s| 7 | s.name = <%= input.camel_case %>::NAME 8 | s.version = <%= input.camel_case %>::VERSION 9 | s.author = "Your Name" 10 | s.email = ["projectsprouts@googlegroups.com"] 11 | s.homepage = "http://projectsprouts.org" 12 | s.summary = "A Library build with Project Sprouts" 13 | s.description = "Longer description here" 14 | s.rubyforge_project = "sprout" 15 | s.required_rubygems_version = ">= 1.3.6" 16 | s.require_path = "." 17 | s.files = FileList["**/*"].exclude /docs|.DS_Store|generated|.svn|.git/ 18 | end 19 | 20 | -------------------------------------------------------------------------------- /lib/sprout/generators/ruby/ruby_generator.rb: -------------------------------------------------------------------------------- 1 | 2 | module Sprout 3 | class RubyGenerator < Sprout::Generator::Base 4 | 5 | ## 6 | # The 3-part version for the new Ruby application. 7 | add_param :version, String, { :default => '0.0.0.pre' } 8 | 9 | ## 10 | # The name of the 'lib' directory - where your Ruby 11 | # files will be located. 12 | add_param :lib, String, { :default => 'lib' } 13 | 14 | ## 15 | # The name of the 'test' directory - where all tests 16 | # and fixtures will be located. 17 | add_param :test, String, { :default => 'test' } 18 | 19 | ## 20 | # The name of the 'unit' directory - where unit tests 21 | # will be located. 22 | add_param :unit, String, { :default => 'unit' } 23 | 24 | ## 25 | # The name of the 'fixtures' directory - where test 26 | # fixtures will be located. 27 | add_param :fixtures, String, { :default => 'fixtures' } 28 | 29 | ## 30 | # The name of the bin directory - where executables 31 | # will be located. 32 | add_param :bin, String, { :default => 'bin' } 33 | 34 | def manifest 35 | snake = input.snake_case 36 | 37 | directory snake do 38 | template 'Gemfile', 'ruby_gemfile' 39 | template 'Rakefile', 'ruby_rakefile' 40 | template "#{input.snake_case}.gemspec", 'ruby_gemspec' 41 | 42 | directory lib do 43 | template "#{snake}.rb", 'ruby_input.erb' 44 | directory snake do 45 | template 'base.rb', 'ruby_base.erb' 46 | end 47 | end 48 | 49 | directory test do 50 | directory fixtures 51 | directory unit do 52 | template "#{input.snake_case}_test.rb", 'ruby_test_case.erb' 53 | template 'test_helper.rb', 'ruby_test_helper.erb' 54 | end 55 | end 56 | 57 | directory bin do 58 | template input.dash_case, 'ruby_executable' 59 | end 60 | end 61 | end 62 | end 63 | end 64 | -------------------------------------------------------------------------------- /lib/sprout/generators/ruby/templates/ruby_base.erb: -------------------------------------------------------------------------------- 1 | require 'sprout' 2 | 3 | module <%= input.camel_case %> 4 | 5 | class Base < Sprout::Executable::Base 6 | 7 | end 8 | end 9 | 10 | -------------------------------------------------------------------------------- /lib/sprout/generators/ruby/templates/ruby_executable: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require '<%= input.snake_case %>' 3 | 4 | <%= input.snake_case %> = <%= input.camel_case %>::Base.new 5 | <%= input.snake_case %>.parse! ARGV 6 | <%= input.snake_case %>.execute 7 | 8 | -------------------------------------------------------------------------------- /lib/sprout/generators/ruby/templates/ruby_gemfile: -------------------------------------------------------------------------------- 1 | source :rubygems 2 | 3 | gem 'sprout', '>= <%= Sprout::VERSION::STRING %>' 4 | 5 | group :development do 6 | gem 'rake' 7 | gem 'shoulda' 8 | gem 'mocha' 9 | end 10 | 11 | -------------------------------------------------------------------------------- /lib/sprout/generators/ruby/templates/ruby_gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | lib = File.expand_path File.join(File.dirname(__FILE__), 'lib') 3 | $:.unshift lib unless $:.include?(lib) 4 | 5 | require 'bundler' 6 | require 'rake' 7 | require '<%= input.snake_case %>' 8 | 9 | Gem::Specification.new do |s| 10 | s.name = <%= input.camel_case %>::NAME 11 | s.version = <%= input.camel_case %>::VERSION 12 | s.platform = Gem::Platform::RUBY 13 | s.authors = ["Your Name Here"] 14 | s.email = "projectsprouts@googlegroups.com" 15 | s.homepage = "http://projectsprouts.org" 16 | s.summary = "Software development - evolved" 17 | s.description = "Project Sprouts gives you access to beautiful generators and easily customized templates, automated build scripts, distributed libraries and simple system configuration" 18 | s.required_rubygems_version = ">= 1.3.6" 19 | s.rubyforge_project = "sprout" 20 | s.require_path = ['lib'] 21 | s.files = FileList['**/**/*'].exclude /.git|.svn|.DS_Store/ 22 | s.executables = ['<%= input.dash_case %>'] 23 | s.add_bundler_dependencies 24 | end 25 | 26 | -------------------------------------------------------------------------------- /lib/sprout/generators/ruby/templates/ruby_input.erb: -------------------------------------------------------------------------------- 1 | require '<%= input.snake_case %>/base' 2 | 3 | module <%= input.camel_case %> 4 | NAME = '<%= input.snake_case %>' 5 | VERSION = '<%= version %>' 6 | end 7 | 8 | -------------------------------------------------------------------------------- /lib/sprout/generators/ruby/templates/ruby_rakefile: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'bundler' 3 | Bundler.require 4 | 5 | require 'rake/testtask' 6 | 7 | # Hack this dir onto path for Ruby 1.9.2 8 | # support: 9 | test_package = File.expand_path(File.join(File.dirname(__FILE__), 'test')) 10 | $: << test_package unless $:.include? test_package 11 | 12 | namespace :test do 13 | Rake::TestTask.new(:units) do |t| 14 | t.libs << "test/unit" 15 | t.test_files = FileList["test/unit/*_test.rb"] 16 | t.verbose = true 17 | end 18 | end 19 | 20 | task :test => 'test:units' 21 | 22 | -------------------------------------------------------------------------------- /lib/sprout/generators/ruby/templates/ruby_test_case.erb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class <%= input.camel_case %>Test < Test::Unit::TestCase 4 | include Sprout::TestHelper 5 | 6 | context "A <%= input.camel_case %>" do 7 | 8 | setup do 9 | @fixture = File.join fixtures, '<%= input.snake_case %>', 'tmp' 10 | FileUtils.makedirs @fixture 11 | end 12 | 13 | teardown do 14 | remove_file @fixture 15 | end 16 | 17 | should "do something" do 18 | assert_file @fixture 19 | assert false, 'Force test failure' 20 | end 21 | end 22 | end 23 | 24 | -------------------------------------------------------------------------------- /lib/sprout/generators/ruby/templates/ruby_test_helper.erb: -------------------------------------------------------------------------------- 1 | require "rubygems" 2 | require "bundler" 3 | Bundler.require :default, :development 4 | 5 | # These require statments *must* be in this order: 6 | # http://bit.ly/bCC0Ew 7 | # Somewhat surprised they're not being required by Bundler... 8 | require 'shoulda' 9 | require 'mocha' 10 | 11 | lib = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'lib')) 12 | $:.unshift lib unless $:.include? lib 13 | 14 | test = File.expand_path(File.join(File.dirname(__FILE__), '..')) 15 | $:.unshift test unless $:.include? test 16 | 17 | require 'sprout' 18 | require 'sprout/test_helper' 19 | 20 | require '<%= input.snake_case %>' 21 | 22 | -------------------------------------------------------------------------------- /lib/sprout/generators/tool/templates/Gemfile: -------------------------------------------------------------------------------- 1 | source "http://rubygems.org" 2 | 3 | gem "sprout", ">= 1.0.pre" 4 | 5 | -------------------------------------------------------------------------------- /lib/sprout/generators/tool/templates/tool.erb: -------------------------------------------------------------------------------- 1 | require 'sprout' 2 | 3 | class <%= input.camel_case %> 4 | NAME = '<%= input.snake_case %>' 5 | 6 | module VERSION 7 | MAJOR = 0 8 | MINOR = 0 9 | TINY = 1 10 | 11 | STRING = "#{MAJOR}.#{MINOR}.#{TINY}" 12 | end 13 | 14 | Sprout::Specification.new do |s| 15 | s.name = <%= input.camel_case %>::NAME 16 | s.version = <%= input.camel_case %>::VERSION::STRING 17 | 18 | # Create an independent remote_file_target for each 19 | # platform that must be supported independently. 20 | # 21 | # If the archive includes support for all platforms (:windows, :osx, :unix) 22 | # then set platform = :universal 23 | # 24 | s.add_remote_file_target do |t| 25 | t.platform = :universal 26 | t.archive_type = :zip 27 | t.url = "<%= url %>" 28 | t.md5 = "<%= md5 %>" 29 | 30 | # List all executables with their relative path within the 31 | # unpacked archive here: 32 | t.add_executable :<%= exe %>, "bin/<%= exe %>" 33 | end 34 | 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /lib/sprout/generators/tool/templates/tool.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | lib = File.expand_path File.dirname(__FILE__), 'lib' 3 | $:.unshift lib unless $:.include?(lib) 4 | 5 | require 'bundler' 6 | require 'rake' 7 | require '<%= input.snake_case %>' 8 | 9 | Gem::Specification.new do |s| 10 | s.name = <%= input.camel_case %>::NAME 11 | s.version = <%= input.camel_case %>::VERSION::STRING 12 | s.author = "<%= author %>" 13 | s.email = "<%= email %>" 14 | s.homepage = "<%= homepage %>" 15 | s.summary = "<%= summary %>" 16 | s.description = "<%= description %>" 17 | s.rubyforge_project = "sprout" 18 | s.files = FileList['**/**/*'].exclude /.git|.svn|.DS_Store/ 19 | s.add_bundler_dependencies 20 | s.require_paths << '.' 21 | end 22 | 23 | -------------------------------------------------------------------------------- /lib/sprout/generators/tool/tool_generator.rb: -------------------------------------------------------------------------------- 1 | 2 | module Sprout 3 | class ToolGenerator < Generator::Base 4 | 5 | add_param :author, String, { :default => 'Unknown' } 6 | 7 | add_param :description, String, { :default => 'This is an unconfigured Sprout Tool' } 8 | 9 | add_param :email, String, { :default => 'projectsprout@googlegroups.com' } 10 | 11 | add_param :exe, String, { :default => 'executable_name' } 12 | 13 | add_param :homepage, String, { :default => 'http://projectsprouts.org' } 14 | 15 | add_param :md5, String, { :default => 'd6939117f1df58e216f365a12fec64f9' } 16 | 17 | add_param :summary, String, { :default => 'Sprout Tool' } 18 | 19 | add_param :url, String, { :default => 'http://github.com/downloads/lukebayes/project-sprouts/echochamber-test.zip' } 20 | 21 | def manifest 22 | directory snake_input do 23 | template 'Gemfile' 24 | template "#{snake_input}.gemspec", 'tool.gemspec' 25 | template "#{snake_input}.rb", 'tool.erb' 26 | end 27 | end 28 | 29 | protected 30 | 31 | def snake_input 32 | input.snake_case 33 | end 34 | end 35 | end 36 | 37 | -------------------------------------------------------------------------------- /lib/sprout/output_buffer.rb: -------------------------------------------------------------------------------- 1 | 2 | module Sprout 3 | 4 | class OutputBuffer < String 5 | 6 | def initialize *args 7 | super 8 | @characters = '' 9 | end 10 | 11 | def puts msg 12 | @characters << msg 13 | end 14 | 15 | def print msg 16 | @characters << msg 17 | end 18 | 19 | def printf msg 20 | @characters << msg 21 | end 22 | 23 | def read 24 | response = @characters 25 | @characters = '' 26 | response 27 | end 28 | 29 | def flush 30 | end 31 | 32 | end 33 | end 34 | 35 | -------------------------------------------------------------------------------- /lib/sprout/platform.rb: -------------------------------------------------------------------------------- 1 | 2 | module Sprout 3 | 4 | ## 5 | # Determine what environment we're in so that we 6 | # can play nice with libraries, processes, executables, etc. 7 | # 8 | class Platform 9 | 10 | ## 11 | # Returns +true+ if the current platform is some flavor of Windows. 12 | # 13 | def windows? 14 | (/cygwin|mswin|mingw|bccwin|wince|emx|vista/ =~ ruby_platform) != nil 15 | end 16 | 17 | ## 18 | # Returns +true+ if the current platform is Vista. 19 | # 20 | def vista? 21 | (/vista/ =~ ruby_platform) != nil 22 | end 23 | 24 | ## 25 | # Returns +true+ if the current platform is some flavor of Unix on 26 | # Windows. Recognized nix-ish systems are: Cygwin, Mingw and BCCWin. 27 | # 28 | def windows_nix? 29 | (/cygwin|mingw|bccwin/ =~ ruby_platform) != nil 30 | end 31 | 32 | ## 33 | # Returns +true+ if the current platform is some flash of OS X. 34 | # 35 | def mac? 36 | (/darwin/ =~ ruby_platform) != nil 37 | end 38 | 39 | ## 40 | # Returns +true+ if the current platform is not +windows?+ or +java?+. 41 | # 42 | def unix? 43 | not windows? and not java? 44 | end 45 | 46 | ## 47 | # Returns +true+ if the current platform is +unix?+ and not +mac?+. 48 | # 49 | def linux? 50 | unix? and not mac? 51 | end 52 | 53 | ## 54 | # Returns +true+ if the current platform is running in the JVM (JRuby). 55 | # 56 | def java? 57 | (/java/ =~ ruby_platform) != nil 58 | end 59 | 60 | ## 61 | # Instance wrapper for the global Ruby Constant, +RUBY_PLATFORM+. 62 | # 63 | # wrapping this global allows for much easier testing and environment simulation. 64 | # 65 | def ruby_platform 66 | RUBY_PLATFORM 67 | end 68 | 69 | end 70 | end 71 | 72 | -------------------------------------------------------------------------------- /lib/sprout/rdoc_parser.rb: -------------------------------------------------------------------------------- 1 | require 'rdoc/rdoc' 2 | 3 | module Sprout 4 | 5 | class RDocParser 6 | 7 | def parse content 8 | end 9 | 10 | def parse_from_caller_string caller_string 11 | class_name, file_name, line_number = parse_caller_string caller_string 12 | rdoc_description_for class_name, file_name, line_number 13 | end 14 | 15 | private 16 | 17 | ## 18 | # NOTE: Don't forget that this string *sometimes* contains a colon on Windows... 19 | def parse_caller_string caller_string 20 | sections = caller_string.split(' ') 21 | parts = sections.first.split(':') 22 | file_name = parts.shift 23 | line_number = parts.shift 24 | class_name = class_name_from_caller_string caller_string 25 | #puts ">> class_name: #{class_name} file_name: #{file_name} line_number: #{line_number}" 26 | [class_name, file_name, line_number] 27 | end 28 | 29 | def class_name_from_caller_string caller_string 30 | parts = caller_string.split(' ') 31 | long = parts.pop 32 | matched = long.match // 33 | matched[1] unless matched.nil? 34 | end 35 | 36 | def rdoc_description_for class_name, file_name, line_number 37 | rendered = rendered_rdoc file_name 38 | end 39 | 40 | def rendered_rdoc file 41 | @rendered_rdoc ||= render_rdoc file 42 | end 43 | 44 | def render_rdoc file 45 | rdoc = RDoc::RDoc.new 46 | puts "===================================" 47 | puts ">> generating rdoc for: #{file}" 48 | 49 | rdoc.document [ file, "--format=xml", "--output=temp" ] 50 | {} 51 | end 52 | 53 | def render_rdoc_from_files 54 | # This works to some extent... 55 | #rdoc test/fixtures/examples/echo_inputs.rb --fmt=xml --op=tmp --all -q 56 | # But the following does not do the same thing: 57 | #response = rdoc.document [ file, '--fmt=xml', '--op=tmp', '--all', '-q' ] 58 | 59 | options = RDoc::Options.new 60 | options.files = FileList[ file ] 61 | options.formatter = 'markup' 62 | options.op_dir = './tmp' 63 | options.verbosity = 0 64 | 65 | rdoc.options = options 66 | 67 | #rdoc.stats = RDoc::Stats.new 1, options.verbosity 68 | #response = rdoc.document [] 69 | 70 | response = rdoc.parse_files [ file ] 71 | render_rdoc_toplevel response 72 | end 73 | 74 | def render_rdoc_toplevel toplevel 75 | puts ">> toplevel: #{toplevel}" 76 | toplevel.each do |file| 77 | puts ">> file: #{file.name}" 78 | puts ">> pretty: #{file.pretty_print}" 79 | end 80 | 81 | toplevel 82 | end 83 | 84 | def render_rdoc_bak file 85 | rdoc = RDoc::RDoc.new 86 | rdoc.options = RDoc::Options.new 87 | rdoc.parse_files [file] 88 | end 89 | end 90 | end 91 | 92 | -------------------------------------------------------------------------------- /lib/sprout/remote_file_loader.rb: -------------------------------------------------------------------------------- 1 | 2 | module Sprout 3 | 4 | ## 5 | # This class is used to load remote files from the network. 6 | class RemoteFileLoader 7 | 8 | class << self 9 | 10 | def load uri, md5=nil, display_name=nil 11 | fetch uri.to_s, display_name 12 | end 13 | 14 | private 15 | 16 | def fetch uri, display_name=nil 17 | begin 18 | return open_uri uri, display_name 19 | rescue SocketError => sock_err 20 | raise Sprout::Errors::RemoteFileLoaderError.new("[ERROR] Failed to load file from: '#{uri.to_s}' - Please check that your machine has a connection to the internet.\n[REMOTE ERROR] #{sock_err.to_s}") 21 | rescue OpenURI::HTTPError => http_err 22 | raise Sprout::Errors::RemoteFileLoaderError.new("[ERROR] Failed to load file from: '#{uri.to_s}'\n[REMOTE ERROR] #{http_err.io.read.strip}") 23 | rescue Errno::ECONNREFUSED => econ_err 24 | raise Errno::ECONNREFUSED.new("[ERROR] Connection refused at: '#{uri.to_s}'") 25 | end 26 | end 27 | 28 | private 29 | 30 | def open_uri uri, display_name=nil 31 | uri = URI.parse(uri) 32 | progress = nil 33 | response = nil 34 | display_name ||= uri.path.split("/").pop 35 | 36 | # Why was this here? Shouldn't the 'open' command work for other 37 | # protocols like https? 38 | # 39 | #message = "The RemoteFileTask failed for #{display_name}. We can only handle HTTP requests at this time, it seems you were trying: '#{uri.scheme}'" 40 | #raise Sprout::Errors::RemoteFileLoaderError.new(message) if uri.scheme != 'http' || uri.scheme != 'https' 41 | 42 | # This is the strangest implementation I've seen in Ruby yet. 43 | # Double lambda arguments with a block to top it off?! Gawsh. 44 | open(uri.to_s, 45 | :content_length_proc => lambda {|length| 46 | length ||= 0 47 | progress = Sprout::ProgressBar.new(display_name, length) 48 | progress.file_transfer_mode 49 | progress.set(0) 50 | }, 51 | :progress_proc => lambda {|length| 52 | progress.set length if progress 53 | }) do |f| 54 | response = f.read 55 | progress.finish 56 | end 57 | 58 | response 59 | end 60 | 61 | end 62 | end 63 | end 64 | 65 | -------------------------------------------------------------------------------- /lib/sprout/remote_file_target.rb: -------------------------------------------------------------------------------- 1 | require 'digest/md5' 2 | 3 | module Sprout 4 | 5 | class RemoteFileTarget < FileTarget 6 | 7 | attr_accessor :archive_type 8 | attr_accessor :url 9 | attr_accessor :md5 10 | 11 | def validate 12 | super 13 | raise Sprout::Errors::ValidationError.new "RemoteFileTarget.url is a required field" if url.nil? 14 | raise Sprout::Errors::ValidationError.new "RemoteFileTarget.md5 is a required field" if md5.nil? 15 | raise Sprout::Errors::ValidationError.new "RemoteFileTarget.archive_type is a required field" if archive_type.nil? 16 | end 17 | 18 | def resolve 19 | validate 20 | load_unpack_or_ignore_archive 21 | self 22 | end 23 | 24 | ## 25 | # Do not cache this value... 26 | # 27 | # This response can change over time IF: 28 | # - The downloaded bytes do not match the expected MD5 29 | # - AND the user confirms the prompt that they are OK with this 30 | def downloaded_file 31 | File.join(Sprout.cache, pkg_name, "#{md5}.#{archive_type}") 32 | end 33 | 34 | def unpacked_file 35 | upcased_pkg = pkg_name.upcase 36 | upcased_version = pkg_version.upcase.gsub /\./, '_' 37 | ENV["SPROUT_#{upcased_pkg}_#{upcased_version}"] || 38 | ENV["SPROUT_#{upcased_pkg}"] || 39 | ENV["#{upcased_pkg}_#{upcased_version}"] || 40 | ENV[upcased_pkg] || 41 | File.join(Sprout.cache, pkg_name, pkg_version) 42 | end 43 | 44 | protected 45 | 46 | def logger 47 | Sprout.stdout 48 | end 49 | 50 | def expand_local_path path 51 | File.join unpacked_file, path 52 | end 53 | 54 | private 55 | 56 | def load_unpack_or_ignore_archive 57 | if(!unpacked_files_exist?) 58 | if(!File.exists?(downloaded_file)) 59 | bytes = download_archive 60 | write_archive bytes 61 | end 62 | 63 | # If we *just* downloaded the file, 64 | # use the bytes directly, otherwise 65 | # read them off disk from a previous 66 | # download attempt: 67 | bytes ||= File.open(downloaded_file, 'rb').read 68 | 69 | if should_unpack?(bytes, md5) 70 | unpack_archive 71 | end 72 | end 73 | end 74 | 75 | def unpacked_files_exist? 76 | File.exists?(unpacked_file) && !Dir.empty?(unpacked_file) 77 | end 78 | 79 | def download_archive 80 | Sprout::RemoteFileLoader.load url, pkg_name 81 | end 82 | 83 | def write_archive bytes 84 | FileUtils.mkdir_p File.dirname(downloaded_file) 85 | File.open downloaded_file, 'wb+' do |f| 86 | f.write bytes 87 | end 88 | end 89 | 90 | def should_unpack? bytes, expected_md5sum 91 | if expected_md5sum 92 | downloaded_md5 = Digest::MD5.new 93 | downloaded_md5 << bytes 94 | 95 | if(expected_md5sum != downloaded_md5.hexdigest) 96 | return prompt_for_md5_failure downloaded_md5, expected_md5sum 97 | end 98 | end 99 | return true 100 | end 101 | 102 | def prompt_for_md5_failure downloaded_md5, expected_md5sum 103 | puts "The MD5 Sum of the downloaded file (#{downloaded_md5.hexdigest}) does not match what was expected (#{expected_md5sum})." 104 | puts "Would you like to install anyway? [Yn]" 105 | user_response = $stdin.gets.chomp! 106 | if(user_response.downcase == 'y') 107 | return true 108 | else 109 | raise Sprout::Errors::RemoteFileLoaderError.new('MD5 Checksum failed') 110 | end 111 | end 112 | 113 | def unpack_archive 114 | logger.puts "Unpacking archive at #{downloaded_file} now. This can take anywhere from a few seconds to many minutes depending on your OS and the size of the archive.\n\nIf you're on windows, consider using this ample time to look into improving the zip utils in Ruby..." 115 | FileUtils.mkdir_p unpacked_file 116 | unpacker = Sprout::ArchiveUnpacker.new 117 | unpacker.unpack downloaded_file, unpacked_file, archive_type 118 | end 119 | 120 | end 121 | end 122 | -------------------------------------------------------------------------------- /lib/sprout/string.rb: -------------------------------------------------------------------------------- 1 | 2 | class String 3 | 4 | # "FooBar".snake_case #=> "foo_bar" 5 | def snake_case 6 | gsub(/\B[A-Z]/, '_\&').downcase 7 | end 8 | 9 | # "foo_bar".camel_case #=> "FooBar" 10 | def camel_case 11 | str = gsub(/^[a-z]|_+[a-z]/) { |a| a.upcase } 12 | str.gsub(/_/, '') 13 | end 14 | 15 | def dash_case 16 | self.snake_case.gsub('_', '-') 17 | end 18 | end 19 | 20 | -------------------------------------------------------------------------------- /lib/sprout/system.rb: -------------------------------------------------------------------------------- 1 | require 'sprout/system/base_system' 2 | require 'sprout/system/unix_system' 3 | require 'sprout/system/java_system' 4 | require 'sprout/system/osx_system' 5 | require 'sprout/system/win_system' 6 | require 'sprout/system/win_nix_system' 7 | require 'sprout/system/vista_system' 8 | 9 | module Sprout 10 | 11 | module System 12 | 13 | # This is the factory that one should 14 | # generally be used to create new, concrete 15 | # System objects. 16 | # 17 | # A typical example follows: 18 | # 19 | # system = System.create 20 | # Dir.chdir system.home 21 | # system.execute "pwd" # /home/yourusername 22 | # 23 | def self.create 24 | p = Sprout::Platform.new 25 | return VistaSystem.new if p.vista? 26 | return WinNixSystem.new if p.windows_nix? 27 | return WinSystem.new if p.windows? 28 | return JavaSystem.new if p.java? 29 | return OSXSystem.new if p.mac? 30 | return UnixSystem.new 31 | end 32 | 33 | end 34 | end 35 | 36 | -------------------------------------------------------------------------------- /lib/sprout/system/java_system.rb: -------------------------------------------------------------------------------- 1 | 2 | module Sprout::System 3 | 4 | # The concrete system for the JRuby environment 5 | class JavaSystem < BaseSystem 6 | 7 | end 8 | end 9 | 10 | -------------------------------------------------------------------------------- /lib/sprout/system/osx_system.rb: -------------------------------------------------------------------------------- 1 | 2 | module Sprout::System 3 | 4 | class OSXSystem < UnixSystem 5 | LIBRARY = 'Library' 6 | 7 | def library 8 | lib = File.join(home, LIBRARY) 9 | if(File.exists?(lib)) 10 | return lib 11 | else 12 | return super 13 | end 14 | end 15 | 16 | def format_application_name(name) 17 | return name.capitalize 18 | end 19 | 20 | def can_execute? platform 21 | [:mac, :osx, :macosx, :darwin].include?(platform) || super 22 | end 23 | 24 | end 25 | end 26 | 27 | -------------------------------------------------------------------------------- /lib/sprout/system/unix_system.rb: -------------------------------------------------------------------------------- 1 | 2 | module Sprout::System 3 | 4 | class UnixSystem < BaseSystem 5 | 6 | def clean_path path 7 | return if path.nil? 8 | if(path.include? '../') 9 | path = File.expand_path path 10 | end 11 | 12 | if(path.index(' ')) 13 | return path.split(' ').join('\ ') 14 | end 15 | return path 16 | end 17 | 18 | def execute(tool, options='') 19 | attempt_to_repair_executable tool 20 | super(tool, options) 21 | end 22 | 23 | ## 24 | # Ensure Application +name+ String begins with a dot (.), and does 25 | # not include spaces. 26 | # 27 | def format_application_name(name) 28 | if(name.index('.') != 0) 29 | name = '.' + name 30 | end 31 | return name.split(" ").join("_").downcase 32 | end 33 | 34 | def can_execute? platform 35 | [:unix, :linux].include?(platform) || super 36 | end 37 | 38 | ## 39 | # Repair Windows Line endings 40 | # found in non-windows executables 41 | # (Flex SDK is regularly published 42 | # with broken CRLFs) 43 | # 44 | # +path+ String path to the executable file. 45 | # 46 | def attempt_to_repair_executable path 47 | repair_executable(path) if should_repair_executable(path) 48 | end 49 | 50 | def repair_executable path 51 | content = File.read(path) 52 | if(content.match(/\r\n/)) 53 | Sprout.stdout.puts "[WARNING] Sprouts is about to replace invalid Windows line endings on an executable at: (#{path})" 54 | content.gsub!(/\r\n/, "\n") 55 | File.open(path, 'w+') do |f| 56 | f.write content 57 | end 58 | end 59 | end 60 | 61 | ## 62 | # Determine if we should call +repair_executable+ 63 | # for the file at the provided +path+ String. 64 | # 65 | # Will this corrupt binaries? Yes... Yes. it. will. 66 | # 67 | # This also fails on UTF-8 files since Ruby's regex 68 | # appears to choke on UTF-8?? 69 | def should_repair_executable path 70 | return (File.exists?(path) && !File.directory?(path) && File.read(path).match(/^\#\!\/bin\/sh/)) 71 | end 72 | 73 | end 74 | end 75 | 76 | -------------------------------------------------------------------------------- /lib/sprout/system/vista_system.rb: -------------------------------------------------------------------------------- 1 | 2 | module Sprout::System 3 | 4 | class VistaSystem < WinSystem 5 | 6 | def find_home 7 | return env_userprofile unless env_userprofile.nil? 8 | super 9 | end 10 | 11 | def env_userprofile 12 | ENV['USERPROFILE'] 13 | end 14 | end 15 | end 16 | 17 | -------------------------------------------------------------------------------- /lib/sprout/system/win_nix_system.rb: -------------------------------------------------------------------------------- 1 | 2 | module Sprout::System 3 | 4 | # The concrete system for Cygwin and Mingw 5 | # We can't quite treat these users like 6 | # a typical *nix system, but we can't quite 7 | # treat them like Windows users either. 8 | # 9 | # One great thing about these users, 10 | # is that we get to use real processes, 11 | # rather than the broken processes that 12 | # windows normally offers. 13 | class WinNixSystem < WinSystem 14 | 15 | def win_home 16 | @win_home ||= ENV['HOMEDRIVE'] + ENV['HOMEPATH'] 17 | end 18 | 19 | def home 20 | @home ||= win_nix_home 21 | end 22 | 23 | def win_nix_home 24 | path = win_home.split('\\').join("/") 25 | return path if File.exists?(path) 26 | 27 | parts = path.split("/") 28 | path = parts.shift().downcase + "/" + parts.join("/") 29 | path = path.split(":").join("") 30 | "/cygdrive/" + path 31 | end 32 | 33 | end 34 | end 35 | 36 | -------------------------------------------------------------------------------- /lib/sprout/system/win_system.rb: -------------------------------------------------------------------------------- 1 | 2 | module Sprout::System 3 | 4 | # The default Windows system. 5 | # This is the system type for all 6 | # major versions and flavors of Windows 7 | # (except Cygwin and Mingw). 8 | class WinSystem < BaseSystem 9 | LOCAL_SETTINGS = "Local\ Settings" 10 | APPLICATION_DATA = "Application\ Data" 11 | 12 | def home 13 | path = super 14 | if(path.include? "My Documents") 15 | path = File.dirname(path) 16 | end 17 | return path 18 | end 19 | 20 | def get_paths 21 | return env_path.split(';') 22 | end 23 | 24 | def library 25 | # For some reason, my homepath returns inside 'My Documents'... 26 | application_data = File.join(home, LOCAL_SETTINGS, APPLICATION_DATA) 27 | if(File.exists?(application_data)) 28 | return application_data 29 | else 30 | return super 31 | end 32 | end 33 | 34 | def clean_path(path) 35 | path = path.split('/').join("\\") 36 | if(path.index(' ')) 37 | return %{"#{path}"} 38 | end 39 | return path 40 | end 41 | 42 | def format_application_name(name) 43 | return name.capitalize 44 | end 45 | 46 | def can_execute? platform 47 | [:windows, :win32].include?(platform) || super 48 | end 49 | 50 | protected 51 | 52 | ## 53 | # Gets the process runner and calls 54 | # platform-specific execute method 55 | def get_and_execute_process_runner tool, options=nil 56 | tool = clean_path find_tool(tool) 57 | runner = get_process_runner 58 | runner.execute_win32 tool, options 59 | runner 60 | end 61 | 62 | private 63 | 64 | def find_tool tool 65 | return "#{tool}.bat" if File.exists?("#{tool}.bat") 66 | return "#{tool}.exe" if File.exists?("#{tool}.exe") 67 | tool 68 | end 69 | 70 | def env_path 71 | ENV['PATH'] 72 | end 73 | 74 | end 75 | end 76 | 77 | -------------------------------------------------------------------------------- /lib/sprout/version.rb: -------------------------------------------------------------------------------- 1 | 2 | module Sprout 3 | NAME = 'sprout' 4 | module VERSION 5 | STRING = File.read(File.join(File.dirname(__FILE__), '..', '..', 'VERSION').strip) 6 | MAJOR = STRING.split('.')[0] 7 | MINOR = STRING.split('.')[1] 8 | TINY = STRING.split('.')[2] 9 | RELEASE = STRING.split('.')[3] 10 | MAJOR_MINOR = [MAJOR, MINOR].join('.') 11 | end 12 | end 13 | 14 | -------------------------------------------------------------------------------- /rakefile.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'bundler' 3 | 4 | # Hack this dir onto path for Ruby 1.9.2 5 | # support: 6 | test_package = File.expand_path(File.join(File.dirname(__FILE__), 'test')) 7 | $: << test_package unless $:.include? test_package 8 | 9 | Bundler.require 10 | 11 | require 'rake/clean' 12 | require 'rake/testtask' 13 | 14 | ## 15 | # NOTE, to generate documentation, simply run: 16 | # 17 | # bundle install 18 | # yard 19 | # 20 | 21 | CLEAN.add 'doc' 22 | 23 | namespace :test do 24 | Rake::TestTask.new(:units) do |t| 25 | t.libs << "test/unit" 26 | t.test_files = FileList["test/unit/*_test.rb"] 27 | t.verbose = true 28 | end 29 | 30 | namespace :coverage do 31 | desc "Delete aggregate coverage data." 32 | task(:clean) { rm_f "coverage.data" } 33 | end 34 | 35 | namespace :torture do 36 | desc "Flog the Sprouts" 37 | task :flog do 38 | puts "--------------------------" 39 | puts "Flog Report:" 40 | message =< ['torture:flog', 'torture:flay'] 68 | 69 | end 70 | 71 | task :test => 'test:units' 72 | 73 | desc "Run all tests and reports" 74 | task :cruise => [:test, 'test:coverage', 'test:torture'] 75 | 76 | -------------------------------------------------------------------------------- /script/add_param_handler.rb: -------------------------------------------------------------------------------- 1 | 2 | class AddParamHandler < YARD::Handlers::Ruby::MethodHandler 3 | 4 | handles method_call(:add_param) 5 | 6 | def process 7 | name = statement[1][0].source.gsub(/^:/, '') 8 | class_name = statement[1][1].source 9 | 10 | case class_name 11 | when "Strings" 12 | class_name = "Array" 13 | when "Files" 14 | class_name = "Array [Files]" 15 | when "Paths" 16 | class_name = "Array [Paths]" 17 | when "Urls" 18 | class_name = "Array [Urls]" 19 | end 20 | 21 | namespace.attributes[scope][name] ||= SymbolHash[:read => nil, :write => nil] 22 | 23 | {:read => name, :write => "#{name}="}.each do |type, meth| 24 | namespace.attributes[scope][name][type] = MethodObject.new(namespace, meth, scope) do |o| 25 | 26 | o.source = statement.source 27 | o.signature = method_signature(meth) 28 | o.docstring = statement.comments 29 | 30 | if type == :write 31 | o.parameters = [['value', nil]] 32 | else 33 | new_tag = YARD::Tags::Tag.new(:return, "An instance of #{class_name}", class_name) 34 | o.docstring.add_tag(new_tag) 35 | end 36 | 37 | o.visibility = visibility 38 | end 39 | end 40 | end 41 | 42 | end 43 | 44 | -------------------------------------------------------------------------------- /script/console: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # File: script/console 3 | irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb' 4 | 5 | libs = " -r irb/completion" 6 | # Perhaps use a console_lib to store any extra methods I may want available in the cosole 7 | # libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}" 8 | libs << " -r #{File.dirname(__FILE__) + '/../lib/as3.rb'}" 9 | puts "Loading as3 gem" 10 | exec "#{irb} #{libs} --simple-prompt" -------------------------------------------------------------------------------- /script/destroy: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..')) 3 | 4 | begin 5 | require 'rubigen' 6 | rescue LoadError 7 | require 'rubygems' 8 | require 'rubigen' 9 | end 10 | require 'rubigen/scripts/destroy' 11 | 12 | ARGV.shift if ['--help', '-h'].include?(ARGV[0]) 13 | RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit] 14 | RubiGen::Scripts::Destroy.new.run(ARGV) 15 | -------------------------------------------------------------------------------- /script/generate: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..')) 3 | 4 | begin 5 | require 'rubigen' 6 | rescue LoadError 7 | require 'rubygems' 8 | require 'rubigen' 9 | end 10 | require 'rubigen/scripts/generate' 11 | 12 | ARGV.shift if ['--help', '-h'].include?(ARGV[0]) 13 | RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit] 14 | RubiGen::Scripts::Generate.new.run(ARGV) 15 | -------------------------------------------------------------------------------- /script/google_analytics_footer.rb: -------------------------------------------------------------------------------- 1 | 2 | YARD::Templates::Engine.register_template_path File.join('sprout', 'script', 'templates') 3 | 4 | -------------------------------------------------------------------------------- /script/templates/default/layout/html/footer.erb: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 12 | 17 | 18 | -------------------------------------------------------------------------------- /sprout.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | lib = File.expand_path File.join(File.dirname(__FILE__), 'lib') 3 | $:.unshift lib unless $:.include?(lib) 4 | 5 | require 'bundler' 6 | require 'rake' 7 | 8 | Gem::Specification.new do |s| 9 | s.name = 'sprout' 10 | s.version = File.read('VERSION').strip 11 | s.platform = Gem::Platform::RUBY 12 | s.authors = ["Luke Bayes"] 13 | s.email = "projectsprouts@googlegroups.com" 14 | s.homepage = "http://projectsprouts.org" 15 | s.summary = "Software development - evolved" 16 | s.description = "Project Sprouts gives you access to beautiful generators and easily customized templates, automated build scripts, distributed libraries and simple system configuration" 17 | s.required_rubygems_version = ">= 1.3.6" 18 | s.rubyforge_project = "sprout" 19 | s.require_path = ['lib'] 20 | s.files = FileList['**/**/*'].exclude /.git|.svn|.DS_Store/ 21 | s.executables = ['sprout', 'sprout-generator', 'sprout-class', 'sprout-test', 'sprout-suite', 'sprout-ruby'] 22 | s.add_bundler_dependencies 23 | end 24 | 25 | -------------------------------------------------------------------------------- /test/fixtures/archive_unpacker/copyable/some_file.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lukebayes/project-sprouts/6882d7309d617e35350749df84fac5e7d9c5e843/test/fixtures/archive_unpacker/copyable/some_file.exe -------------------------------------------------------------------------------- /test/fixtures/archive_unpacker/copyable/some_file.rb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lukebayes/project-sprouts/6882d7309d617e35350749df84fac5e7d9c5e843/test/fixtures/archive_unpacker/copyable/some_file.rb -------------------------------------------------------------------------------- /test/fixtures/archive_unpacker/copyable/some_file.swc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lukebayes/project-sprouts/6882d7309d617e35350749df84fac5e7d9c5e843/test/fixtures/archive_unpacker/copyable/some_file.swc -------------------------------------------------------------------------------- /test/fixtures/archive_unpacker/tgz/some folder.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lukebayes/project-sprouts/6882d7309d617e35350749df84fac5e7d9c5e843/test/fixtures/archive_unpacker/tgz/some folder.tgz -------------------------------------------------------------------------------- /test/fixtures/archive_unpacker/tgz/some_file.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lukebayes/project-sprouts/6882d7309d617e35350749df84fac5e7d9c5e843/test/fixtures/archive_unpacker/tgz/some_file.tgz -------------------------------------------------------------------------------- /test/fixtures/archive_unpacker/zip/some folder.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lukebayes/project-sprouts/6882d7309d617e35350749df84fac5e7d9c5e843/test/fixtures/archive_unpacker/zip/some folder.zip -------------------------------------------------------------------------------- /test/fixtures/archive_unpacker/zip/some_file.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lukebayes/project-sprouts/6882d7309d617e35350749df84fac5e7d9c5e843/test/fixtures/archive_unpacker/zip/some_file.zip -------------------------------------------------------------------------------- /test/fixtures/examples/app_generator.rb: -------------------------------------------------------------------------------- 1 | ## 2 | # This is an example of how I think generators ought to look. 3 | # 4 | # The current interface to Rubigen is unacceptable because 5 | # of it's dependence on duplicate boilerplate, and global 6 | # state. 7 | # 8 | # should also be a generator helper that allows you 9 | # to reference an existing directory on disk, and will 10 | # emit a new generator (gem?) that would recreate those files: 11 | # 12 | # sprout-generator-importer ~/Projects/SomeProject 13 | # 14 | class AppGenerator 15 | include Sprout::Generator 16 | 17 | ## 18 | # The path where classes should usually be created. 19 | add_param :src, String, { :default => 'src' } 20 | 21 | ## 22 | # The path where test cases should be created. 23 | add_param :test, String, { :default => 'test' } 24 | 25 | ## 26 | # The path where libraries should be added. 27 | add_param :lib, String, { :default => 'lib' } 28 | 29 | ## 30 | # The path where binaries should be created. 31 | add_param :bin, String, { :default => 'bin' } 32 | 33 | ## 34 | # The path where all assets should be created. 35 | add_param :assets, String, { :default => 'assets' } 36 | 37 | ## 38 | # The path where skins should be created. 39 | add_param :skins, String, { :default => 'skins' } 40 | 41 | ## 42 | # The path where scripts are created. 43 | add_param :script, String, { :default => 'script' } 44 | 45 | ## 46 | # The name of the project that should be created. 47 | add_param :input, String, { :reader => :get_input } 48 | 49 | ## 50 | # Prevent the creation of a lib directory. 51 | add_param :no_lib, Boolean 52 | 53 | ## 54 | # Prevent the creation of an assets directory. 55 | add_param :no_assets, Boolean 56 | 57 | def manifest 58 | directory input do 59 | file 'rakefile.rb.erb', 'rakefile.rb' 60 | file 'Gemfile.erb', 'Gemfile' 61 | 62 | directory src do 63 | file 'Class.as.erb', "#{input}.as" 64 | end 65 | 66 | directory File.join(assets, skins) do 67 | file 'ProjectSprouts.png', 'ProjectSprouts.png' 68 | end unless no_assets 69 | 70 | directory lib unless no_lib 71 | directory bin 72 | 73 | default_project_files 74 | end 75 | end 76 | 77 | private 78 | 79 | def get_input 80 | @input.camel_case 81 | end 82 | 83 | end 84 | 85 | 86 | ## 87 | # Defined in the imaginary base class: 88 | def default_project_files 89 | directory script do 90 | file 'generate', 'generate' 91 | file 'destroy', 'destroy' 92 | file 'console', 'console' 93 | end 94 | end 95 | 96 | ## 97 | # These directives ought to also be very easy to test. 98 | # 99 | class AppGeneratorTest 100 | include Sprout::GeneratorTestHelper 101 | 102 | context "a new generator" do 103 | 104 | setup do 105 | @fixture = File.join fixtures, 'generators' 106 | @generator = ProjectGenerator.new 107 | @generator.path = @fixture 108 | @generator.name = 'SomeProject' 109 | @generator.execute 110 | end 111 | 112 | should_create_directory File.join(@fixture, 'SomeProject') do 113 | with_file 'rakefile.rb' do |content| 114 | assert_matches /SomeProject.as/, content 115 | assert_matches /SomeProjectRunner.as/, content 116 | assert_matches /SomeProject.swf/, content 117 | end 118 | should_create_directory 'script' do 119 | with_file 'generate' 120 | with_file 'destroy' 121 | with_file 'console' 122 | end 123 | end 124 | end 125 | 126 | end 127 | 128 | -------------------------------------------------------------------------------- /test/fixtures/examples/echo_inputs.rb: -------------------------------------------------------------------------------- 1 | # /usr/bin/env ruby 2 | 3 | require 'rubygems' 4 | require 'sprout' 5 | 6 | class CustomParameter < Sprout::Executable::Param; end 7 | 8 | class EchoInputs < Sprout::Executable::Base 9 | 10 | ## 11 | # A boolean parameter that will be set to true if present. 12 | # 13 | # echo-inputs --truthy 14 | # 15 | add_param :truthy, Boolean 16 | 17 | add_param :long_truthy, Boolean 18 | 19 | add_param :default_truthy, Boolean, { :default => true } 20 | 21 | ## 22 | # A boolean parameter that defaults to true, and must be 23 | # explicitly set to false in order to turn it off. 24 | # 25 | # echo-inputs --falsey=false 26 | # 27 | add_param :falsey, Boolean, { :default => true, :hidden_value => false, :show_on_false => true } 28 | 29 | ## 30 | # A file that exists at the time it is provided. 31 | # 32 | # echo-inputs --file=lib/sprout.rb 33 | # 34 | add_param :file, File 35 | 36 | ## 37 | # A collection of files, this parameter can be repeated 38 | # any number of times. 39 | # 40 | # echo-inputs --files+=rakefile.rb --files+=README.textil 41 | # 42 | add_param :files, Files 43 | 44 | ## 45 | # A numeric value. 46 | # 47 | # echo-inputs --number=23 48 | # 49 | add_param :number, Number 50 | 51 | ## 52 | # A relative or fully-qualified path to a directory. 53 | # 54 | # echo-inputs --path=lib/ 55 | # 56 | add_param :path, Path 57 | 58 | ## 59 | # Relative or fully-qualified paths to directories. 60 | # 61 | # echo-inputs --paths+=lib/ --paths+=test/ 62 | # 63 | add_param :paths, Paths 64 | 65 | ## 66 | # A simple string value. 67 | # 68 | # echo-inputs --string='Some String' 69 | # 70 | add_param :string, String 71 | 72 | ## 73 | # A collection of simple string values. 74 | # 75 | # echo-inputs --strings+='First' --strings+='Second' 76 | # 77 | add_param :strings, Strings 78 | 79 | ## 80 | # A short version of another parameter. 81 | # 82 | # echo-inputs -sp+='First' --sp+='Second' 83 | # 84 | add_param_alias :sp, :strings 85 | 86 | 87 | ## 88 | # A collection of url values. 89 | # 90 | # echo-inputs --urls+='http://google.com' --urls+='http://yahoo.com' 91 | # 92 | add_param :urls, Urls 93 | 94 | ## 95 | # A custom parameter type that is provided by this tool. 96 | # 97 | # echo-inputs --custom='Some Value' 98 | # 99 | add_param :custom, CustomParameter 100 | 101 | ## 102 | # A required value with a hidden name. This kind of value is often 103 | # presented as the default option. 104 | # 105 | # echo-inputs lib/sprout.rb 106 | # 107 | add_param :input, File, { :required => true } 108 | 109 | def execute 110 | puts "--truthy=#{truthy}" if truthy 111 | puts "--falsey=#{falsey}" unless falsey 112 | puts "--file=#{file}" unless file.nil? 113 | puts "--files=#{files.inspect}" unless files.empty? 114 | puts "--number=#{number}" unless number.nil? 115 | puts "--path=#{path}" unless path.nil? 116 | puts "--paths=#{paths.inspect}" unless paths.empty? 117 | puts "--string=#{string}" unless string.nil? 118 | puts "--strings=#{strings.inspect}" unless strings.empty? 119 | puts "--sp=#{sp.inspect}" unless sp.empty? 120 | puts "--urls=#{urls.inspect}" unless urls.empty? 121 | puts "--custom=#{custom}" unless custom.nil? 122 | puts " [input]: #{input}" 123 | end 124 | end 125 | 126 | ## 127 | # When we're the outer application, 128 | # run like an application: 129 | if($0 == __FILE__) 130 | exe = EchoInputs.new 131 | exe.parse! ARGV 132 | exe.execute 133 | end 134 | 135 | ## 136 | # Expose this application to Rake like: 137 | # 138 | # echo_inputs do |t| 139 | # t.string = 'Foo' 140 | # t.falsey = false 141 | # end 142 | # 143 | def echo_inputs args 144 | exe = EchoInputs.new 145 | yield exe if block_given? 146 | # Use 'file' task as if we were a compiler 147 | # that created a file... 148 | file args do 149 | exe.execute 150 | end 151 | exe 152 | end 153 | 154 | 155 | -------------------------------------------------------------------------------- /test/fixtures/examples/rakefile.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'bundler' 3 | Bundler.require 4 | 5 | library :corelib 6 | 7 | # Configure the default environment: 8 | env :default do 9 | set :input, 'src/SomeProject.as' 10 | set :output, 'bin/SomeProject.swf' 11 | set :libraries, [:corelib] 12 | end 13 | 14 | # Configure the deployed environment: 15 | env :deploy => :default do 16 | set :debug, false 17 | end 18 | 19 | # Configure the demo environment: 20 | env :demo => :deploy do 21 | set :debug, true 22 | end 23 | 24 | # Configure the test environment: 25 | env :test => :deploy do 26 | set :input , 'src/SomeProjectRunner.as' 27 | set :output, 'bin/SomeProjectRunner.swf' 28 | 29 | library :asunit4 30 | set :libraries, [:corelib, :asunit4] 31 | end 32 | 33 | # Configure the Continuous Integration environment: 34 | evn :ci => :test do 35 | set :input, 'src/SomeProjectXMLRunner.as' 36 | set :output, 'bin/SomeProjectXMLRunner.swf' 37 | end 38 | 39 | 40 | desc 'Build the application' 41 | mxmlc get(:output) => get(:libraries) do |t| 42 | t.input = get(:input) 43 | t.debug = get(:debug) 44 | end 45 | 46 | desc 'Compile and run the application' 47 | flashplayer :run => get(:output) 48 | 49 | desc 'Compile and debug the application' 50 | fdb :debug => get(:output) do |t| 51 | t.kill_on_fault = true 52 | end 53 | 54 | task :default => :run 55 | 56 | -------------------------------------------------------------------------------- /test/fixtures/executable/echochamber_gem/bin/echochamber: -------------------------------------------------------------------------------- 1 | 2 | echo "ECHO ECHO ECHO $1" 3 | 4 | -------------------------------------------------------------------------------- /test/fixtures/executable/echochamber_gem/echo_chamber.rb: -------------------------------------------------------------------------------- 1 | 2 | Sprout::Specification.new do |s| 3 | s.name = 'echo_chamber' 4 | s.version = '1.0.pre' 5 | 6 | s.add_file_target do |t| 7 | t.add_executable :echos, 'bin/echochamber' 8 | end 9 | end 10 | 11 | -------------------------------------------------------------------------------- /test/fixtures/executable/flex3sdk_gem/fdb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | class FakeFDB 4 | 5 | def initialize 6 | validate_argv 7 | str = "Adobe fdb (Flash Player Debugger) [build 16076]\n" 8 | str << "Copyright (c) 2004-2007 Adobe, Inc. All rights reserved.\n" 9 | str << "(fdb) " 10 | printf str 11 | gather_input 12 | end 13 | 14 | def gather_input 15 | $stdout.flush 16 | command = $stdin.gets.chomp! 17 | parts = command.split(' ') 18 | name = parts.shift 19 | 20 | case name 21 | when "run" 22 | handle_run parts 23 | when "break" 24 | handle_break parts 25 | when "continue" 26 | handle_continue parts 27 | when "kill" 28 | handle_kill parts 29 | when "y" 30 | handle_confirmation parts 31 | when "quit" 32 | handle_quit parts 33 | when "run_with_error" 34 | handle_run_with_error parts 35 | else 36 | puts "FAKE FDB doesn't know how to respond to #{command}" 37 | exit 1 38 | end 39 | 40 | gather_input 41 | end 42 | 43 | def validate_argv 44 | if ARGV.size > 0 45 | raise "FAKE FDB doesn't expect any params, but received, #{ARGV}" 46 | end 47 | end 48 | 49 | def handle_run args 50 | str = "Waiting for Player to connect\n" 51 | str << "Player connected; session starting.\n" 52 | str << "Set breakpoints and then type 'continue' to resume the session.\n" 53 | str = "[SWF] Users:lbayes:Projects:AsUnit-P2:asunit-4.0:bin:AsUnitRunner.swf - 226,833 bytes after decompression\n" 54 | str << "(fdb) " 55 | printf str 56 | end 57 | 58 | def handle_break args 59 | str = "Breakpoint 1, AsUnitRunner() at AsUnitRunner.as:12\n" 60 | str << "12 core = new TextCore();\n" 61 | str << "(fdb) " 62 | printf str 63 | end 64 | 65 | def handle_continue args 66 | str = "Continuing now\n" 67 | str << "\n" 68 | str << "Fake Content\n" 69 | str << "\n" 70 | str << "(fdb) " 71 | printf str 72 | end 73 | 74 | def handle_kill args 75 | printf "Kill the program being debugged? (y or n) " 76 | end 77 | 78 | def handle_confirmation args 79 | str = "Confirmation accepted\n" 80 | str << "(fdb) " 81 | printf str 82 | end 83 | 84 | def handle_run_with_error args 85 | str = "This is an error!\n" 86 | str << "This is more details about the error!\n" 87 | str << "Here are even more details!\n" 88 | $stderr.printf str 89 | printf "(fdb) " 90 | end 91 | 92 | def handle_quit args 93 | puts ">> EXITING NOW!\n" 94 | exit! 0 95 | end 96 | 97 | end 98 | 99 | fake_fdb = FakeFDB.new 100 | 101 | 102 | -------------------------------------------------------------------------------- /test/fixtures/executable/flex3sdk_gem/fdb.bat: -------------------------------------------------------------------------------- 1 | 2 | @echo off 3 | ruby test\fixtures\executable\flex3sdk_gem\fdb 4 | 5 | -------------------------------------------------------------------------------- /test/fixtures/executable/flex3sdk_gem/flex3sdk.rb: -------------------------------------------------------------------------------- 1 | 2 | exe = OpenStruct.new({ 3 | :name => :mxmlc, 4 | :pkg_name => 'flex3sdk', 5 | :pkg_version => '3.0.0', 6 | :platform => :universal, 7 | :path => File.join(File.dirname(__FILE__), 'mxmlc') 8 | }) 9 | 10 | Sprout::Executable.register exe 11 | 12 | -------------------------------------------------------------------------------- /test/fixtures/executable/flex3sdk_gem/mxmlc: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "success" 3 | 4 | -------------------------------------------------------------------------------- /test/fixtures/executable/flex3sdk_gem/mxmlc.bat: -------------------------------------------------------------------------------- 1 | 2 | echo "windows success" 3 | 4 | -------------------------------------------------------------------------------- /test/fixtures/executable/params/input.as: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lukebayes/project-sprouts/6882d7309d617e35350749df84fac5e7d9c5e843/test/fixtures/executable/params/input.as -------------------------------------------------------------------------------- /test/fixtures/executable/params/input2.as: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lukebayes/project-sprouts/6882d7309d617e35350749df84fac5e7d9c5e843/test/fixtures/executable/params/input2.as -------------------------------------------------------------------------------- /test/fixtures/executable/params/input3.as: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lukebayes/project-sprouts/6882d7309d617e35350749df84fac5e7d9c5e843/test/fixtures/executable/params/input3.as -------------------------------------------------------------------------------- /test/fixtures/executable/params/mxmlc: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Fake MXMLC called with" + $1 4 | exit 0 5 | 6 | -------------------------------------------------------------------------------- /test/fixtures/executable/path with spaces/input.as: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lukebayes/project-sprouts/6882d7309d617e35350749df84fac5e7d9c5e843/test/fixtures/executable/path with spaces/input.as -------------------------------------------------------------------------------- /test/fixtures/executable/path with spaces/input2.as: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lukebayes/project-sprouts/6882d7309d617e35350749df84fac5e7d9c5e843/test/fixtures/executable/path with spaces/input2.as -------------------------------------------------------------------------------- /test/fixtures/executable/path with spaces/input3.as: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lukebayes/project-sprouts/6882d7309d617e35350749df84fac5e7d9c5e843/test/fixtures/executable/path with spaces/input3.as -------------------------------------------------------------------------------- /test/fixtures/executable/paths/folder1/file1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lukebayes/project-sprouts/6882d7309d617e35350749df84fac5e7d9c5e843/test/fixtures/executable/paths/folder1/file1 -------------------------------------------------------------------------------- /test/fixtures/executable/paths/folder1/file2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lukebayes/project-sprouts/6882d7309d617e35350749df84fac5e7d9c5e843/test/fixtures/executable/paths/folder1/file2 -------------------------------------------------------------------------------- /test/fixtures/executable/paths/folder1/file3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lukebayes/project-sprouts/6882d7309d617e35350749df84fac5e7d9c5e843/test/fixtures/executable/paths/folder1/file3 -------------------------------------------------------------------------------- /test/fixtures/executable/paths/folder2/file4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lukebayes/project-sprouts/6882d7309d617e35350749df84fac5e7d9c5e843/test/fixtures/executable/paths/folder2/file4 -------------------------------------------------------------------------------- /test/fixtures/executable/paths/folder2/file5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lukebayes/project-sprouts/6882d7309d617e35350749df84fac5e7d9c5e843/test/fixtures/executable/paths/folder2/file5 -------------------------------------------------------------------------------- /test/fixtures/executable/paths/folder3/file6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lukebayes/project-sprouts/6882d7309d617e35350749df84fac5e7d9c5e843/test/fixtures/executable/paths/folder3/file6 -------------------------------------------------------------------------------- /test/fixtures/executable/src/Main.as: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lukebayes/project-sprouts/6882d7309d617e35350749df84fac5e7d9c5e843/test/fixtures/executable/src/Main.as -------------------------------------------------------------------------------- /test/fixtures/executable/subclass/executable_subclass.rb: -------------------------------------------------------------------------------- 1 | 2 | class ExecutableSubclass < ExecutableSuperclass 3 | 4 | add_param :subclass_param, String 5 | end 6 | 7 | -------------------------------------------------------------------------------- /test/fixtures/executable/subclass/executable_superclass.rb: -------------------------------------------------------------------------------- 1 | 2 | class ExecutableSuperclass < Sprout::Executable::Base 3 | 4 | set :default_prefix, '---' 5 | 6 | add_param :superclass_param, String 7 | end 8 | 9 | -------------------------------------------------------------------------------- /test/fixtures/generators/song_generator.rb: -------------------------------------------------------------------------------- 1 | 2 | class SongGenerator < Sprout::Generator::Base 3 | ## 4 | # Set your favorite song name: 5 | add_param :favorite, String, { :default => 'Emerge' } 6 | 7 | ## 8 | # Define your generator directories, files and templates: 9 | def manifest 10 | template "#{favorite_cleaned}.txt", 'Song.txt' 11 | end 12 | 13 | protected 14 | 15 | # helper methods will be available to templates too: 16 | def favorite_cleaned 17 | favorite.gsub(' ', '').snake_case 18 | end 19 | end 20 | 21 | -------------------------------------------------------------------------------- /test/fixtures/generators/song_subclass/least_favorite.rb: -------------------------------------------------------------------------------- 1 | 2 | class LeastFavorite < SongGenerator 3 | 4 | def manifest 5 | directory 'sucky' do 6 | super 7 | end 8 | end 9 | end 10 | 11 | -------------------------------------------------------------------------------- /test/fixtures/generators/song_subclass/templates/Song.txt: -------------------------------------------------------------------------------- 1 | 2 | Your LEAST favorite song is '<%= favorite %>'! 3 | 4 | -------------------------------------------------------------------------------- /test/fixtures/generators/temp_generator.rb: -------------------------------------------------------------------------------- 1 | 2 | class TempGenerator < Sprout::Generator::Base 3 | 4 | add_param :source, String, { :default => 'src' } 5 | 6 | set :name, :demo 7 | set :pkg_name, 'temp_generator' 8 | set :pkg_version, '1.0.pre' 9 | 10 | def manifest 11 | directory input do 12 | directory source do 13 | template 'Main.as' 14 | end 15 | end 16 | end 17 | 18 | private 19 | 20 | def class_name 21 | input.camel_case 22 | end 23 | end 24 | 25 | -------------------------------------------------------------------------------- /test/fixtures/generators/templates/Main.as: -------------------------------------------------------------------------------- 1 | package { 2 | 3 | public class <%= class_name %> { 4 | 5 | public function <%= class_name %>() { 6 | } 7 | } 8 | } 9 | 10 | -------------------------------------------------------------------------------- /test/fixtures/generators/templates/OtherFileTemplate: -------------------------------------------------------------------------------- 1 | We are agents of the free. I've had my fun and now it's time to... 2 | -------------------------------------------------------------------------------- /test/fixtures/generators/templates/SomeFile: -------------------------------------------------------------------------------- 1 | I've got my spine, I've got my Orange Crush - <%= band_name %>. 2 | -------------------------------------------------------------------------------- /test/fixtures/generators/templates/SomeSubclassFile: -------------------------------------------------------------------------------- 1 | 2 | Living Jest enough for the City and <%= input.camel_case %>. 3 | -------------------------------------------------------------------------------- /test/fixtures/generators/templates/Song.txt: -------------------------------------------------------------------------------- 1 | 2 | Your favorite song is '<%= favorite %>'! 3 | 4 | -------------------------------------------------------------------------------- /test/fixtures/generators/templates/destroy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lukebayes/project-sprouts/6882d7309d617e35350749df84fac5e7d9c5e843/test/fixtures/generators/templates/destroy -------------------------------------------------------------------------------- /test/fixtures/generators/templates/generate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lukebayes/project-sprouts/6882d7309d617e35350749df84fac5e7d9c5e843/test/fixtures/generators/templates/generate -------------------------------------------------------------------------------- /test/fixtures/library/sources/lib/a/A.as: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lukebayes/project-sprouts/6882d7309d617e35350749df84fac5e7d9c5e843/test/fixtures/library/sources/lib/a/A.as -------------------------------------------------------------------------------- /test/fixtures/library/sources/lib/b/B.as: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lukebayes/project-sprouts/6882d7309d617e35350749df84fac5e7d9c5e843/test/fixtures/library/sources/lib/b/B.as -------------------------------------------------------------------------------- /test/fixtures/library/sources/src/Source.as: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lukebayes/project-sprouts/6882d7309d617e35350749df84fac5e7d9c5e843/test/fixtures/library/sources/src/Source.as -------------------------------------------------------------------------------- /test/fixtures/process_runner/chmod_script.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Hello World" 4 | -------------------------------------------------------------------------------- /test/fixtures/process_runner/dir with spaces/chmod_script.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Hello World" 4 | -------------------------------------------------------------------------------- /test/fixtures/process_runner/failure: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Write to stderr: 4 | echo 1>&2 "Failure" 5 | 6 | -------------------------------------------------------------------------------- /test/fixtures/process_runner/success: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Success" 4 | 5 | -------------------------------------------------------------------------------- /test/fixtures/remote_file_loader/md5/echochamber-test.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lukebayes/project-sprouts/6882d7309d617e35350749df84fac5e7d9c5e843/test/fixtures/remote_file_loader/md5/echochamber-test.zip -------------------------------------------------------------------------------- /test/fixtures/remote_file_loader/md5/file_with_known_md5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lukebayes/project-sprouts/6882d7309d617e35350749df84fac5e7d9c5e843/test/fixtures/remote_file_loader/md5/file_with_known_md5 -------------------------------------------------------------------------------- /test/fixtures/remote_file_target/bin/echochamber: -------------------------------------------------------------------------------- 1 | 2 | echo "ECHO ECHO ECHO $1" 3 | 4 | -------------------------------------------------------------------------------- /test/fixtures/remote_file_target/bin/echochamber.bat: -------------------------------------------------------------------------------- 1 | 2 | echo "ECHO ECHO ECHO $1" 3 | 4 | -------------------------------------------------------------------------------- /test/fixtures/remote_file_target/echochamber-test.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lukebayes/project-sprouts/6882d7309d617e35350749df84fac5e7d9c5e843/test/fixtures/remote_file_target/echochamber-test.zip -------------------------------------------------------------------------------- /test/fixtures/specification/asunit4.rb: -------------------------------------------------------------------------------- 1 | 2 | Sprout::Specification.new do |s| 3 | s.name = "asunit4" 4 | s.version = "4.2.pre" 5 | 6 | # Sprout Spec is no longer a wrapper to Gem::Specification... 7 | #s.authors = ["Luke Bayes", "Ali Mills", "Robert Penner"] 8 | #s.email = "asunit-users@lists.sourceforge.net" 9 | #s.homepage = "http://asunit.org" 10 | #s.summary = "The fastest and most flexible ActionScript unit test framework" 11 | #s.description = < :f_textlayout do |t| 20 | # t.input = 'src/SomeProject.as' 21 | # end 22 | # 23 | # If you'd like to consume one of the localized frameworks 24 | # you can set that up as follows: 25 | # 26 | # library 'flex_4_es_ES' 27 | # 28 | # mxmlc 'bin/SomeProject.swf' => 'flex_4_es_ES' do |t| 29 | # t.input = 'src/SomeProject.as' 30 | # end 31 | # 32 | s.name = 'flex4' 33 | s.version = '4.1.0.16076' 34 | 35 | s.add_remote_file_target do |t| 36 | t.platform = :universal 37 | t.archive_type = :zip 38 | t.url = "http://fpdownload.adobe.com/pub/flex/sdk/builds/flex4/flex_sdk_4.1.0.16076.zip" 39 | t.md5 = "4c5f3d3fa4e1f5be244679210cd852c0" 40 | 41 | # Executables: (add .exe suffix if it was passed in) 42 | t.add_executable :aasdoc, "bin/aasdoc" 43 | t.add_executable :acompc, "bin/acompc" 44 | t.add_executable :adl, "bin/adl" 45 | t.add_executable :adt, "bin/adt" 46 | t.add_executable :amxmlc, "bin/amxmlc" 47 | t.add_executable :asdoc, "bin/asdoc" 48 | t.add_executable :compc, "bin/compc" 49 | t.add_executable :copylocale, "bin/compc" 50 | t.add_executable :digest, "bin/digest" 51 | t.add_executable :fcsh, "bin/fcsh" 52 | t.add_executable :fdb, "bin/fdb" 53 | t.add_executable :mxmlc, "bin/mxmlc" 54 | t.add_executable :optimizer, "bin/optimizer" 55 | 56 | # Flex framework SWCs: 57 | t.add_library :flex, "frameworks/libs/flex.swc" 58 | t.add_library :flex4, "frameworks/libs/flex4.swc" 59 | t.add_library :f_textlayout, "frameworks/libs/framework_textLayout.swc" 60 | t.add_library :framework, "frameworks/libs/framework.swc" 61 | t.add_library :rpc, "frameworks/libs/rpc.swc" 62 | t.add_library :sparkskins, "frameworks/libs/sparkskins.swc" 63 | t.add_library :textlayout, "frameworks/libs/textLayout.swc" 64 | t.add_library :utilities, "frameworks/libs/utilities.swc" 65 | t.add_library :playerglobal_9, "frameworks/libs/player/9/playerglobal.swc" 66 | t.add_library :playerglobal_10, "frameworks/libs/player/10/playerglobal.swc" 67 | 68 | # AsDoc templates: 69 | t.add_library :asdoc_templates, "asdoc/templates" 70 | 71 | # Locale-Specific Flex SWCs: 72 | [ 73 | 'da_DK', 'de_DE', 'en_US', 'es_ES', 'fi_FL', 'fr_FR', 'it_IT', 'ja_JP', 74 | 'ko_KR', 'nb_NO', 'nl_NL', 'pt_BR', 'ru_RU', 'sv_SE', 'zh_CN', 'zh_TW' 75 | ].each do |locale| 76 | t.add_library "flex_4_#{locale}".to_sym, "frameworks/locale/#{locale}/flex4_rb.swc" 77 | t.add_library "airframework_#{locale}".to_sym, "frameworks/locale/#{locale}/airframework_rb.swc" 78 | t.add_library "framework_#{locale}".to_sym, "frameworks/locale/#{locale}/framework_rb.swc" 79 | t.add_library "rpc_#{locale}".to_sym, "frameworks/locale/#{locale}/rpc_rb.swc" 80 | end 81 | end 82 | end 83 | 84 | -------------------------------------------------------------------------------- /test/fixtures/specification/flexunit4.sproutspec: -------------------------------------------------------------------------------- 1 | 2 | Sprout::Specification.new do |s| 3 | s.name = "flexunit4" 4 | s.version = "4.0.pre" 5 | 6 | s.add_remote_file_target do |t| 7 | t.platform = :universal 8 | t.archive_type = :zip 9 | t.url = "http://digitalprimate.com/flexunit.zip" 10 | t.md5 = "abcd" 11 | 12 | t.add_library :swc, "primates/bin/FlexUnit.swc" 13 | t.add_library :src, "primates/dist" 14 | end 15 | 16 | end 17 | 18 | -------------------------------------------------------------------------------- /test/fixtures/specification/lib/as3reflection/Reflection.as: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lukebayes/project-sprouts/6882d7309d617e35350749df84fac5e7d9c5e843/test/fixtures/specification/lib/as3reflection/Reflection.as -------------------------------------------------------------------------------- /test/fixtures/specification/src/AsUnit.as: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lukebayes/project-sprouts/6882d7309d617e35350749df84fac5e7d9c5e843/test/fixtures/specification/src/AsUnit.as -------------------------------------------------------------------------------- /test/unit/archive_unpacker_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ArchiveUnpackerTest < Test::Unit::TestCase 4 | include Sprout::TestHelper 5 | 6 | def setup 7 | super 8 | fixture = File.join fixtures, 'archive_unpacker' 9 | @zip_file = File.join fixture, 'zip', 'some_file.zip' 10 | @zip_folder = File.join fixture, 'zip', 'some folder.zip' 11 | 12 | @tgz_file = File.join fixture, 'tgz', 'some_file.tgz' 13 | @tgz_folder = File.join fixture, 'tgz', 'some folder.tgz' 14 | 15 | @exe_file = File.join fixture, 'copyable', 'some_file.exe' 16 | @swc_file = File.join fixture, 'copyable', 'some_file.swc' 17 | @rb_file = File.join fixture, 'copyable', 'some_file.rb' 18 | 19 | @file_name = 'some_file.rb' 20 | 21 | @unpacker = Sprout::ArchiveUnpacker.new 22 | end 23 | 24 | context "an archive unpacker" do 25 | 26 | should "be identified as zip" do 27 | assert @unpacker.is_zip?("foo.zip"), "zip" 28 | assert !@unpacker.is_zip?("foo"), "not zip" 29 | end 30 | 31 | should "be identified as tgz" do 32 | assert @unpacker.is_tgz?("foo.tgz"), "tgz" 33 | assert @unpacker.is_tgz?("foo.tar.gz"), "tgz" 34 | assert !@unpacker.is_tgz?("foo"), "not tgz" 35 | end 36 | 37 | should "raise on unknown file types" do 38 | assert_raises Sprout::Errors::UnknownArchiveType do 39 | @unpacker.unpack 'SomeUnknowFileType', temp_path 40 | end 41 | end 42 | 43 | should "unpack zip on darwin specially" do 44 | as_a_mac_system do 45 | @unpacker.expects(:unpack_zip_on_darwin) 46 | @unpacker.unpack @zip_file, temp_path 47 | end 48 | end 49 | 50 | ['exe', 'swc', 'rb'].each do |format| 51 | should "copy #{format} files" do 52 | file = eval("@#{format}_file") 53 | assert @unpacker.unpack file, temp_path 54 | assert_file File.join(temp_path, File.basename(file)) 55 | end 56 | end 57 | 58 | ['zip', 'tgz'].each do |format| 59 | 60 | context "with a #{format} archive" do 61 | 62 | setup do 63 | @archive_file = eval("@#{format.gsub(/\./, '')}_file") 64 | @archive_folder = eval("@#{format.gsub(/\./, '')}_folder") 65 | end 66 | 67 | should "fail with missing file" do 68 | assert_raises Sprout::Errors::ArchiveUnpackerError do 69 | @unpacker.unpack "SomeUnknownFile.#{format}", temp_path 70 | end 71 | end 72 | 73 | should "fail with missing destination" do 74 | assert_raises Sprout::Errors::ArchiveUnpackerError do 75 | @unpacker.unpack @archive_file, "SomeInvalidDestination" 76 | end 77 | end 78 | 79 | should "unpack a single archive" do 80 | expected_file = File.join temp_path, @file_name 81 | 82 | @unpacker.unpack @archive_file, temp_path 83 | assert_file expected_file 84 | assert_matches /hello world/, File.read(expected_file) 85 | end 86 | 87 | should "clobber existing files if necessary" do 88 | expected_file = File.join temp_path, @file_name 89 | FileUtils.touch expected_file 90 | 91 | as_a_windows_system do 92 | @unpacker.unpack @archive_file, temp_path, nil, :clobber 93 | assert_file expected_file 94 | assert_matches /hello world/, File.read(expected_file) 95 | end 96 | end 97 | 98 | should "not clobber if not told to do so" do 99 | expected_file = File.join temp_path, @file_name 100 | FileUtils.touch expected_file 101 | 102 | as_a_windows_system do 103 | assert_raises Sprout::Errors::DestinationExistsError do 104 | @unpacker.unpack @archive_file, temp_path, nil, :no_clobber 105 | end 106 | end 107 | end 108 | 109 | should "unpack a nested archive" do 110 | expected_file = File.join temp_path, 'some folder', 'child folder', 'child child folder', @file_name 111 | 112 | as_a_windows_system do 113 | @unpacker.unpack @archive_folder, temp_path 114 | assert_file expected_file 115 | assert_matches /hello world/, File.read(expected_file) 116 | end 117 | end 118 | end 119 | end 120 | end 121 | end 122 | 123 | -------------------------------------------------------------------------------- /test/unit/boolean_param_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class BooleanParamTest < Test::Unit::TestCase 4 | include Sprout::TestHelper 5 | 6 | context "a new, simple BooleanParam" do 7 | 8 | setup do 9 | @param = Sprout::Executable::Boolean.new 10 | @param.name = 'foo' 11 | end 12 | 13 | should "be hidden when false" do 14 | @param.value = false 15 | assert_equal '', @param.to_shell 16 | end 17 | 18 | should "default to false" do 19 | assert_equal false, @param.value 20 | end 21 | 22 | should "show on true" do 23 | @param.value = true 24 | assert_equal '--foo', @param.to_shell 25 | end 26 | 27 | context "when configuring option parser" do 28 | 29 | should "update correctly" do 30 | @param.show_on_false = true 31 | @param.default = true 32 | @param.hidden_value = false 33 | assert_equal "--[no-]foo [BOOL]", @param.option_parser_declaration 34 | end 35 | 36 | should "not insert [no] param modifier unless default true" do 37 | @param.name = 'something_off' 38 | assert_equal "--something-off", @param.option_parser_declaration 39 | end 40 | end 41 | end 42 | end 43 | 44 | -------------------------------------------------------------------------------- /test/unit/command_line_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class CommandLineTest < Test::Unit::TestCase 4 | include Sprout::TestHelper 5 | 6 | context "a new command line ui" do 7 | 8 | setup do 9 | @logger = Sprout::OutputBuffer.new 10 | @instance = Sprout::CommandLine.new 11 | @instance.logger = @logger 12 | end 13 | 14 | should "display the version number" do 15 | @instance.parse! ['--version'] 16 | @instance.execute 17 | assert_matches /sprout #{Sprout::VERSION::STRING}/, @logger.read 18 | end 19 | 20 | should "display helper if no options provided" do 21 | @instance.expects :abort 22 | @instance.parse! [] 23 | end 24 | end 25 | end 26 | 27 | 28 | -------------------------------------------------------------------------------- /test/unit/executable_option_parser_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | require 'fixtures/examples/echo_inputs' 3 | 4 | class ExecutableOptionParserTest < Test::Unit::TestCase 5 | include Sprout::TestHelper 6 | 7 | context "a new ruby executable" do 8 | 9 | setup do 10 | @exe = EchoInputs.new 11 | @exe.abort_on_failure = false 12 | @default_input = '--input=lib/sprout.rb' 13 | end 14 | 15 | should "fail without required args" do 16 | assert_raises Sprout::Errors::MissingArgumentError do 17 | @exe.parse! [] 18 | end 19 | end 20 | 21 | should "accept required args" do 22 | @exe.parse! [ @default_input ] 23 | assert_equal 'lib/sprout.rb', @exe.input 24 | end 25 | 26 | should "accept boolean with hidden_value" do 27 | assert !@exe.truthy 28 | @exe.parse! [ '--truthy', @default_input ] 29 | assert @exe.truthy 30 | end 31 | 32 | should "accept long boolean with hidden_value" do 33 | assert !@exe.long_truthy 34 | @exe.parse! [ '--long-truthy', @default_input ] 35 | assert @exe.long_truthy 36 | end 37 | 38 | should "accept negative truthy" do 39 | assert @exe.default_truthy, "Should default true" 40 | @exe.parse! [ '--no-default-truthy', @default_input ] 41 | assert !@exe.default_truthy, "Should accept no- prefix" 42 | end 43 | 44 | should "always accept help option" do 45 | @exe.expects :abort 46 | assert_raises Sprout::Errors::MissingArgumentError do 47 | @exe.parse! [ '--help' ] 48 | end 49 | end 50 | 51 | should "accept false boolean" do 52 | assert @exe.falsey, "Should be true by default" 53 | @exe.parse! [@default_input, '--falsey=false'] 54 | assert !@exe.falsey, "Should be false" 55 | end 56 | 57 | should "accept string" do 58 | @exe.parse! [@default_input, '--string=abcd'] 59 | assert_equal 'abcd', @exe.string 60 | end 61 | 62 | should "accept file" do 63 | @exe.parse! [@default_input, '--file=lib/sprout.rb'] 64 | assert_equal 'lib/sprout.rb', @exe.file 65 | end 66 | 67 | should "accept files" do 68 | @exe.parse! [@default_input, '--files+=lib/sprout.rb', '--files+=lib/sprout/log.rb'] 69 | assert_equal ['lib/sprout.rb', 'lib/sprout/log.rb'], @exe.files 70 | end 71 | 72 | # TODO: This might not be correct behavior... 73 | should "accept files with equal sign delimiter" do 74 | @exe.parse! [@default_input, '--files=lib/sprout.rb', '--files=lib/sprout/log.rb'] 75 | assert_equal ['lib/sprout.rb', 'lib/sprout/log.rb'], @exe.files 76 | end 77 | 78 | # TODO: Not sure what's going on here... 79 | should "configure required arguments" do 80 | @exe.parse! [@default_input, @default_input] 81 | assert_equal 'lib/sprout.rb', @exe.input 82 | end 83 | 84 | # TODO: This test ensures that the commandline description 85 | # is pulled from the provided RDocs - but this turns out 86 | # to be more work than I'm prepared to take on at the moment. 87 | # 88 | #should "use rdoc to assign parameter documentation" do 89 | #skip "Not yet ready to integrate rdoc comments" 90 | #doc = "A boolean parameter that defaults to true, and must be explicitly set to false in order to turn it off." 91 | #assert_matches /#{doc}/, @exe.to_help 92 | #end 93 | 94 | should "fail without required param" do 95 | assert_raises Sprout::Errors::MissingArgumentError do 96 | @exe.parse! [] 97 | end 98 | end 99 | 100 | should "fail with incorrect param" do 101 | assert_raises Sprout::Errors::InvalidArgumentError do 102 | @exe.parse! ['--input=lib/unknown_file.rb'] 103 | end 104 | end 105 | 106 | context "with an unknown option" do 107 | should "throw an exception" do 108 | assert_raises OptionParser::InvalidOption do 109 | @exe.parse! [ '--unknown-param', @default_input ] 110 | end 111 | end 112 | 113 | should "abort and display help" do 114 | @exe.abort_on_failure = true 115 | @exe.expects :abort 116 | @exe.parse! [ '--unknown-param', @default_input ] 117 | end 118 | end 119 | 120 | context "with a hidden name" do 121 | 122 | # Define the class in a place 123 | # where only these tests can use it. 124 | class SomeExecutable < Sprout::Executable::Base 125 | add_param :debug, Boolean 126 | add_param :input, String, { :hidden_name => true } 127 | end 128 | 129 | setup do 130 | @exe = SomeExecutable.new 131 | end 132 | 133 | should "accept a value at the end" do 134 | @exe.parse! ['--debug', 'SomeString'] 135 | assert @exe.debug 136 | assert_equal 'SomeString', @exe.input 137 | end 138 | 139 | =begin 140 | TODO: Get these passing... 141 | 142 | should "fail if multiple values provided for a singular param" do 143 | skip "not yet implemented" 144 | end 145 | 146 | should "accept multiple values for collection param" do 147 | skip "not yet implemented" 148 | end 149 | =end 150 | end 151 | end 152 | end 153 | 154 | -------------------------------------------------------------------------------- /test/unit/executable_param_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ExecutableParamTest < Test::Unit::TestCase 4 | include Sprout::TestHelper 5 | 6 | context "a new, simple Executable::Param" do 7 | 8 | setup do 9 | @param = Sprout::Executable::Param.new 10 | end 11 | 12 | should "be invisible until value set" do 13 | assert !@param.visible? 14 | end 15 | 16 | should "return empty string with no value" do 17 | assert_equal '', @param.to_shell 18 | end 19 | 20 | should "raise if required and nil" do 21 | @param.required = true 22 | assert_raises Sprout::Errors::MissingArgumentError do 23 | @param.to_shell 24 | end 25 | end 26 | 27 | context "with simple values" do 28 | 29 | setup do 30 | @param.name = :foo 31 | @param.value = 'bar' 32 | end 33 | 34 | should "not raise if required and has value" do 35 | @param.required = true 36 | assert @param.to_shell 37 | end 38 | 39 | should "accept a name and value" do 40 | assert_equal '--foo=bar', @param.to_shell 41 | end 42 | 43 | should "accept space delimiter" do 44 | @param.delimiter = ' ' 45 | assert_equal '--foo bar', @param.to_shell 46 | end 47 | 48 | should "accept arbitrary delimiter" do 49 | @param.delimiter = ' ||= ' 50 | assert_equal '--foo ||= bar', @param.to_shell 51 | end 52 | 53 | should "accept empty prefix" do 54 | @param.prefix = '' 55 | assert_equal 'foo=bar', @param.to_shell 56 | end 57 | 58 | should "accept arbitrary prefix" do 59 | @param.prefix = '++++' 60 | assert_equal '++++foo=bar', @param.to_shell 61 | end 62 | 63 | should "accept hidden_name attribute" do 64 | @param.hidden_name = true 65 | assert_equal 'bar', @param.to_shell 66 | end 67 | 68 | should "accept hidden_value attribute" do 69 | @param.hidden_value = true 70 | assert_equal '--foo', @param.to_shell 71 | end 72 | 73 | end 74 | end 75 | end 76 | 77 | -------------------------------------------------------------------------------- /test/unit/executable_session_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | require 'fixtures/executable/fdb' 3 | 4 | class ExecutableSessionTest < Test::Unit::TestCase 5 | include Sprout::TestHelper 6 | 7 | context "a new executable session" do 8 | 9 | setup do 10 | # Uncomment the following to see interactive sessions: 11 | #Sprout.stdout = $stdout 12 | #Sprout.stderr = $stderr 13 | @test_result_file = File.join fixtures, 'executable', 'Result.xml' 14 | end 15 | 16 | teardown do 17 | remove_file @test_result_file 18 | end 19 | 20 | should "execute without shell params" do 21 | @fdb = Sprout::FDB.new 22 | # Comment to hit real FDB: 23 | @fdb.binary_path = File.join fixtures, 'executable', 'flex3sdk_gem', 'fdb' 24 | @fdb.test_result_file = @test_result_file 25 | 26 | @fdb.execute false 27 | @fdb.run 28 | 29 | # Uncomment if you are on OSX and want to 30 | # test the real FDB while running a real SWF: 31 | #Kernel.system 'open ~/Projects/Sprouts/flashsdk/test/fixtures/flashplayer/AsUnit\ Runner.swf' 32 | #@fdb.wait_for_prompt 33 | 34 | @fdb.break "AsUnitRunner:12" 35 | 36 | @fdb.continue 37 | #@fdb.continue 38 | 39 | #@fdb.handle_user_input 40 | @fdb.quit 41 | 42 | assert_file @test_result_file do |content| 43 | assert_match content, /Fake Content/ 44 | end 45 | end 46 | 47 | end 48 | 49 | end 50 | 51 | -------------------------------------------------------------------------------- /test/unit/fake_executable_task.rb: -------------------------------------------------------------------------------- 1 | 2 | class FakeExecutableTask 3 | attr_accessor :output 4 | attr_accessor :default_prefix 5 | attr_accessor :default_short_prefix 6 | 7 | def initialize 8 | super 9 | @output = 'fake_tool' 10 | @default_prefix = '-' 11 | @default_short_prefix = '--' 12 | end 13 | 14 | def default_file_expression 15 | @default_file_expression ||= '/**/**/*' 16 | end 17 | 18 | def prerequisites 19 | @prerequisites ||= [] 20 | end 21 | end 22 | 23 | -------------------------------------------------------------------------------- /test/unit/fake_other_executable.rb: -------------------------------------------------------------------------------- 1 | 2 | class CustomFakeParameter < Sprout::Executable::StringParam; end 3 | 4 | class FakeOtherExecutableTask < Sprout::Executable::Base 5 | 6 | add_param :boolean_param, Boolean 7 | add_param :custom_param, CustomFakeParameter 8 | add_param :file_param, File 9 | add_param :files_param, Files 10 | add_param :number_param, Number 11 | add_param :path_param, Path 12 | add_param :paths_param, Paths 13 | add_param :string_param, String 14 | add_param :strings_param, Strings 15 | add_param :urls_param, Urls 16 | 17 | set :default_prefix, '---' 18 | 19 | add_param_alias :sp, :strings_param 20 | end 21 | 22 | -------------------------------------------------------------------------------- /test/unit/fake_process_runner.rb: -------------------------------------------------------------------------------- 1 | 2 | class FakeProcessRunner 3 | 4 | attr_accessor :command 5 | 6 | def initialize 7 | @r = FakeIO.new 8 | @w = FakeIO.new 9 | @e = FakeIO.new 10 | end 11 | 12 | def execute_open4 *command 13 | @command = command 14 | end 15 | 16 | def read 17 | @r 18 | end 19 | 20 | def read_err 21 | @e 22 | end 23 | 24 | def write value 25 | @w.write value 26 | end 27 | 28 | end 29 | 30 | -------------------------------------------------------------------------------- /test/unit/file_param_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class FileParamTest < Test::Unit::TestCase 4 | include Sprout::TestHelper 5 | 6 | context "a new FileParam" do 7 | 8 | setup do 9 | @input_with_spaces = File.join(fixtures, "executable", "path with spaces", "input.as") 10 | @input_with_spaces.gsub!(Dir.pwd + File::SEPARATOR, '') 11 | @input_with_escaped_spaces = @input_with_spaces.gsub(' ', '\ ') 12 | @input_with_quoted_spaces = "#{@input_with_spaces.gsub('/', '\\')}" 13 | 14 | @input = File.join(fixtures, "executable", "params", "input.as") 15 | 16 | @tool = FakeExecutableTask.new 17 | 18 | @param = Sprout::Executable::FileParam.new 19 | @param.belongs_to = @tool 20 | @param.name = 'input' 21 | @param.value = @input 22 | end 23 | 24 | should "clean the path for each system" do 25 | as_each_system do |sys| 26 | @param.expects(:validate) 27 | # Ensure that system.clean_path is called 28 | @param.value = @input_with_spaces 29 | @param.prepare 30 | assert_equal "-input=#{sys.clean_path(@input_with_spaces)}", @param.to_shell 31 | end 32 | end 33 | 34 | should "include file path in shell output" do 35 | as_each_system do |sys| 36 | assert_equal "-input=#{sys.clean_path(@input)}", @param.to_shell 37 | end 38 | end 39 | 40 | should "add file as prerequisite to parent" do 41 | assert_equal 0, @tool.prerequisites.size 42 | @param.prepare 43 | assert_equal 1, @tool.prerequisites.size 44 | end 45 | 46 | should "not add prerequisite that matches output of parent" do 47 | @tool.output = :abcd 48 | @param.value = "abcd" 49 | @param.prepare 50 | assert_equal 0, @tool.prerequisites.size 51 | end 52 | 53 | should "raise if the file doesn't exist when asked for output" do 54 | @param.value = 'unknown file' 55 | assert_raises Sprout::Errors::InvalidArgumentError do 56 | @param.to_shell 57 | end 58 | end 59 | end 60 | end 61 | 62 | -------------------------------------------------------------------------------- /test/unit/file_target_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class FileTargetTest < Test::Unit::TestCase 4 | include Sprout::TestHelper 5 | 6 | context "a file target" do 7 | setup do 8 | @asunit_swc = 'bin/AsUnit4-4.1.pre.swc' 9 | end 10 | 11 | context "that is created with a constructor block" do 12 | should "have the provided values" do 13 | target = Sprout::FileTarget.new do |t| 14 | t.pkg_name = 'asunit4' 15 | t.pkg_version = '4.2.2.pre' 16 | t.add_library :swc, @asunit_swc 17 | end 18 | assert_provided_values target 19 | end 20 | end 21 | 22 | context "that is created with no constructor block" do 23 | should "have the provided values" do 24 | target = Sprout::FileTarget.new 25 | target.pkg_name = 'asunit4' 26 | target.pkg_version = '4.2.2.pre' 27 | target.add_library :swc, @asunit_swc 28 | assert_provided_values target 29 | end 30 | end 31 | 32 | end 33 | 34 | private 35 | 36 | def assert_provided_values t 37 | assert_equal :universal, t.platform 38 | assert_equal 0, t.executables.size 39 | assert_equal 1, t.libraries.size 40 | library = t.libraries.first 41 | assert_equal :swc, library.name 42 | assert_equal File.join('.', @asunit_swc), library.path 43 | assert_equal '[FileTarget pkg_name=asunit4 pkg_version=4.2.2.pre platform=universal]', t.to_s 44 | end 45 | 46 | end 47 | 48 | -------------------------------------------------------------------------------- /test/unit/files_param_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class FilesParamTest < Test::Unit::TestCase 4 | include Sprout::TestHelper 5 | 6 | context "a new FilesParam" do 7 | 8 | setup do 9 | @input1 = File.join(fixtures, "executable", "params", "input.as") 10 | @input2 = File.join(fixtures, "executable", "params", "input2.as") 11 | @input3 = File.join(fixtures, "executable", "params", "input3.as") 12 | 13 | @input4 = File.join(fixtures, "executable", "path with spaces", "input.as") 14 | @input5 = File.join(fixtures, "executable", "path with spaces", "input2.as") 15 | @input6 = File.join(fixtures, "executable", "path with spaces", "input3.as") 16 | 17 | @param = Sprout::Executable::Files.new 18 | @param.name = 'inputs' 19 | @param.belongs_to = FakeExecutableTask.new 20 | end 21 | 22 | ['abcd', 1234, true].each do |value| 23 | should "throw with non-enumerable assignment of #{value}" do 24 | assert_raises Sprout::Errors::ExecutableError do 25 | @param.value = value 26 | end 27 | end 28 | end 29 | 30 | should "allow assignment of enumerables" do 31 | @param.value = ['abcd', 'efgh'] 32 | end 33 | 34 | should "allow concatenation on first access" do 35 | @param.value << 'abcd' 36 | end 37 | 38 | should "clean each path provided" do 39 | # Ensure order is retained: 40 | @param.value << @input3 41 | @param.value << @input2 42 | @param.value << @input1 43 | 44 | as_each_system do |sys| 45 | assert_equal "-inputs+=#{sys.clean_path(@input3)} -inputs+=#{sys.clean_path(@input2)} -inputs+=#{sys.clean_path(@input1)}", @param.to_shell, "As a #{sys}" 46 | end 47 | end 48 | 49 | should "clean paths with spaces" do 50 | @param.value << @input6 51 | @param.value << @input5 52 | @param.value << @input4 53 | 54 | as_each_system do |sys| 55 | assert_equal "-inputs+=#{sys.clean_path(@input6)} -inputs+=#{sys.clean_path(@input5)} -inputs+=#{sys.clean_path(@input4)}", @param.to_shell, "As a #{sys}" 56 | end 57 | end 58 | 59 | should "defer to to_shell_proc if provided" do 60 | @param.to_shell_proc = Proc.new { |param| 61 | "proc:#{param.name}:#{param.value.shift}" 62 | } 63 | 64 | @param.value << 'abcd' 65 | 66 | assert @param.visible?, "Should be visible" 67 | assert_equal 'proc:inputs:abcd', @param.to_shell 68 | end 69 | 70 | end 71 | end 72 | 73 | -------------------------------------------------------------------------------- /test/unit/generator_generator_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | require 'sprout/generators/generator/generator_generator' 4 | 5 | class GeneratorGeneratorTest < Test::Unit::TestCase 6 | include Sprout::TestHelper 7 | 8 | context "A new generator generator" do 9 | 10 | setup do 11 | @temp = File.join(fixtures, 'generators', 'tmp') 12 | FileUtils.mkdir_p @temp 13 | @generator = Sprout::GeneratorGenerator.new 14 | @generator.path = @temp 15 | @generator.logger = StringIO.new 16 | end 17 | 18 | teardown do 19 | remove_file @temp 20 | end 21 | 22 | ['TestClassGenerator', 'test_class_generator', 'test_class', 'TestClass'].each do |input| 23 | 24 | should "massage '#{input}' into appropriate value" do 25 | @generator.input = "TestClassGenerator" 26 | @generator.execute 27 | 28 | test_file = File.join(@temp, 'test', 'unit', 'test_class_generator_test.rb') 29 | assert_file test_file do |content| 30 | assert_matches /TestClassGeneratorTest/, content 31 | end 32 | end 33 | end 34 | 35 | should "generate a new generator" do 36 | @generator.input = 'fwee' 37 | @generator.execute 38 | 39 | lib_dir = File.join(@temp, 'lib') 40 | assert_directory lib_dir 41 | 42 | test_dir = File.join(@temp, 'test') 43 | assert_directory test_dir 44 | 45 | #TODO: This should be generated by the library creator 46 | # vendor_dir = File.join(@temp, 'vendor') 47 | # assert_directory vendor_dir 48 | 49 | fixtures_dir = File.join(test_dir, 'fixtures', 'generators') 50 | assert_directory fixtures_dir 51 | 52 | test_file = File.join(test_dir, 'unit', 'fwee_generator_test.rb') 53 | assert_file test_file do |content| 54 | assert_matches /FweeGeneratorTest/, content 55 | end 56 | 57 | test_helper_file = File.join(test_dir, 'unit', 'test_helper.rb') 58 | assert_file test_helper_file 59 | 60 | generators_dir = File.join(lib_dir, 'generators') 61 | assert_directory generators_dir 62 | 63 | generator_file = File.join(generators_dir, 'fwee_generator.rb') 64 | assert_file generator_file 65 | 66 | templates_dir = File.join(generators_dir, 'templates') 67 | assert_directory templates_dir 68 | 69 | template_file = File.join(templates_dir, 'Fwee.as') 70 | assert_file template_file 71 | 72 | bin_dir = File.join(@temp, 'bin') 73 | assert_directory bin_dir 74 | 75 | executable_file = File.join(bin_dir, 'fwee') 76 | assert_file executable_file 77 | 78 | end 79 | 80 | should 'generate a new generator in a namespaced directory' do 81 | @generator.input = 'fwi' 82 | @generator.namespace = 'sigmund' 83 | @generator.execute 84 | 85 | lib_dir = File.join(@temp, 'lib') 86 | assert_directory lib_dir 87 | 88 | namespace_dir = File.join(lib_dir, 'sigmund') 89 | assert_directory namespace_dir 90 | 91 | generator_dir = File.join(namespace_dir, 'generators') 92 | assert_directory generator_dir 93 | 94 | end 95 | 96 | end 97 | end 98 | 99 | -------------------------------------------------------------------------------- /test/unit/library_generator_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | require 'sprout/generators/library/library_generator' 3 | 4 | class LibraryGeneratorTest < Test::Unit::TestCase 5 | include Sprout::TestHelper 6 | 7 | context "A generated library" do 8 | 9 | setup do 10 | @temp = File.join(fixtures, 'generators', 'library') 11 | FileUtils.mkdir_p @temp 12 | @generator = Sprout::LibraryGenerator.new 13 | @generator.path = @temp 14 | @generator.logger = StringIO.new 15 | end 16 | 17 | teardown do 18 | remove_file @temp 19 | end 20 | 21 | should "generate a new library" do 22 | @generator.input = 'flexunit' 23 | @generator.version = '4.2.pre' 24 | @generator.execute 25 | 26 | assert_file File.join(@temp, 'flexunit.gemspec') do |content| 27 | assert_matches /s.name\s+= Flexunit::NAME/, content 28 | assert_matches /s.version\s+= Flexunit::VERSION/, content 29 | assert_matches /s.author\s+= "Your Name"/, content 30 | end 31 | 32 | assert_file File.join(@temp, 'flexunit.rb') do |content| 33 | assert_matches /NAME\s+= 'flexunit'/, content 34 | assert_matches /VERSION\s+= '4.2.pre'/, content 35 | end 36 | end 37 | 38 | end 39 | end 40 | 41 | -------------------------------------------------------------------------------- /test/unit/library_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class LibraryTest < Test::Unit::TestCase 4 | include Sprout::TestHelper 5 | 6 | context "a new archive library" do 7 | setup do 8 | @path = File.join fixtures, 'library', 'archive' 9 | @archive = File.join @path, 'Archive.swc' 10 | create_and_register_library :fake_archive_lib, :swc, @archive 11 | end 12 | 13 | should "be able to load registered libraries" do 14 | lib = Sprout::Library.load :swc, :fake_archive_lib 15 | assert_not_nil lib 16 | end 17 | end 18 | 19 | context "a new precompiled library" do 20 | setup do 21 | fixture = File.join fixtures, 'library' 22 | @lib_dir = File.join fixture, 'project_lib' 23 | sources = File.join fixture, 'sources' 24 | @src = File.join sources, 'src', 'Source.as' 25 | 26 | Sprout::Library.any_instance.stubs(:project_path).returns @lib_dir 27 | create_and_register_library :fake_swc_lib, :swc, @src 28 | end 29 | 30 | should "create rake file tasks for single files" do 31 | Sprout::Library.define_task :swc, :fake_swc_lib 32 | end 33 | end 34 | 35 | context "a new source library" do 36 | setup do 37 | fixture = File.join fixtures, 'library' 38 | @lib_dir = File.join fixture, 'project_lib' 39 | sources = File.join fixture, 'sources' 40 | @lib_a = File.join sources, 'lib', 'a' 41 | @lib_b = File.join sources, 'lib', 'b' 42 | @src = File.join sources, 'src' 43 | Sprout::Library.any_instance.stubs(:project_path).returns @lib_dir 44 | create_and_register_library :fake_source_lib, :src, [@src, @lib_a, @lib_b] 45 | end 46 | 47 | teardown do 48 | remove_file @lib_dir 49 | end 50 | 51 | should "be able to load registered libraries" do 52 | lib = Sprout::Library.load :src, :fake_source_lib 53 | assert_not_nil lib 54 | paths = lib.path.dup 55 | assert_equal @src, paths.shift 56 | assert_equal @lib_a, paths.shift 57 | assert_equal @lib_b, paths.shift 58 | end 59 | 60 | should "create rake file tasks for directories" do 61 | Sprout::Library.define_task :src, :fake_source_lib 62 | Rake::application[:resolve_sprout_libraries].invoke 63 | 64 | library_dir = File.join(@lib_dir, 'fake_source_lib') 65 | assert_file library_dir 66 | assert_file File.join(library_dir, 'Source.as') 67 | assert_file File.join(library_dir, 'a') 68 | assert_file File.join(library_dir, 'b') 69 | end 70 | 71 | should "create rake tasks for libraries" do 72 | library :fake_source_lib 73 | assert_not_nil Rake.application[:fake_source_lib] 74 | end 75 | end 76 | 77 | private 78 | 79 | def create_and_register_library pkg_name, name, path, pkg_version=nil 80 | lib = Sprout::Library.new 81 | lib.name = name 82 | lib.path = path 83 | lib.pkg_name = pkg_name unless pkg_name.nil? 84 | lib.pkg_version = pkg_version unless pkg_version.nil? 85 | Sprout::Library.register lib 86 | end 87 | end 88 | 89 | -------------------------------------------------------------------------------- /test/unit/osx_system_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class OSXSystemTest < Test::Unit::TestCase 4 | include Sprout::TestHelper 5 | 6 | context "new osx system" do 7 | 8 | setup do 9 | @user = Sprout::System::OSXSystem.new 10 | @user.stubs(:home).returns '/Users/someone' 11 | end 12 | 13 | should "capitalize application name" do 14 | File.stubs(:exists?).returns true 15 | assert_equal '/Users/someone/Library/Sprouts', @user.application_home('sprouts') 16 | end 17 | 18 | end 19 | end 20 | 21 | -------------------------------------------------------------------------------- /test/unit/path_param_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class PathParamTest < Test::Unit::TestCase 4 | include Sprout::TestHelper 5 | 6 | context "a new PathParam" do 7 | 8 | setup do 9 | @path1 = File.join(fixtures, 'executable', 'paths', 'folder1') 10 | 11 | @param = Sprout::Executable::Path.new 12 | @param.belongs_to = FakeExecutableTask.new 13 | @param.name = 'path' 14 | end 15 | 16 | should "accept a collection of paths" do 17 | @param.value = @path1 18 | 19 | assert_equal "-path=#{@path1}", @param.to_shell 20 | # All child files have been added as prerequisites: 21 | assert_equal 3, @param.belongs_to.prerequisites.size 22 | end 23 | 24 | should "accept a custom file expression" do 25 | @param.file_expression = "file2" 26 | @param.value = @path1 27 | assert_equal "-path=#{@path1}", @param.to_shell 28 | # All child files have been added as prerequisites: 29 | assert_equal 1, @param.belongs_to.prerequisites.size 30 | end 31 | 32 | should "accept hidden_name parameter" do 33 | @param.hidden_name = true 34 | @param.value = @path1 35 | assert_equal @path1, @param.to_shell 36 | # All child files have been added as prerequisites: 37 | assert_equal 3, @param.belongs_to.prerequisites.size 38 | end 39 | 40 | end 41 | end 42 | 43 | 44 | -------------------------------------------------------------------------------- /test/unit/paths_param_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class PathsParamTest < Test::Unit::TestCase 4 | include Sprout::TestHelper 5 | 6 | context "a new PathsParam" do 7 | 8 | setup do 9 | @path1 = File.join(fixtures, 'executable', 'paths', 'folder1') 10 | @path2 = File.join(fixtures, 'executable', 'paths', 'folder2') 11 | @path3 = File.join(fixtures, 'executable', 'paths', 'folder3') 12 | 13 | @param = Sprout::Executable::Paths.new 14 | @param.belongs_to = FakeExecutableTask.new 15 | @param.name = 'paths' 16 | end 17 | 18 | should "accept a collection of paths" do 19 | @param.value << @path1 20 | @param.value << @path2 21 | @param.value << @path3 22 | 23 | as_each_system do |sys| 24 | assert_equal "-paths+=#{sys.clean_path(@path1)} -paths+=#{sys.clean_path(@path2)} -paths+=#{sys.clean_path(@path3)}", @param.to_shell 25 | end 26 | 27 | # All child files have been added as prerequisites: 28 | assert_equal 6, @param.belongs_to.prerequisites.size 29 | end 30 | 31 | should "accept a custom file expression" do 32 | @param.file_expression = "file2" 33 | @param.value << @path1 34 | 35 | as_each_system do |sys| 36 | assert_equal "-paths+=#{sys.clean_path(@path1)}", @param.to_shell 37 | end 38 | 39 | # All child files have been added as prerequisites: 40 | assert_equal 1, @param.belongs_to.prerequisites.size 41 | end 42 | 43 | should "accept hidden_name parameter" do 44 | @param.hidden_name = true 45 | @param.value << @path1 46 | assert_equal @path1, @param.to_shell 47 | # All child files have been added as prerequisites: 48 | assert_equal 3, @param.belongs_to.prerequisites.size 49 | end 50 | 51 | end 52 | end 53 | 54 | -------------------------------------------------------------------------------- /test/unit/platform_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class PlatformTest < Test::Unit::TestCase 4 | include Sprout::TestHelper 5 | 6 | context "platform" do 7 | 8 | setup do 9 | @platform = Sprout::Platform.new 10 | end 11 | 12 | ['cygwin', 'mingw', 'bccwin'].each do |variant| 13 | context variant do 14 | should "know if they're windows nix" do 15 | @platform.stubs(:ruby_platform).returns variant 16 | assert @platform.windows?, "Windows?" 17 | assert @platform.windows_nix?, "Windows Nix?" 18 | assert !@platform.java?, "Java?" 19 | assert !@platform.mac?, "Mac?" 20 | assert !@platform.unix?, "Unix?" 21 | assert !@platform.linux?, "Linux?" 22 | end 23 | end 24 | end 25 | 26 | ['vista', 'mswin', 'wince', 'emx'].each do |variant| 27 | context variant do 28 | should "know if they're windows" do 29 | @platform.stubs(:ruby_platform).returns variant 30 | assert @platform.windows?, "Windows?" 31 | assert !@platform.java?, "Java?" 32 | assert !@platform.mac?, "Mac?" 33 | assert !@platform.unix?, "Unix?" 34 | assert !@platform.windows_nix?, "Windows Nix?" 35 | assert !@platform.linux?, "Linux?" 36 | end 37 | end 38 | end 39 | 40 | ['solaris', 'redhat', 'ubuntu'].each do |variant| 41 | context variant do 42 | should "know if they're unix" do 43 | @platform.stubs(:ruby_platform).returns variant 44 | assert @platform.unix?, "Unix?" 45 | assert @platform.linux?, "Linux?" 46 | assert !@platform.java?, "Java?" 47 | assert !@platform.windows?, "Windows?" 48 | assert !@platform.mac?, "Mac?" 49 | assert !@platform.windows_nix?, "Windows Nix?" 50 | end 51 | end 52 | end 53 | 54 | should "know if they're java" do 55 | @platform.stubs(:ruby_platform).returns "java" 56 | assert @platform.java?, "Java?" 57 | assert !@platform.mac?, "Mac?" 58 | assert !@platform.unix?, "Unix?" 59 | assert !@platform.windows?, "Windows?" 60 | assert !@platform.windows_nix?, "Windows Nix?" 61 | assert !@platform.linux?, "Linux?" 62 | end 63 | 64 | should "know if they're mac" do 65 | @platform.stubs(:ruby_platform).returns "darwin" 66 | assert @platform.mac?, "Mac?" 67 | assert @platform.unix?, "Unix?" 68 | assert !@platform.java?, "Java?" 69 | assert !@platform.windows?, "Windows?" 70 | assert !@platform.windows_nix?, "Windows Nix?" 71 | assert !@platform.linux?, "Linux?" 72 | end 73 | 74 | end 75 | end 76 | 77 | -------------------------------------------------------------------------------- /test/unit/process_runner_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ProcessRunnerTest < Test::Unit::TestCase 4 | include Sprout::TestHelper 5 | 6 | context "process runner" do 7 | 8 | setup do 9 | @fixture = File.expand_path File.join(fixtures, 'process_runner') 10 | @script = File.join @fixture, 'chmod_script.sh' 11 | @script_with_spaces = File.join @fixture, 'dir with spaces', 'chmod_script.sh' 12 | 13 | pid = nil 14 | write = StringIO.new 15 | read = StringIO.new "Hello World" 16 | error = StringIO.new 17 | 18 | @runner = Sprout::ProcessRunner.new 19 | @runner.stubs(:open4_popen4_block).returns( [pid, write, read, error] ) 20 | end 21 | 22 | teardown do 23 | FileUtils.chmod 0744, @script 24 | FileUtils.chmod 0744, @script_with_spaces 25 | end 26 | 27 | #-------------------------------------------------- 28 | context "on nix" do 29 | 30 | should "accept and forward multiple arguments" do 31 | @runner.expects(:execute_with_block).once.with("ls", "-la").returns nil 32 | @runner.execute_open4 "ls", "-la" 33 | end 34 | 35 | should "accept and forward no arguments" do 36 | @runner.expects(:execute_with_block).once.with("ls").returns nil 37 | @runner.execute_open4 "ls" 38 | end 39 | 40 | context "with invalid executable mode" do 41 | setup do 42 | FileUtils.chmod(0644, @script) 43 | FileUtils.chmod(0644, @script_with_spaces) 44 | # Raise the Errno::EACCESS (Bad File Mode) error 45 | # On the first call only - this should trigger the 46 | # File mode update, when encountered 47 | @runner.stubs(:open4_popen4_block).once.raises Errno::EACCES 48 | end 49 | 50 | context "and arguments" do 51 | should "update file mode" do 52 | execute_with_open4_and_bad_mode @script, "-n FooBar" 53 | end 54 | 55 | context "and spaces in the path" do 56 | should "modify invalid file modes for executables" do 57 | execute_with_open4_and_bad_mode @script_with_spaces, "-n FooBar" 58 | end 59 | end 60 | end 61 | 62 | context "and no arguments" do 63 | should "update file mode" do 64 | execute_with_open4_and_bad_mode @script 65 | end 66 | end 67 | end 68 | 69 | end 70 | 71 | #-------------------------------------------------- 72 | context "on win32" do 73 | should "accept and forward multiple arguments" do 74 | # Comment out the following line to actually execute the process on Windows: 75 | @runner.expects(:execute_with_block).once.with("dir").returns nil 76 | @runner.execute_win32("dir") 77 | end 78 | 79 | should "attempt to load win32-open 3 gem on Ruby 1.8.6" do 80 | @runner.stubs(:ruby_version).returns('1.8.6') 81 | @runner.expects(:open3_popen3_block).never 82 | @runner.expects(:win32_open3_block) 83 | @runner.execute_win32('ls') 84 | end 85 | 86 | should "attempt to load win32-open 3 gem on Ruby 1.8.7" do 87 | @runner.stubs(:ruby_version).returns('1.8.7') 88 | @runner.expects(:open3_popen3_block).never 89 | @runner.expects(:win32_open3_block) 90 | @runner.execute_win32('ls') 91 | end 92 | 93 | should "NOT load win32-open 3 gem on Ruby 1.9.2" do 94 | @runner.stubs(:ruby_version).returns('1.9.2') 95 | @runner.expects(:win32_open3_block).never 96 | @runner.expects(:open3_popen3_block) 97 | @runner.execute_win32('ls') 98 | end 99 | 100 | end 101 | 102 | 103 | 104 | context "an unknown process" do 105 | should "raise an exception if the executable doesn't exist" do 106 | assert_raise Sprout::Errors::ProcessRunnerError do 107 | @runner.stubs(:open4_popen4_block).raises Errno::ENOENT 108 | @runner.execute_open4('SomeUnknownExecutableThatCantBeInYourPath', '--some-arg true --other-arg false') 109 | end 110 | end 111 | end 112 | 113 | end 114 | 115 | private 116 | 117 | def execute_with_open4_and_bad_mode(command, options="") 118 | assert !File.stat(command).executable?, "File should not be executable to begin" 119 | @runner.expects(:update_executable_mode) 120 | @runner.execute_open4 command, options 121 | assert_matches /^Hello World/, @runner.read 122 | end 123 | 124 | end 125 | 126 | -------------------------------------------------------------------------------- /test/unit/rdoc_parser_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | require 'fixtures/examples/echo_inputs' 3 | 4 | class ExecutableOptionParserTest < Test::Unit::TestCase 5 | include Sprout::TestHelper 6 | 7 | context "a new RDoc parser" do 8 | 9 | setup do 10 | @parser = Sprout::RDocParser.new 11 | end 12 | 13 | end 14 | end 15 | 16 | -------------------------------------------------------------------------------- /test/unit/remote_file_loader_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class RemoteFileLoaderTest < Test::Unit::TestCase 4 | include Sprout::TestHelper 5 | 6 | context "The remote file loader" do 7 | 8 | setup do 9 | @uri = 'http://github.com/downloads/lukebayes/project-sprouts/echochamber-test.zip' 10 | @file = File.join fixtures, 'remote_file_loader', 'md5', 'echochamber-test.zip' 11 | @md5 = 'd6939117f1df58e216f365a12fec64f9' 12 | 13 | # Don't reach out to the network for these tests: 14 | Sprout::RemoteFileLoader.stubs(:fetch).returns File.read @file 15 | end 16 | 17 | should "attempt to load a requested file" do 18 | bytes = Sprout::RemoteFileLoader.load @uri, @md5 19 | assert_equal 310, bytes.size 20 | end 21 | 22 | end 23 | end 24 | 25 | -------------------------------------------------------------------------------- /test/unit/remote_file_target_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class RemoteFileTargetTest < Test::Unit::TestCase 4 | include Sprout::TestHelper 5 | 6 | context "an improperly configured remote file target" do 7 | 8 | should "throw validation error on archive_type" do 9 | assert_raises Sprout::Errors::ValidationError do 10 | t = Sprout::RemoteFileTarget.new 11 | #t.archive_type = :zip # This causes the validation error 12 | t.md5 = 'abcd' 13 | t.url = 'http://google.com' 14 | t.pkg_name = 'google' 15 | t.pkg_version = '1.0.0' 16 | 17 | t.resolve 18 | end 19 | end 20 | 21 | should "throw validation error on md5" do 22 | assert_raises Sprout::Errors::ValidationError do 23 | t = Sprout::RemoteFileTarget.new 24 | t.archive_type = :zip 25 | #t.md5 = 'abcd' # This causes the validation error 26 | t.url = 'http://google.com' 27 | t.pkg_name = 'google' 28 | t.pkg_version = '1.0.0' 29 | 30 | t.resolve 31 | end 32 | end 33 | 34 | should "throw validation error on url" do 35 | assert_raises Sprout::Errors::ValidationError do 36 | t = Sprout::RemoteFileTarget.new 37 | t.archive_type = :zip 38 | t.md5 = 'abcd' 39 | #t.url = 'http://google.com' # This causes the validation error 40 | t.pkg_name = 'google' 41 | t.pkg_version = '1.0.0' 42 | 43 | t.resolve 44 | end 45 | end 46 | end 47 | 48 | context "a correctly configured remote file target" do 49 | 50 | setup do 51 | @target = Sprout::RemoteFileTarget.new do |t| 52 | t.archive_type = :zip 53 | t.md5 = 'd41d8cd98f00b204e9800998ecf8427e' 54 | t.url = 'http://github.com/downloads/lukebayes/project-sprouts/echochamber-test.zip' 55 | t.pkg_name = 'echochamber' 56 | t.pkg_version = '1.0.pre' 57 | t.add_executable :echochamber, 'bin/echochamber.sh' 58 | end 59 | 60 | @downloaded_file = File.join(temp_cache, 'downloaded.zip') 61 | @target.stubs(:downloaded_file).returns @downloaded_file 62 | 63 | @unpacked_file = File.join(temp_cache, 'unpacked') 64 | 65 | 66 | downloaded_bytes = File.join(fixtures, 'remote_file_target', 'echochamber-test.zip') 67 | @archive_bytes = File.open(downloaded_bytes, 'rb').read 68 | 69 | @env_path = File.join(fixtures, 'env_path') 70 | 71 | @target.stubs(:download_archive).returns @archive_bytes 72 | end 73 | 74 | teardown do 75 | remove_file File.join(fixtures, 'sprout') 76 | ENV['ECHOCHAMBER'] = nil 77 | ENV['ECHOCHAMBER_1_PRE'] = nil 78 | ENV['SPROUT_ECHOCHAMBER'] = nil 79 | ENV['SPROUT_ECHOCHAMBER_1_PRE'] = nil 80 | end 81 | 82 | context "that is identified by environment var" do 83 | should "use the provided path" do 84 | ENV["ECHOCHAMBER"] = @env_path 85 | assert_equal @env_path, @target.unpacked_file 86 | end 87 | 88 | should "use the provided path with version" do 89 | ENV["ECHOCHAMBER"] = File.join(@env_path, 'WRONG') 90 | ENV["ECHOCHAMBER_1_0_PRE"] = @env_path 91 | assert_equal @env_path, @target.unpacked_file 92 | end 93 | 94 | should "use sprout prefixed env first if found" do 95 | ENV["SPROUT_ECHOCHAMBER"] = @env_path 96 | ENV["ECHOCHAMBER"] = File.join(@env_path, 'WRONG') 97 | assert_equal @env_path, @target.unpacked_file 98 | end 99 | 100 | should "load from env path if available" do 101 | end 102 | end 103 | 104 | context "that has already been UNPACKED" do 105 | should "not be DOWNLOADED or unpacked" do 106 | FileUtils.mkdir_p @unpacked_file 107 | create_file File.join(@unpacked_file, 'content') 108 | @target.stubs(:unpacked_file).returns @unpacked_file 109 | 110 | @target.expects(:prompt_for_md5_failure).never 111 | @target.expects(:download_archive).never 112 | @target.expects(:unpack_archive).never 113 | @target.resolve 114 | end 115 | end 116 | 117 | context "that had an unpack failure" do 118 | should "still unpack the file" do 119 | @target.stubs(:unpacked_file).returns @unpacked_file 120 | # Create the expected unpacked_file: 121 | FileUtils.mkdir_p @unpacked_file 122 | @target.stubs('should_unpack?').returns true 123 | @target.expects(:unpack_archive) 124 | @target.resolve 125 | end 126 | end 127 | 128 | context "that has been DOWNLOADED, but not UNPACKED" do 129 | should "not unpack if md5 doesn't match, and user responds in negative" do 130 | @target.stubs('should_unpack?').returns false 131 | @target.expects(:unpack_archive).never 132 | @target.resolve 133 | end 134 | 135 | should "unpack but not download" do 136 | @target.stubs(:unpacked_file).returns @unpacked_file 137 | @target.stubs('should_unpack?').returns true 138 | @target.resolve 139 | assert_not_empty @unpacked_file 140 | end 141 | end 142 | 143 | context "that has not yet been DOWNLOADED, or UNPACKED" do 144 | should "download and unpack the remote archive" do 145 | @target.stubs(:unpacked_file).returns @unpacked_file 146 | @target.stubs('should_unpack?').returns true 147 | #@target.expects(:download_archive) 148 | #@target.expects(:unpack_archive) 149 | @target.resolve 150 | 151 | assert_file @downloaded_file 152 | assert_not_empty @unpacked_file 153 | end 154 | end 155 | 156 | end 157 | end 158 | -------------------------------------------------------------------------------- /test/unit/ruby_feature_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class RubyFeatureTest < Test::Unit::TestCase 4 | include Sprout::TestHelper 5 | 6 | context "a new ruby feature" do 7 | 8 | teardown do 9 | FakePlugin.clear_entities! 10 | end 11 | 12 | should "allow register" do 13 | # Shouldn't require the package since it's already 14 | # registered and available... 15 | FakePlugin.expects(:require_ruby_package).never 16 | plugin = create_item 17 | FakePlugin.register plugin 18 | assert_equal plugin, FakePlugin.load(:foo, 'sprout/base') 19 | end 20 | 21 | should "return nil if nothing is registered" do 22 | FakePlugin.expects :require_ruby_package 23 | assert_raises Sprout::Errors::LoadError do 24 | FakePlugin.load(:foo, 'sprout/base') 25 | end 26 | end 27 | 28 | should "find the correct registered plugin" do 29 | foo = create_item 30 | bar = create_item :name => :bar 31 | FakePlugin.register foo 32 | FakePlugin.register bar 33 | assert_equal bar, FakePlugin.load(:bar) 34 | end 35 | 36 | should "not share registrations among includers" do 37 | foo = create_item 38 | FakePlugin.register foo 39 | assert_raises Sprout::Errors::LoadError do 40 | OtherFakePlugin.load :foo 41 | end 42 | end 43 | 44 | should "not call resolve on register" do 45 | plugin = FakePlugin.new({:name => :foo2}) 46 | plugin.expects(:resolve).never 47 | FakePlugin.register plugin 48 | end 49 | 50 | should "call resolve on load" do 51 | plugin = FakePlugin.new({:name => :foo2}) 52 | FakePlugin.register plugin 53 | 54 | plugin.expects(:resolve) 55 | FakePlugin.load :foo2 56 | end 57 | 58 | should "allow registration and load without ruby package or version" do 59 | FakePlugin.register FakePlugin.new({:name => :foo2}) 60 | assert_not_nil FakePlugin.load :foo2 61 | end 62 | 63 | should "allow registration and match with nil pkg_name" do 64 | FakePlugin.register(create_item(:pkg_name => nil)) 65 | assert_not_nil FakePlugin.load :foo 66 | end 67 | 68 | should "allow registration and match with nil pkg_version" do 69 | FakePlugin.register(create_item(:pkg_version => nil)) 70 | assert_not_nil FakePlugin.load :foo 71 | end 72 | 73 | should "allow registration and match with nil platform" do 74 | FakePlugin.register(create_item(:platform => nil)) 75 | assert_not_nil FakePlugin.load :foo 76 | end 77 | 78 | should "not allow registration with nil name" do 79 | assert_raises Sprout::Errors::UsageError do 80 | FakePlugin.register(create_item(:name => nil)) 81 | end 82 | end 83 | 84 | should "load when request is a string" do 85 | FakePlugin.register(FakePlugin.new({:name => :foo3})) 86 | assert_not_nil FakePlugin.load 'foo3' 87 | end 88 | 89 | should "load when registration is a string" do 90 | FakePlugin.register(FakePlugin.new({:name => :swc, :pkg_name => 'asunit4'})) 91 | assert_not_nil FakePlugin.load nil, :asunit4 92 | end 93 | 94 | should "raise on failure to find from collection" do 95 | FakePlugin.register(create_item) 96 | assert_raises Sprout::Errors::LoadError do 97 | FakePlugin.load [:bar, :baz] 98 | end 99 | end 100 | 101 | should "allow load with collection of names" do 102 | FakePlugin.register(create_item) 103 | assert_not_nil FakePlugin.load [:bar, :baz, :foo] 104 | end 105 | 106 | should "find platform-specific remote file target" do 107 | osx = create_item(:platform => :osx) 108 | windows = create_item(:platform => :windows) 109 | linux = create_item(:platform => :linux) 110 | 111 | FakePlugin.register osx 112 | FakePlugin.register windows 113 | FakePlugin.register linux 114 | 115 | as_a_mac_system do 116 | result = FakePlugin.load :foo 117 | assert_equal osx, result 118 | end 119 | 120 | as_a_windows_system do 121 | result = FakePlugin.load :foo 122 | assert_equal windows, result 123 | end 124 | 125 | as_a_win_nix_system do 126 | result = FakePlugin.load :foo 127 | assert_equal windows, result 128 | end 129 | 130 | as_a_unix_system do 131 | result = FakePlugin.load :foo 132 | assert_equal linux, result 133 | end 134 | end 135 | 136 | end 137 | 138 | private 139 | 140 | def create_item options={} 141 | FakePlugin.new({:name => :foo, :pkg_name => 'sprout/base', :pkg_version => '1.0.pre', :platform => :universal}.merge(options)) 142 | end 143 | 144 | class FakePlugin < OpenStruct 145 | include Sprout::RubyFeature 146 | 147 | ## 148 | # Implement resolve like RemoteFileTargets.. 149 | def resolve 150 | end 151 | end 152 | 153 | class OtherFakePlugin 154 | include Sprout::RubyFeature 155 | end 156 | end 157 | 158 | 159 | -------------------------------------------------------------------------------- /test/unit/ruby_generator_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | require 'sprout/generators/ruby/ruby_generator' 4 | 5 | class RubyGeneratorTest < Test::Unit::TestCase 6 | include Sprout::TestHelper 7 | 8 | context "A generated ruby application" do 9 | 10 | setup do 11 | @temp = File.join(fixtures, 'generators', 'ruby') 12 | FileUtils.mkdir_p @temp 13 | @generator = Sprout::RubyGenerator.new 14 | @generator.path = @temp 15 | @generator.logger = StringIO.new 16 | end 17 | 18 | teardown do 19 | remove_file @temp 20 | end 21 | 22 | should "generate a new ruby application" do 23 | @generator.input = 'SomeProject' 24 | @generator.version = '4.2.pre' 25 | @generator.lib = 'libs' 26 | @generator.execute 27 | 28 | project_dir = File.join @temp, 'some_project' 29 | assert_file project_dir 30 | 31 | gem_file = File.join project_dir, 'Gemfile' 32 | assert_file gem_file 33 | 34 | rake_file = File.join project_dir, 'Rakefile' 35 | assert_file rake_file 36 | 37 | gem_spec = File.join project_dir, 'some_project.gemspec' 38 | assert_file gem_spec 39 | 40 | lib_dir = File.join project_dir, 'libs' 41 | assert_file lib_dir 42 | 43 | module_file = File.join lib_dir, 'some_project.rb' 44 | assert_file module_file do |content| 45 | assert_matches /VERSION/, content 46 | assert_matches /4.2.pre/, content 47 | end 48 | 49 | classes_dir = File.join lib_dir, 'some_project' 50 | assert_file classes_dir 51 | 52 | main_file = File.join classes_dir, 'base.rb' 53 | assert_file main_file 54 | 55 | test_dir = File.join project_dir, 'test' 56 | assert_file test_dir 57 | 58 | unit_dir = File.join test_dir, 'unit' 59 | assert_file unit_dir 60 | 61 | test_helper = File.join unit_dir, 'test_helper.rb' 62 | assert_file test_helper do |content| 63 | assert_matches /require 'some_project'/, content 64 | end 65 | 66 | test_case = File.join unit_dir, 'some_project_test.rb' 67 | assert_file test_case do |content| 68 | assert_matches /class SomeProjectTest/, content 69 | end 70 | 71 | fixtures_dir = File.join test_dir, 'fixtures' 72 | assert_file fixtures_dir 73 | 74 | bin_dir = File.join project_dir, 'bin' 75 | assert_file bin_dir 76 | 77 | exe_file = File.join bin_dir, 'some-project' 78 | assert_file exe_file do |content| 79 | assert_matches /some_project/, content 80 | assert_matches /SomeProject::Base.new/, content 81 | end 82 | 83 | end 84 | end 85 | end 86 | 87 | -------------------------------------------------------------------------------- /test/unit/specification_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class SpecificationTest < Test::Unit::TestCase 4 | include Sprout::TestHelper 5 | 6 | context "a newly defined specification" do 7 | setup do 8 | @spec = Sprout::Specification.new do |s| 9 | s.version = '1.0.pre' 10 | end 11 | end 12 | 13 | should "have a default name" do 14 | assert_equal 'specification_test', @spec.name 15 | end 16 | 17 | should "accept the version" do 18 | assert_equal '1.0.pre', @spec.version 19 | end 20 | 21 | context "with a new name" do 22 | setup do 23 | @spec.name = 'foo_sdk' 24 | @spec.version = '1.0.pre' 25 | end 26 | 27 | should "register executables with file_target reference" do 28 | @spec.add_file_target do |t| 29 | t.add_executable :foo, 'bin/foo' 30 | end 31 | 32 | Sprout::Executable.stubs :require_ruby_package 33 | exe = Sprout::Executable.load :foo, 'foo_sdk', '1.0.pre' 34 | assert_equal Sprout::FileTarget, exe.file_target.class 35 | end 36 | 37 | should "register executable with remote_file_target instances" do 38 | @spec.add_remote_file_target do |t| 39 | t.url = 'http://www.example.com' 40 | t.md5 = 'abcd' 41 | t.archive_type = :zip 42 | t.add_executable :foo, 'bin/foo' 43 | end 44 | 45 | Sprout::RemoteFileTarget.any_instance.stubs :resolve 46 | Sprout::Executable.stubs :require_ruby_package 47 | exe = Sprout::Executable.load :foo, 'foo_sdk', '1.0.pre' 48 | assert_equal Sprout::RemoteFileTarget, exe.file_target.class 49 | assert exe.path =~ /cache/, "RemoteFileTarget local path should include Sprout CACHE directory" 50 | end 51 | 52 | should "load returns libraries in expected order" do 53 | @spec.add_file_target do |t| 54 | t.add_library :swc, 'bin/foo' 55 | t.add_library :src, 'bin/bar' 56 | end 57 | 58 | # Without specifying the :swc/:src decision: 59 | library = Sprout::Library.load nil, 'foo_sdk' 60 | assert_equal 'foo', File.basename(library.path) 61 | end 62 | 63 | end 64 | end 65 | 66 | context "a platform-specific, remote executable specification" do 67 | 68 | setup do 69 | @spec = Sprout::Specification.new do |s| 70 | s.name = 'fake_flashplayer_spec' 71 | s.version = '10.1.53' 72 | 73 | s.add_remote_file_target do |t| 74 | t.platform = :windows 75 | t.add_executable :fake_flashplayer, "flashplayer_10_sa_debug.exe" 76 | end 77 | 78 | s.add_remote_file_target do |t| 79 | t.platform = :osx 80 | t.add_executable :fake_flashplayer, "Flash Player Debugger.app" 81 | end 82 | 83 | s.add_remote_file_target do |t| 84 | t.platform = :linux 85 | t.add_executable :fake_flashplayer, "flashplayerdebugger" 86 | end 87 | end 88 | 89 | end 90 | 91 | should "be resolved for Windows systems" do 92 | Sprout::RemoteFileTarget.any_instance.expects(:resolve) 93 | as_a_windows_system do 94 | target = Sprout::Executable.load 'fake_flashplayer' 95 | assert_equal :windows, target.platform 96 | end 97 | end 98 | 99 | should "be resolved for OSX systems" do 100 | Sprout::RemoteFileTarget.any_instance.expects(:resolve) 101 | as_a_mac_system do 102 | target = Sprout::Executable.load 'fake_flashplayer' 103 | assert_equal :osx, target.platform 104 | end 105 | end 106 | 107 | should "be resolved for Unix systems" do 108 | Sprout::RemoteFileTarget.any_instance.expects(:resolve) 109 | as_a_unix_system do 110 | target = Sprout::Executable.load 'fake_flashplayer' 111 | assert_equal :linux, target.platform 112 | end 113 | end 114 | end 115 | 116 | =begin 117 | ## 118 | # This test method is EXTREMELY slow! 119 | # It attempts to download and unpack the 120 | # Flex SDK - but only the first time 121 | # it's run on a particular system... 122 | context "a universal collection of executables" do 123 | 124 | setup do 125 | @spec = Sprout::Specification.new do |s| 126 | s.name = 'flex4' 127 | s.version = '4.0.pre' 128 | 129 | s.add_remote_file_target do |t| 130 | # Apply the windows-specific configuration: 131 | t.platform = :universal 132 | # Apply the shared platform configuration: 133 | # Remote Archive: 134 | t.archive_type = :zip 135 | t.url = "http://download.macromedia.com/pub/labs/flex/4/flex4sdk_b2_100509.zip" 136 | t.md5 = "6a0838c5cb33145fe88933778ddb966d" 137 | 138 | # Executables: (add .exe suffix if it was passed in) 139 | t.add_executable :compc, "bin/compc" 140 | t.add_executable :fcsh, "bin/fcsh" 141 | t.add_executable :fdb, "bin/fdb" 142 | t.add_executable :mxmlc, "bin/mxmlc" 143 | end 144 | end 145 | 146 | end 147 | 148 | should "make binaries available" do 149 | mxmlc = Sprout::Executable.load :mxmlc 150 | assert_not_nil mxmlc 151 | end 152 | end 153 | =end 154 | 155 | context "a newly included executable" do 156 | setup do 157 | @echo_chamber = File.join fixtures, 'executable', 'echochamber_gem', 'echo_chamber' 158 | $:.unshift File.dirname(@echo_chamber) 159 | end 160 | 161 | teardown do 162 | $:.shift 163 | end 164 | 165 | should "require the sproutspec" do 166 | path = Sprout::Executable.load(:echos, 'echo_chamber').path 167 | assert_matches /fixtures\/.*echochamber/, path 168 | assert_file path 169 | 170 | # TODO: We should be able to execute 171 | # the provided executable! 172 | #response = Sprout::System.create.execute path 173 | #assert_equal 'ECHO ECHO ECHO', response 174 | end 175 | end 176 | end 177 | 178 | -------------------------------------------------------------------------------- /test/unit/sprout_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class SproutTest < Test::Unit::TestCase 4 | include Sprout::TestHelper 5 | 6 | context "The Sprout::TestHelper" do 7 | 8 | context "find_fixtures" do 9 | 10 | setup do 11 | @from = File.join(fixtures, 'sprout_test_case', 'test', 'other') 12 | @expected_fixtures = File.join(fixtures, 'sprout_test_case', 'test', 'fixtures') 13 | FileUtils.makedirs @from 14 | end 15 | 16 | teardown do 17 | remove_file File.join(fixtures, 'sprout_test_case') 18 | end 19 | 20 | should "find_fixtures within a test folder" do 21 | result = find_fixtures @from 22 | assert_equal @expected_fixtures, result 23 | end 24 | 25 | should "throw if reaches system root" do 26 | assert_raises Sprout::Errors::UsageError do 27 | find_fixtures File.dirname(File.dirname(File.dirname(__FILE__))) 28 | end 29 | end 30 | end 31 | 32 | end 33 | 34 | context "Errors" do 35 | include Sprout::Errors 36 | 37 | [ 38 | ArchiveUnpackerError, 39 | DestinationExistsError, 40 | ExecutionError, 41 | ExecutableRegistrationError, 42 | MissingExecutableError, 43 | ProcessRunnerError, 44 | SproutError, 45 | ExecutableError, 46 | UnknownArchiveType, 47 | UsageError, 48 | VersionRequirementNotMetError 49 | ].each do |error| 50 | 51 | should "be available to instantiate a #{error.to_s}" do 52 | error.new 53 | end 54 | end 55 | end 56 | 57 | context "cache" do 58 | setup do 59 | @library = File.join(fixtures, 'sprout') 60 | end 61 | 62 | should "find library from system" do 63 | user = Sprout::System::OSXSystem.new 64 | user.stubs(:library).returns @library 65 | Sprout.stubs(:current_system).returns user 66 | 67 | expected_cache = File.join(@library, 'Sprouts', Sprout::VERSION::MAJOR_MINOR, 'cache') 68 | assert_equal expected_cache, Sprout.cache 69 | end 70 | 71 | should "find library for unix system" do 72 | user = Sprout::System::UnixSystem.new 73 | user.stubs(:library).returns @library 74 | Sprout.stubs(:current_system).returns user 75 | 76 | expected_cache = File.join(@library, '.sprouts', Sprout::VERSION::MAJOR_MINOR, 'cache') 77 | assert_equal expected_cache, Sprout.cache 78 | end 79 | end 80 | 81 | context "A new sprout test case" do 82 | 83 | should "be able to work as a particular user but then revert when done" do 84 | original_class = Sprout.current_system.class 85 | 86 | block_called = false 87 | 88 | systems = [ 89 | Sprout::System::VistaSystem, 90 | Sprout::System::WinNixSystem, 91 | Sprout::System::WinSystem, 92 | Sprout::System::JavaSystem, 93 | Sprout::System::OSXSystem, 94 | Sprout::System::UnixSystem 95 | ] 96 | incr = 0 97 | 98 | as_each_system do |sys| 99 | block_called = true 100 | assert_equal systems[incr], Sprout.current_system.class, "Requests for the current system should yield a UNIX system" 101 | incr += 1 102 | end 103 | 104 | assert_equal original_class, Sprout.current_system.class 105 | assert block_called, "Ensure the block was yielded to..." 106 | end 107 | end 108 | 109 | context "Executables" do 110 | 111 | context "with a sandboxed load path" do 112 | 113 | setup do 114 | path = File.join fixtures, "executable", "flex3sdk_gem" 115 | $:.unshift path 116 | end 117 | 118 | teardown do 119 | $:.shift 120 | end 121 | 122 | should "find requested executables" do 123 | path = Sprout::Executable.load(:mxmlc, 'flex3sdk', '>= 3.0.0').path 124 | assert_not_nil path 125 | end 126 | end 127 | 128 | context "with a stubbed load path" do 129 | 130 | setup do 131 | Sprout::Executable.stubs(:require_ruby_package).returns true 132 | @path = 'test/fixtures/process_runner/chmod_script.sh' 133 | end 134 | 135 | should "work when registered with different gem names" do 136 | register_executable :mxmlc, 'flex3sdk', '1.0.pre', @path 137 | register_executable :mxmlc, 'flex4sdk', '1.0.pre', @path 138 | end 139 | 140 | should "work when registered with different exe names" do 141 | register_executable :mxmlc, 'flex3sdk', '1.0.pre', @path 142 | register_executable :compc, 'flex3sdk', '1.0.pre', @path 143 | end 144 | 145 | context "that are registered" do 146 | should "work the first time" do 147 | register_executable :mxmlc, 'flex3sdk', '1.0.pre', @path 148 | end 149 | 150 | context "and then requested" do 151 | setup do 152 | register_executable :mxmlc, 'flex3sdk', '1.0.pre', @path 153 | end 154 | 155 | should "succeed if the executable is available and no version specified" do 156 | assert_equal @path, Sprout::Executable.load(:mxmlc, 'flex3sdk').path 157 | end 158 | 159 | should "succeed if version requirement is met" do 160 | assert_equal @path, Sprout::Executable.load(:mxmlc, 'flex3sdk', '>= 1.0.pre').path 161 | end 162 | 163 | should "fail if version requirement is not met" do 164 | assert_raises Sprout::Errors::LoadError do 165 | Sprout::Executable.load :mxmlc, 'flex3sdk', '>= 1.1.0' 166 | end 167 | end 168 | 169 | end 170 | end 171 | 172 | context "that are not registered" do 173 | should "fail when requested" do 174 | assert_raises Sprout::Errors::LoadError do 175 | Sprout::Executable.load :mxmlc, 'flex3sdk' 176 | end 177 | end 178 | end 179 | 180 | end 181 | end 182 | 183 | private 184 | 185 | def register_executable name, pkg_name, pkg_version, path, platform=:universal 186 | exe = OpenStruct.new({ 187 | :name => name, 188 | :path => path, 189 | :pkg_name => pkg_name, 190 | :pkg_version => pkg_version, 191 | :platform => platform 192 | }) 193 | Sprout::Executable.register exe 194 | end 195 | 196 | end 197 | 198 | 199 | -------------------------------------------------------------------------------- /test/unit/string_param_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class StringParamTest < Test::Unit::TestCase 4 | include Sprout::TestHelper 5 | 6 | context "a new StringParam" do 7 | 8 | setup do 9 | @param = Sprout::Executable::StringParam.new 10 | @param.name = "string" 11 | end 12 | 13 | should "escape spaces" do 14 | @param.value = "a b c" 15 | assert_equal '--string=a\ b\ c', @param.to_shell 16 | end 17 | end 18 | end 19 | 20 | -------------------------------------------------------------------------------- /test/unit/string_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class StringTest < Test::Unit::TestCase 4 | include Sprout::TestHelper 5 | 6 | context "a new string" do 7 | 8 | should "switch to snake case" do 9 | assert_equal "a_b_c", "ABC".snake_case 10 | assert_equal "my_big_camel_case_word", "MyBigCamelCaseWord".snake_case 11 | end 12 | 13 | should "switch to camel case" do 14 | assert_equal "ABC", "a_b_c".camel_case 15 | assert_equal "MyBigCamelCaseWord", "my_big_camel_case_word".camel_case 16 | end 17 | 18 | end 19 | end 20 | 21 | -------------------------------------------------------------------------------- /test/unit/strings_param_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class StringsParamTest < Test::Unit::TestCase 4 | include Sprout::TestHelper 5 | 6 | context "a new StringsParam" do 7 | 8 | setup do 9 | @param = Sprout::Executable::Strings.new 10 | @param.name = "strings" 11 | end 12 | 13 | ['abcd', 1234, true].each do |value| 14 | should "throw with non-enumerable assignment of #{value}" do 15 | assert_raises Sprout::Errors::ExecutableError do 16 | @param.value = value 17 | end 18 | end 19 | end 20 | 21 | should "not escape spaces" do 22 | @param.value << "a b c" 23 | assert_equal '--strings+=a b c', @param.to_shell 24 | end 25 | end 26 | end 27 | 28 | -------------------------------------------------------------------------------- /test/unit/test_helper.rb: -------------------------------------------------------------------------------- 1 | require "rubygems" 2 | require "bundler" 3 | 4 | Bundler.setup :default, :development 5 | 6 | # These require statments *must* be in this order: 7 | # http://bit.ly/bCC0Ew 8 | # Somewhat surprised they're not being required by Bundler... 9 | require 'shoulda' 10 | require 'mocha' 11 | 12 | lib = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'lib')) 13 | $:.unshift lib unless $:.include? lib 14 | 15 | require 'sprout' 16 | 17 | test = File.expand_path(File.join(File.dirname(__FILE__), '..')) 18 | $:.unshift test unless $:.include? test 19 | 20 | require 'unit/fake_process_runner' 21 | require 'unit/fake_executable_task' 22 | require 'sprout/test_helper' 23 | 24 | class Test::Unit::TestCase 25 | 26 | # Only clear registrations in the Sprout core 27 | # project - not in child projects 28 | def teardown 29 | Sprout::Executable.clear_entities! 30 | Sprout::Library.clear_entities! 31 | Sprout::Generator.clear_entities! 32 | end 33 | end 34 | 35 | -------------------------------------------------------------------------------- /test/unit/tool_generator_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | require 'sprout/generators/tool/tool_generator' 4 | 5 | class ToolGeneratorTest < Test::Unit::TestCase 6 | include Sprout::TestHelper 7 | 8 | context "A generated tool" do 9 | 10 | setup do 11 | @temp = File.join(fixtures, 'generators', 'tool') 12 | FileUtils.mkdir_p @temp 13 | @generator = Sprout::ToolGenerator.new 14 | @generator.path = @temp 15 | @generator.logger = StringIO.new 16 | end 17 | 18 | teardown do 19 | remove_file @temp 20 | end 21 | 22 | should "generate a new tool project" do 23 | @generator.input = 'flex4sdk' 24 | @generator.author = 'Some Body' 25 | @generator.execute 26 | 27 | project = File.join(@temp, 'flex4sdk') 28 | assert_file project 29 | assert_file File.join(project, 'Gemfile') 30 | assert_file File.join(project, 'flex4sdk.gemspec') do |content| 31 | assert_matches /s.name\s+= Flex4sdk::NAME/, content 32 | assert_matches /s.version\s+= Flex4sdk::VERSION::STRING/, content 33 | assert_matches /s.author\s+= "Some Body"/, content 34 | end 35 | assert_file File.join(project, 'flex4sdk.rb') do |content| 36 | assert_matches /NAME = 'flex4sdk'/, content 37 | assert_matches /url\s+= "http:\/\/github.com/, content 38 | end 39 | end 40 | 41 | end 42 | end 43 | 44 | -------------------------------------------------------------------------------- /test/unit/unix_system_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class UnixSystemTest < Test::Unit::TestCase 4 | include Sprout::TestHelper 5 | 6 | context "new unix system" do 7 | 8 | setup do 9 | @user = Sprout::System::UnixSystem.new 10 | @user.stubs(:home).returns '/home/someone' 11 | end 12 | 13 | should "escape spaces in paths" do 14 | assert_equal 'a\ b', @user.clean_path('a b') 15 | end 16 | 17 | should "snake case application name" do 18 | assert_equal '.foo_bar', @user.format_application_name('Foo Bar') 19 | end 20 | 21 | should "have home" do 22 | assert_equal '/home/someone', @user.home 23 | end 24 | 25 | should "have library" do 26 | assert_equal '/home/someone', @user.library 27 | end 28 | 29 | should "format application home" do 30 | assert_equal '/home/someone/.sprouts', @user.application_home('Sprouts') 31 | end 32 | 33 | context "when fed an application with windows line endings" do 34 | 35 | setup do 36 | exe_with_crlf = "#!/bin/sh\r\n\r\n################################################################################\r\n##\r\n## ADOBE SYSTEMS INCORPORATED\r\n## Copyright 2007 Adobe Systems Incorporated\r\n## All Rights Reserved.\r\n##\r\n## NOTICE: Adobe permits you to use, modify, and distribute this file\r\n## in accordance with the terms of the license agreement accompanying it.\r\n##\r\n################################################################################\r\n\r\n#\r\n# mxmlc launch script for unix. On windows, mxmlc.exe is used and\r\n# java settings are managed in jvm.config in this directory.\r\n#\r\n\r\ncase `uname` in\r\n CYGWIN*)\r\n OS=\"Windows\"\r\n ;;\r\n *)\r\n OS=Unix\r\nesac\r\n\r\nif [ $OS = \"Windows\" ]; then\r\n # set FLEX_HOME relative to mxmlc if not set\r\n test \"$FLEX_HOME\" = \"\" && {\r\n FLEX_HOME=`dirname $0`/..\r\n FLEX_HOME=`cygpath -m $FLEX_HOME`\r\n }\r\n\r\nelif [ $OS = \"Unix\" ]; then\r\n\r\n # set FLEX_HOME relative to mxmlc if not set\r\n test \"$FLEX_HOME\" = \"\" && {\r\n FLEX_HOME=`dirname \"$0\"`/..\r\n }\r\n\r\nfi\r\n\r\n# don't use $FLEX_HOME in this variable because it may contain spaces,\r\n# instead put it on the java args directly, with double-quotes around it\r\nVMARGS=\"-Xmx384m -Dsun.io.useCanonCaches=false\"\r\n\r\njava $VMARGS -jar \"$FLEX_HOME/lib/mxmlc.jar\" +flexlib=\"$FLEX_HOME/frameworks\" \"$@\"\r\n" 37 | @target = File.join fixtures, 'executable', 'windows_line_endings.tmp' 38 | File.open(@target, 'wb+') do |f| 39 | f.write exe_with_crlf 40 | end 41 | end 42 | 43 | teardown do 44 | remove_file @target 45 | end 46 | 47 | should "fix windows line endings" do 48 | @user.expects :repair_executable 49 | @user.attempt_to_repair_executable @target 50 | end 51 | end 52 | end 53 | end 54 | 55 | 56 | -------------------------------------------------------------------------------- /test/unit/user_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class UserTest < Test::Unit::TestCase 4 | #include Sprout::TestHelper 5 | 6 | ['vista', 'mswin', 'wince', 'emx'].each do |variant| 7 | context variant do 8 | should "create a Win System" do 9 | Sprout::Platform.any_instance.stubs(:ruby_platform).returns variant 10 | assert Sprout::System.create.is_a?(Sprout::System::WinSystem) 11 | end 12 | end 13 | end 14 | 15 | =begin 16 | 17 | ['cygwin', 'mingw', 'bccwin'].each do |variant| 18 | context variant do 19 | should "create a WinNix System" do 20 | Sprout::Platform.any_instance.stubs(:ruby_platform).returns variant 21 | assert Sprout::System.create.is_a?(Sprout::System::WinNixUser) 22 | assert Sprout::System.create.is_a?(Sprout::System::WinUser) 23 | end 24 | end 25 | end 26 | 27 | context "vista" do 28 | should "create a Vista System" do 29 | Sprout::Platform.any_instance.stubs(:ruby_platform).returns "vista" 30 | assert Sprout::System.create.is_a?(Sprout::System::VistaUser) 31 | assert Sprout::System.create.is_a?(Sprout::System::WinUser) 32 | end 33 | end 34 | 35 | ['solaris', 'redhat', 'ubuntu'].each do |variant| 36 | context variant do 37 | 38 | setup do 39 | @success_exec = File.join(fixtures, 'process_runner', 'success') 40 | @failure_exec = File.join(fixtures, 'process_runner', 'failure') 41 | @system = Sprout::System::UnixUser.new 42 | @process = FakeProcessRunner.new 43 | # Allows this test to run on Windows: 44 | @system.stubs(:get_process_runner).returns @process 45 | end 46 | 47 | should "create a Unix System" do 48 | Sprout::Platform.any_instance.stubs(:ruby_platform).returns variant 49 | assert Sprout::System.create.is_a?(Sprout::System::UnixUser) 50 | end 51 | 52 | should "execute external processes" do 53 | @system.execute @success_exec 54 | end 55 | 56 | should "handle execution errors" do 57 | # Write to the fake error stream: 58 | @process.read_err.write "Forced Error For test" 59 | assert_raises Sprout::Errors::ExecutionError do 60 | @system.execute @failure_exec 61 | end 62 | end 63 | end 64 | end 65 | 66 | context "osx" do 67 | should "create an OSX System" do 68 | Sprout::Platform.any_instance.stubs(:ruby_platform).returns "darwin" 69 | assert Sprout::System.create.is_a?(Sprout::System::OSXUser) 70 | end 71 | end 72 | 73 | context "java" do 74 | should "create a Java System" do 75 | Sprout::Platform.any_instance.stubs(:ruby_platform).returns "java" 76 | assert Sprout::System.create.is_a?(Sprout::System::JavaUser) 77 | end 78 | end 79 | 80 | context "any system" do 81 | 82 | setup do 83 | @system = Sprout::System::UnixUser.new 84 | end 85 | 86 | context "library path" do 87 | 88 | should "match the home path" do 89 | assert_not_nil @system.library 90 | assert_equal @system.home, @system.library 91 | end 92 | end 93 | 94 | context "home path" do 95 | 96 | setup do 97 | # Block all of the automatic path introspection: 98 | [ 99 | :env_userprofile, 100 | :env_home, 101 | :env_homedrive, 102 | :env_homepath, 103 | :tilde_home, 104 | :alt_separator? 105 | ].each do |accessor| 106 | @system.stubs(accessor).returns nil 107 | end 108 | end 109 | 110 | should "use env HOME" do 111 | @system.expects(:env_home).returns "abc" 112 | assert_equal 'abc', @system.home 113 | end 114 | 115 | should "use the env USERPROFILE" do 116 | @system.expects(:env_userprofile).returns "abc" 117 | assert_equal 'abc', @system.home 118 | end 119 | 120 | should "use the env HOMEPATH" do 121 | @system.expects(:env_homedrive).returns "c" 122 | @system.expects(:env_homepath).returns "abc" 123 | assert_equal 'c:abc', @system.home 124 | end 125 | 126 | should "use ~" do 127 | @system.expects(:tilde_home).returns "abc" 128 | assert_equal 'abc', @system.home 129 | end 130 | 131 | should "fallback to C drive" do 132 | @system.expects(:tilde_home).raises StandardError.new 133 | @system.expects(:alt_separator?).returns true 134 | assert_equal "C:\\", @system.home 135 | end 136 | 137 | should "fallback to unix root" do 138 | @system.expects(:tilde_home).raises StandardError.new 139 | @system.expects(:alt_separator?).returns false 140 | assert_equal "/", @system.home 141 | end 142 | end 143 | 144 | end 145 | =end 146 | end 147 | 148 | -------------------------------------------------------------------------------- /test/unit/vista_system_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class VistaSystemTest < Test::Unit::TestCase 4 | include Sprout::TestHelper 5 | 6 | context "new windows vista system" do 7 | 8 | setup do 9 | @user_system = Sprout::System::VistaSystem.new 10 | end 11 | 12 | should "work when env_userprofile isn't found" do 13 | @user_system.stubs(:find_home).returns 'C:\Documents and Settings\Some System' 14 | File.stubs(:exists?).returns true 15 | assert_equal 'C:\Documents and Settings\Some System/Local Settings/Application Data', @user_system.library 16 | end 17 | 18 | context "with a valid userprofile" do 19 | 20 | setup do 21 | @user_system.stubs(:env_userprofile).returns '/somehome' 22 | end 23 | 24 | should "find library" do 25 | File.stubs(:exists?).returns true 26 | assert_equal '/somehome/Local Settings/Application Data', @user_system.library 27 | end 28 | 29 | should "wrap paths that have spaces with escaped quotes" do 30 | assert_equal "\"foo bar\"", @user_system.clean_path("foo bar") 31 | end 32 | 33 | should "not modify paths that have no spaced" do 34 | assert_equal "foobar", @user_system.clean_path("foobar") 35 | end 36 | end 37 | 38 | end 39 | end 40 | 41 | -------------------------------------------------------------------------------- /test/unit/win_nix_system_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class WinNixSystemTest < Test::Unit::TestCase 4 | include Sprout::TestHelper 5 | 6 | context "new windows nix (cygwin/mingw) system" do 7 | 8 | setup do 9 | @sys = Sprout::System::WinNixSystem.new 10 | @sys.stubs(:win_home).returns 'C:\Documents and Settings\Some System' 11 | end 12 | 13 | should "find home on cygwin" do 14 | File.stubs(:exists?).returns false 15 | assert_equal '/cygdrive/c/Documents and Settings/Some System', @sys.home 16 | end 17 | 18 | should "find home on mingw" do 19 | File.stubs(:exists?).returns true 20 | assert_equal 'C:/Documents and Settings/Some System', @sys.home 21 | end 22 | 23 | should "wrap paths that have spaces with escaped quotes" do 24 | assert_equal "\"foo bar\"", @sys.clean_path("foo bar") 25 | end 26 | 27 | should "not modify paths that have no spaced" do 28 | assert_equal "foobar", @sys.clean_path("foobar") 29 | end 30 | end 31 | end 32 | 33 | -------------------------------------------------------------------------------- /test/unit/win_system_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class WinSystemTest < Test::Unit::TestCase 4 | include Sprout::TestHelper 5 | 6 | context "new windows system" do 7 | 8 | setup do 9 | @user = Sprout::System::WinSystem.new 10 | end 11 | 12 | should "not accept home path with My Documents" do 13 | @user.stubs(:find_home).returns File.join('C:', 'foo', 'My Documents') 14 | assert_equal File.join('C:', 'foo'), @user.home 15 | end 16 | 17 | should "return env_path" do 18 | @user.stubs(:env_path).returns "a;b;c;" 19 | assert_equal ['a', 'b', 'c'], @user.get_paths 20 | end 21 | 22 | should "execute with correct implementation" do 23 | @echochamber = File.join fixtures, 'remote_file_target', 'bin', 'echochamber' 24 | # Don't actually call the win32 execute function: 25 | r = StringIO.new 26 | w = StringIO.new 27 | e = StringIO.new 28 | pid = nil 29 | Sprout::ProcessRunner.any_instance.expects(:io_popen_block).returns([pid, w, r, e]) 30 | @user.stubs(:clean_path).returns @echochamber 31 | @user.execute @echochamber 32 | end 33 | 34 | context "with home already set" do 35 | 36 | setup do 37 | @user.stubs(:home).returns 'C:\Documents and Settings\Some System' 38 | end 39 | 40 | should "find library" do 41 | File.stubs(:exists?).returns true 42 | assert_matches /Local Settings\/Application Data/, @user.library 43 | end 44 | 45 | should "find library outside home" do 46 | File.stubs(:exists?).returns false 47 | assert (@user.library =~ /Application Data/).nil?, "Shouldn't use app data if it doesn't exist" 48 | end 49 | 50 | should "wrap paths that have spaces with escaped quotes" do 51 | assert_equal "\"foo bar\"", @user.clean_path("foo bar") 52 | end 53 | 54 | should "not modify paths that have no spaced" do 55 | assert_equal "foobar", @user.clean_path("foobar") 56 | end 57 | end 58 | 59 | end 60 | end 61 | 62 | --------------------------------------------------------------------------------