rbuilder 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Rakefile +47 -0
- data/bin/rbuilder +65 -0
- data/conf/example.conf +2 -0
- data/rbuilder/build.rb +50 -0
- data/rbuilder/build_command.rb +33 -0
- data/rbuilder/build_configuration.rb +21 -0
- data/rbuilder/build_description.rb +46 -0
- data/rbuilder/build_report.rb +40 -0
- data/rbuilder/build_status.rb +39 -0
- data/rbuilder/builder.rb +45 -0
- data/rbuilder/gui.rb +6 -0
- data/rbuilder/gui/build_details_pane.rb +105 -0
- data/rbuilder/gui/build_list_view_entry.rb +33 -0
- data/rbuilder/gui/builder_list_view.rb +92 -0
- data/rbuilder/gui/builder_monitor_window.rb +112 -0
- data/rbuilder/gui/images.rb +5 -0
- data/rbuilder/gui/images/broken_builder.gif +0 -0
- data/rbuilder/gui/images/building.gif +0 -0
- data/rbuilder/gui/images/failed.gif +0 -0
- data/rbuilder/gui/images/ok.gif +0 -0
- data/rbuilder/gui/images/ok_builder.gif +0 -0
- data/rbuilder/lib/observer.rb +7 -0
- data/rbuilder/libs.rb +4 -0
- data/rbuilder/revision_committed.rb +21 -0
- data/rbuilder/source_control.rb +3 -0
- data/rbuilder/source_control/status.rb +23 -0
- data/rbuilder/source_control/svn.rb +64 -0
- data/rbuilder/source_control/tracker.rb +36 -0
- data/tests/gui/test_build_details_pane.rb +118 -0
- data/tests/gui/test_builder_list_view.rb +202 -0
- data/tests/gui/test_builder_list_view_entry.rb +79 -0
- data/tests/gui/test_builder_monitor_window.rb +81 -0
- data/tests/source_control/test_source_control.rb +52 -0
- data/tests/source_control/test_svn.rb +60 -0
- data/tests/test_build.rb +111 -0
- data/tests/test_build_command.rb +57 -0
- data/tests/test_build_configuration.rb +31 -0
- data/tests/test_build_description.rb +106 -0
- data/tests/test_build_report.rb +56 -0
- data/tests/test_builder.rb +54 -0
- data/tests/test_revision_comitted.rb +30 -0
- metadata +104 -0
    
        data/Rakefile
    ADDED
    
    | @@ -0,0 +1,47 @@ | |
| 1 | 
            +
            require 'rubygems'
         | 
| 2 | 
            +
            Gem::manage_gems
         | 
| 3 | 
            +
            require 'rake/gempackagetask'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
             desc 'Running all unit tests'
         | 
| 6 | 
            +
             task :default => :test
         | 
| 7 | 
            +
             task :test do
         | 
| 8 | 
            +
                test_files = ['tests/**/test*.rb', 'tests/test*.rb']
         | 
| 9 | 
            +
                test_files.each do |file_set|
         | 
| 10 | 
            +
                    Dir[file_set].each do |testfile| 
         | 
| 11 | 
            +
                        require testfile
         | 
| 12 | 
            +
                    end
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
             end
         | 
| 15 | 
            +
             
         | 
| 16 | 
            +
             desc 'Measures test coverage'
         | 
| 17 | 
            +
             task :coverage do
         | 
| 18 | 
            +
                 rm_f "coverage"
         | 
| 19 | 
            +
                 rm_f "coverage.data"
         | 
| 20 | 
            +
                 rcov = "rcov --aggregate coverage.data"
         | 
| 21 | 
            +
                 system("#{rcov} --html tests/test*.rb")
         | 
| 22 | 
            +
                 system("#{rcov} --html tests/**/test*.rb")
         | 
| 23 | 
            +
             end
         | 
| 24 | 
            +
             
         | 
| 25 | 
            +
             
         | 
| 26 | 
            +
             spec = Gem::Specification.new do |s| 
         | 
| 27 | 
            +
              s.name = "rbuilder"
         | 
| 28 | 
            +
              s.version = "0.0.1"
         | 
| 29 | 
            +
              s.author = "Rob Westgeest"
         | 
| 30 | 
            +
              s.email = "rob.westgeest@gmail.com"
         | 
| 31 | 
            +
              s.homepage = "http://notaresource.blogspot.com/rbuilder"
         | 
| 32 | 
            +
              s.platform = Gem::Platform::RUBY
         | 
| 33 | 
            +
              s.summary = "A Ruby auto build tool like build-o-matic for running on a desktop pc"
         | 
| 34 | 
            +
              s.files = FileList["Rakefile", "conf/example.conf", "{bin}/*","{rbuilder}/**/*"].to_a
         | 
| 35 | 
            +
              s.test_files = FileList["{tests}/test*.rb","{tests}/**/test_*.rb"].to_a
         | 
| 36 | 
            +
              s.has_rdoc = true
         | 
| 37 | 
            +
              s.require_path = 'rbuilder'
         | 
| 38 | 
            +
              s.executables << 'rbuilder'
         | 
| 39 | 
            +
              s.add_dependency("mocha", ">= 0.5.5")
         | 
| 40 | 
            +
            end
         | 
| 41 | 
            +
             
         | 
| 42 | 
            +
            Rake::GemPackageTask.new(spec) do |pkg| 
         | 
| 43 | 
            +
              rm_f "pkg"
         | 
| 44 | 
            +
              pkg.need_tar = true 
         | 
| 45 | 
            +
            end 
         | 
| 46 | 
            +
             | 
| 47 | 
            +
             
         | 
    
        data/bin/rbuilder
    ADDED
    
    | @@ -0,0 +1,65 @@ | |
| 1 | 
            +
            #!/usr/bin/env ruby
         | 
| 2 | 
            +
            $: << File.join(File.expand_path(File.dirname(__FILE__)),'..','rbuilder')
         | 
| 3 | 
            +
            require 'libs'
         | 
| 4 | 
            +
            require 'gui'
         | 
| 5 | 
            +
            require 'optparse'
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            USAGE_MESSAGE = %Q{
         | 
| 8 | 
            +
            usage #{$0} <working_dir> <build_command>
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            This program is an automatic builder for any build environment 
         | 
| 11 | 
            +
            (ant, make, rake... the lot). It accepts parameters for the 
         | 
| 12 | 
            +
            working directory and the build command. It assumes that the 
         | 
| 13 | 
            +
            working directory is a check-out of the archive that you are 
         | 
| 14 | 
            +
            working on and that the environment is subversion. It uses 
         | 
| 15 | 
            +
            svn commandline commands to get information on the archive and to poll
         | 
| 16 | 
            +
            wether anything has changed in the archive.
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            If the subversion archive has been changed, a build will start 
         | 
| 19 | 
            +
            and reported in the gui of this program. The build command will 
         | 
| 20 | 
            +
            be executed in the working directory (i.e. probably the root of 
         | 
| 21 | 
            +
            your archive where the build files are expected to reside). 
         | 
| 22 | 
            +
            Your command would probably just be something simple like 'rake' 
         | 
| 23 | 
            +
            or 'make' or 'ant' but can be anything.
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            The build command is expected to have an exit value of 0 when 
         | 
| 26 | 
            +
            the build is successfull and anything else when the build is 
         | 
| 27 | 
            +
            not successfull.
         | 
| 28 | 
            +
            }
         | 
| 29 | 
            +
             | 
| 30 | 
            +
            def usage 
         | 
| 31 | 
            +
                puts USAGE_MESSAGE
         | 
| 32 | 
            +
                exit(1)
         | 
| 33 | 
            +
            end
         | 
| 34 | 
            +
                
         | 
| 35 | 
            +
            configuration_file = nil
         | 
| 36 | 
            +
            parser = OptionParser.new do |opts|
         | 
| 37 | 
            +
                opts.banner = USAGE_MESSAGE
         | 
| 38 | 
            +
                opts.on("-h", '--help', "show this message") { usage }
         | 
| 39 | 
            +
                opts.on("-c", '--configfile file', "use configuration file ") { |file| configuration_file = file }
         | 
| 40 | 
            +
            end 
         | 
| 41 | 
            +
                
         | 
| 42 | 
            +
            rest = parser.parse ARGV
         | 
| 43 | 
            +
            usage unless configuration_file || (rest[0] && rest[1])
         | 
| 44 | 
            +
             | 
| 45 | 
            +
            builder = Builder.new
         | 
| 46 | 
            +
            build_configuration = BuildConfiguration.new(builder)
         | 
| 47 | 
            +
             
         | 
| 48 | 
            +
            if configuration_file 
         | 
| 49 | 
            +
                build_configuration.from_file(configuration_file)
         | 
| 50 | 
            +
            else
         | 
| 51 | 
            +
                working_dir  = rest[0]
         | 
| 52 | 
            +
                build_command = rest[1]
         | 
| 53 | 
            +
                build_configuration.build(working_dir, build_command)
         | 
| 54 | 
            +
            end
         | 
| 55 | 
            +
             
         | 
| 56 | 
            +
            list_view = Gui::BuilderListView.new(builder)
         | 
| 57 | 
            +
            details_pane = Gui::BuildDetailsPane.new(Build.new(nil,nil,nil))
         | 
| 58 | 
            +
            view = Gui::BuilderMonitorWindow.new(builder,list_view,details_pane)
         | 
| 59 | 
            +
            view.show
         | 
| 60 | 
            +
                
         | 
| 61 | 
            +
            Thread.start do  
         | 
| 62 | 
            +
                builder.run
         | 
| 63 | 
            +
            end
         | 
| 64 | 
            +
            Gtk.main
         | 
| 65 | 
            +
                
         | 
    
        data/conf/example.conf
    ADDED
    
    
    
        data/rbuilder/build.rb
    ADDED
    
    | @@ -0,0 +1,50 @@ | |
| 1 | 
            +
            require 'lib/observer'
         | 
| 2 | 
            +
            require 'build_report'
         | 
| 3 | 
            +
            class Build
         | 
| 4 | 
            +
                include Observable
         | 
| 5 | 
            +
                
         | 
| 6 | 
            +
                attr_reader :reason, :report, :archive
         | 
| 7 | 
            +
                
         | 
| 8 | 
            +
                def initialize(build_command, working_dir, reason, archive = '')
         | 
| 9 | 
            +
                    @build_command = build_command
         | 
| 10 | 
            +
                    @working_dir = working_dir
         | 
| 11 | 
            +
                    @reason = reason
         | 
| 12 | 
            +
                    @report = BuildReport.new
         | 
| 13 | 
            +
                    @archive = archive
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
                
         | 
| 16 | 
            +
                def run
         | 
| 17 | 
            +
                    self.building=true
         | 
| 18 | 
            +
                    report.info("running build with reason #{reason}\n")
         | 
| 19 | 
            +
                    build_command.execute(working_dir, report)
         | 
| 20 | 
            +
                    self.building=false
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
                
         | 
| 23 | 
            +
                def status
         | 
| 24 | 
            +
                    return building && BuildStatus.building || report.status
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                def summary
         | 
| 28 | 
            +
                    return building && reason.to_s || report.summary
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
                
         | 
| 31 | 
            +
                def building=(value)
         | 
| 32 | 
            +
                    @building=value  
         | 
| 33 | 
            +
                    changed!
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
                
         | 
| 36 | 
            +
                def revision 
         | 
| 37 | 
            +
                    return reason.revision
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
                
         | 
| 40 | 
            +
                def committer 
         | 
| 41 | 
            +
                    return reason.committer
         | 
| 42 | 
            +
                end
         | 
| 43 | 
            +
                
         | 
| 44 | 
            +
                def green?  
         | 
| 45 | 
            +
                    status == BuildStatus.ok
         | 
| 46 | 
            +
                end
         | 
| 47 | 
            +
                
         | 
| 48 | 
            +
                private
         | 
| 49 | 
            +
                attr_reader :build_command, :working_dir, :building
         | 
| 50 | 
            +
            end
         | 
| @@ -0,0 +1,33 @@ | |
| 1 | 
            +
            require 'fileutils'
         | 
| 2 | 
            +
            class BuildCommand
         | 
| 3 | 
            +
                include FileUtils
         | 
| 4 | 
            +
                def initialize(commandline)
         | 
| 5 | 
            +
                    @commandline = commandline
         | 
| 6 | 
            +
                end
         | 
| 7 | 
            +
                
         | 
| 8 | 
            +
                def execute(working_dir, build_result)
         | 
| 9 | 
            +
                    cd working_dir do 
         | 
| 10 | 
            +
                        if run_command(build_result)
         | 
| 11 | 
            +
                            build_result.green
         | 
| 12 | 
            +
                        else
         | 
| 13 | 
            +
                            build_result.red
         | 
| 14 | 
            +
                        end
         | 
| 15 | 
            +
                    end
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
                
         | 
| 18 | 
            +
                def run_command(build_result)
         | 
| 19 | 
            +
                    puts "running '#{commandline}' in working dir '#{`pwd`.strip}'"
         | 
| 20 | 
            +
                    IO.popen commandline do |stdout|
         | 
| 21 | 
            +
                        while !stdout.eof?
         | 
| 22 | 
            +
                            line = stdout.readline
         | 
| 23 | 
            +
                            build_result.info(line)
         | 
| 24 | 
            +
                            puts line
         | 
| 25 | 
            +
                        end
         | 
| 26 | 
            +
                    end
         | 
| 27 | 
            +
                    return $? == 0
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
                    
         | 
| 30 | 
            +
                private 
         | 
| 31 | 
            +
                attr_reader :commandline
         | 
| 32 | 
            +
                
         | 
| 33 | 
            +
            end
         | 
| @@ -0,0 +1,21 @@ | |
| 1 | 
            +
            require 'source_control'
         | 
| 2 | 
            +
            require 'build_description'
         | 
| 3 | 
            +
            require 'build_command'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            class BuildConfiguration
         | 
| 6 | 
            +
                def initialize(builder)
         | 
| 7 | 
            +
                    @builder = builder
         | 
| 8 | 
            +
                end
         | 
| 9 | 
            +
                
         | 
| 10 | 
            +
                def build(dir, command)
         | 
| 11 | 
            +
                    @builder.add_description BuildDescription.new(BuildCommand.new(command), SourceControl.svn(dir))
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
                
         | 
| 14 | 
            +
                def from_text(text) 
         | 
| 15 | 
            +
                    instance_eval(text)
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
                
         | 
| 18 | 
            +
                def from_file(file)
         | 
| 19 | 
            +
                    from_text(File.read(file))
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
            end
         | 
| @@ -0,0 +1,46 @@ | |
| 1 | 
            +
            require 'build_status'
         | 
| 2 | 
            +
            require 'revision_committed'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            class BuildDescription
         | 
| 5 | 
            +
                include Observable
         | 
| 6 | 
            +
                attr_reader :builds
         | 
| 7 | 
            +
                
         | 
| 8 | 
            +
                def initialize(build_command, source_control)
         | 
| 9 | 
            +
                    @build_command = build_command
         | 
| 10 | 
            +
                    @builds = []
         | 
| 11 | 
            +
                    @source_control = source_control
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
                
         | 
| 14 | 
            +
                def status
         | 
| 15 | 
            +
                    return BuilderState.ok if builds.empty? || builds.last.green?
         | 
| 16 | 
            +
                    return BuilderState.broken 
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                def run_build(reason)
         | 
| 20 | 
            +
                    build = create_build(reason)
         | 
| 21 | 
            +
                    changed!(:new_build => build)
         | 
| 22 | 
            +
                    build.run
         | 
| 23 | 
            +
                    builds << build 
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
                
         | 
| 26 | 
            +
                def new_revision_committed(source_control_status)
         | 
| 27 | 
            +
                    run_build(RevisionCommitted.from_source_control_status(source_control_status))
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
                
         | 
| 30 | 
            +
                def create_build(reason)
         | 
| 31 | 
            +
                    Build.new(build_command, working_dir, reason, source_control.archive)
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
                
         | 
| 34 | 
            +
                def iterate
         | 
| 35 | 
            +
                    source_control.report_change_to(self)
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
                
         | 
| 38 | 
            +
                private
         | 
| 39 | 
            +
                
         | 
| 40 | 
            +
                def working_dir
         | 
| 41 | 
            +
                    source_control.working_dir
         | 
| 42 | 
            +
                end
         | 
| 43 | 
            +
                
         | 
| 44 | 
            +
                attr_reader :build_command, :source_control
         | 
| 45 | 
            +
                
         | 
| 46 | 
            +
            end
         | 
| @@ -0,0 +1,40 @@ | |
| 1 | 
            +
            require 'lib/observer'
         | 
| 2 | 
            +
            class BuildReport
         | 
| 3 | 
            +
                include Observable
         | 
| 4 | 
            +
                attr_reader :status
         | 
| 5 | 
            +
                
         | 
| 6 | 
            +
                def initialize(status = BuildStatus.ok)
         | 
| 7 | 
            +
                    @status = status
         | 
| 8 | 
            +
                    @loglines = []
         | 
| 9 | 
            +
                end
         | 
| 10 | 
            +
                
         | 
| 11 | 
            +
                def green
         | 
| 12 | 
            +
                    self.status = BuildStatus.ok
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
                
         | 
| 15 | 
            +
                def red
         | 
| 16 | 
            +
                    self.status = BuildStatus.failed
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
                
         | 
| 19 | 
            +
                def status=(new_value)
         | 
| 20 | 
            +
                    @status = new_value
         | 
| 21 | 
            +
                    changed!
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
                
         | 
| 24 | 
            +
                def info(line_of_output)
         | 
| 25 | 
            +
                    line_of_output = line_of_output.strip
         | 
| 26 | 
            +
                    loglines << line_of_output
         | 
| 27 | 
            +
                    changed! :log_line => line_of_output
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
                
         | 
| 30 | 
            +
                def summary 
         | 
| 31 | 
            +
                    loglines.last || ''
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
                    
         | 
| 34 | 
            +
                def log
         | 
| 35 | 
            +
                    loglines.join("\n")
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
                
         | 
| 38 | 
            +
                private 
         | 
| 39 | 
            +
                attr_reader :loglines
         | 
| 40 | 
            +
            end
         | 
| @@ -0,0 +1,39 @@ | |
| 1 | 
            +
                class BuilderState
         | 
| 2 | 
            +
                    def initialize(value)
         | 
| 3 | 
            +
                        @value = value
         | 
| 4 | 
            +
                    end
         | 
| 5 | 
            +
                    @@broken = BuilderState.new('broken')
         | 
| 6 | 
            +
                    @@ok = BuilderState.new('ok')
         | 
| 7 | 
            +
                    
         | 
| 8 | 
            +
                    def self.broken
         | 
| 9 | 
            +
                        return @@broken
         | 
| 10 | 
            +
                    end
         | 
| 11 | 
            +
                    
         | 
| 12 | 
            +
                    def self.ok
         | 
| 13 | 
            +
                        return @@ok
         | 
| 14 | 
            +
                    end
         | 
| 15 | 
            +
                    
         | 
| 16 | 
            +
                    def to_s
         | 
| 17 | 
            +
                        @value
         | 
| 18 | 
            +
                    end
         | 
| 19 | 
            +
                    alias_method :inspect, :to_s
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
                
         | 
| 22 | 
            +
                class BuildStatus
         | 
| 23 | 
            +
                    def initialize(value)
         | 
| 24 | 
            +
                        @value = value
         | 
| 25 | 
            +
                    end
         | 
| 26 | 
            +
                    @@ok = BuildStatus.new('ok')
         | 
| 27 | 
            +
                    @@failed = BuildStatus.new('failed')
         | 
| 28 | 
            +
                    @@building = BuildStatus.new('building')
         | 
| 29 | 
            +
                    
         | 
| 30 | 
            +
                    def self.ok; return @@ok; end
         | 
| 31 | 
            +
                    def self.failed; return @@failed; end
         | 
| 32 | 
            +
                    def self.building; return @@building; end
         | 
| 33 | 
            +
                    
         | 
| 34 | 
            +
                    def to_s
         | 
| 35 | 
            +
                        @value
         | 
| 36 | 
            +
                    end
         | 
| 37 | 
            +
                    alias_method :inspect, :to_s
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
                
         | 
    
        data/rbuilder/builder.rb
    ADDED
    
    | @@ -0,0 +1,45 @@ | |
| 1 | 
            +
            require 'lib/observer'
         | 
| 2 | 
            +
            require 'build_description'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            class Builder
         | 
| 5 | 
            +
                include Observable
         | 
| 6 | 
            +
                
         | 
| 7 | 
            +
                attr_reader :descriptions
         | 
| 8 | 
            +
                def initialize
         | 
| 9 | 
            +
                    @descriptions = []
         | 
| 10 | 
            +
                end
         | 
| 11 | 
            +
                
         | 
| 12 | 
            +
                def add_description(build_description)
         | 
| 13 | 
            +
                    descriptions << build_description
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
                
         | 
| 16 | 
            +
                def each_description(&block)
         | 
| 17 | 
            +
                    descriptions.each(&block)
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
                
         | 
| 20 | 
            +
                def iterate
         | 
| 21 | 
            +
                    descriptions.each {|description| iterate_description(description)}
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
                
         | 
| 24 | 
            +
                def iterate_description(desc)
         | 
| 25 | 
            +
                    desc.iterate
         | 
| 26 | 
            +
                    changed!
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
                
         | 
| 29 | 
            +
                def run 
         | 
| 30 | 
            +
                    while true
         | 
| 31 | 
            +
                        begin  
         | 
| 32 | 
            +
                            iterate
         | 
| 33 | 
            +
                        rescue Exception => e
         | 
| 34 | 
            +
                            puts e.to_s
         | 
| 35 | 
            +
                        end
         | 
| 36 | 
            +
                        sleep(5)
         | 
| 37 | 
            +
                    end 
         | 
| 38 | 
            +
                end 
         | 
| 39 | 
            +
                
         | 
| 40 | 
            +
                def status
         | 
| 41 | 
            +
                    descriptions.each {|description| return BuilderState.broken if description.status == BuilderState.broken}
         | 
| 42 | 
            +
                    return BuilderState.ok
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
            end
         | 
| 45 | 
            +
             | 
    
        data/rbuilder/gui.rb
    ADDED
    
    
| @@ -0,0 +1,105 @@ | |
| 1 | 
            +
            require 'gui/images'
         | 
| 2 | 
            +
            module Gui
         | 
| 3 | 
            +
                class LogWidget 
         | 
| 4 | 
            +
                    attr_reader :gtk_container
         | 
| 5 | 
            +
                    def initialize(build_report)
         | 
| 6 | 
            +
                        @gtk_container = Gtk::Frame.new "Build log" 
         | 
| 7 | 
            +
                        gtk_container.shadow_type = Gtk::SHADOW_IN
         | 
| 8 | 
            +
                        
         | 
| 9 | 
            +
                        gtk_container << window = Gtk::ScrolledWindow.new
         | 
| 10 | 
            +
                        window << @text_view = Gtk::TextView.new
         | 
| 11 | 
            +
                        text_view.editable = false
         | 
| 12 | 
            +
                        @build_report = build_report
         | 
| 13 | 
            +
                        build_report.add_observer(self)
         | 
| 14 | 
            +
                    end
         | 
| 15 | 
            +
                    
         | 
| 16 | 
            +
                    def attach_to(new_build_report)
         | 
| 17 | 
            +
                        build_report.delete_observer(self)
         | 
| 18 | 
            +
                        @build_report = new_build_report
         | 
| 19 | 
            +
                        build_report.add_observer(self)
         | 
| 20 | 
            +
                        update
         | 
| 21 | 
            +
                    end
         | 
| 22 | 
            +
                    
         | 
| 23 | 
            +
                    def update(options = {})
         | 
| 24 | 
            +
                        update_text(options[:log_line]) and return if options.has_key?(:log_line)
         | 
| 25 | 
            +
                        set_text(build_report.log)
         | 
| 26 | 
            +
                    end
         | 
| 27 | 
            +
                    
         | 
| 28 | 
            +
                    def update_text(line)
         | 
| 29 | 
            +
                        text_view.buffer.insert(text_view.buffer.end_iter, line + $/)
         | 
| 30 | 
            +
                    end
         | 
| 31 | 
            +
                    
         | 
| 32 | 
            +
                    def set_text(new_text)
         | 
| 33 | 
            +
                        text_view.buffer.text=new_text
         | 
| 34 | 
            +
                    end
         | 
| 35 | 
            +
                    
         | 
| 36 | 
            +
                    def text
         | 
| 37 | 
            +
                        text_view.buffer.text
         | 
| 38 | 
            +
                    end
         | 
| 39 | 
            +
                    
         | 
| 40 | 
            +
                    private 
         | 
| 41 | 
            +
                    attr_reader :build_report, :text_view
         | 
| 42 | 
            +
                end
         | 
| 43 | 
            +
                
         | 
| 44 | 
            +
                class StatusWidget 
         | 
| 45 | 
            +
                    Image = {BuildStatus.ok => Images.file('ok.gif'), BuildStatus.failed => Images.file('failed.gif'), BuildStatus.building => Images.file('building.gif')}
         | 
| 46 | 
            +
                    Image.default = ''
         | 
| 47 | 
            +
                    attr_reader :gtk_container
         | 
| 48 | 
            +
                    
         | 
| 49 | 
            +
                    def initialize(build_status)
         | 
| 50 | 
            +
                        @gtk_container = Gtk::Image.new(Image[build_status])
         | 
| 51 | 
            +
                    end
         | 
| 52 | 
            +
                    
         | 
| 53 | 
            +
                    def status=(new_status)
         | 
| 54 | 
            +
                        @gtk_container.file=Image[new_status]
         | 
| 55 | 
            +
                        
         | 
| 56 | 
            +
                    end
         | 
| 57 | 
            +
                end
         | 
| 58 | 
            +
                
         | 
| 59 | 
            +
                class BuildDetailsPane
         | 
| 60 | 
            +
                    attr_reader :build, :gtk_container
         | 
| 61 | 
            +
                    attr_reader :archive_label, :reason_label
         | 
| 62 | 
            +
                    def initialize(build, status_widget = nil, log_widget = nil)
         | 
| 63 | 
            +
                        @status_widget = status_widget || StatusWidget.new(build.status)
         | 
| 64 | 
            +
                        @log_widget = log_widget || LogWidget.new(build.report)
         | 
| 65 | 
            +
                        @archive_label = Gtk::Label.new
         | 
| 66 | 
            +
                        @reason_label = Gtk::Label.new
         | 
| 67 | 
            +
                        
         | 
| 68 | 
            +
                        @gtk_container = Gtk::VBox.new
         | 
| 69 | 
            +
                        add_label("builing archive:", archive_label)
         | 
| 70 | 
            +
                        add_label("    with reason:", reason_label)
         | 
| 71 | 
            +
                        @gtk_container.pack_start(@status_widget.gtk_container, false, false, 5)
         | 
| 72 | 
            +
                        @gtk_container.pack_start(@log_widget.gtk_container, true, true, 5)
         | 
| 73 | 
            +
                        
         | 
| 74 | 
            +
                        attach_to(build)
         | 
| 75 | 
            +
                        
         | 
| 76 | 
            +
                    end     
         | 
| 77 | 
            +
                    
         | 
| 78 | 
            +
                    def add_label(label_text, widget)
         | 
| 79 | 
            +
                        box = Gtk::HBox.new
         | 
| 80 | 
            +
                        label = Gtk::Label.new(label_text)
         | 
| 81 | 
            +
                        box.pack_start(label, false, false, 10)
         | 
| 82 | 
            +
                        box.pack_start(widget, false, false, 5)
         | 
| 83 | 
            +
                        gtk_container.pack_start(box, false, false, 5)
         | 
| 84 | 
            +
                    end
         | 
| 85 | 
            +
                    
         | 
| 86 | 
            +
                    def attach_to(new_build)
         | 
| 87 | 
            +
                        if (build)
         | 
| 88 | 
            +
                            build.delete_observer(self)
         | 
| 89 | 
            +
                        end
         | 
| 90 | 
            +
                        @build = new_build
         | 
| 91 | 
            +
                        build.add_observer(self)
         | 
| 92 | 
            +
                        log_widget.attach_to(build.report)
         | 
| 93 | 
            +
                        archive_label.text = build.archive
         | 
| 94 | 
            +
                        reason_label.text = build.reason.to_s
         | 
| 95 | 
            +
                        update
         | 
| 96 | 
            +
                    end
         | 
| 97 | 
            +
                    
         | 
| 98 | 
            +
                    def update
         | 
| 99 | 
            +
                        status_widget.status = build.status 
         | 
| 100 | 
            +
                    end
         | 
| 101 | 
            +
                    
         | 
| 102 | 
            +
                    private 
         | 
| 103 | 
            +
                    attr_reader :status_widget, :reason_widget, :log_widget
         | 
| 104 | 
            +
                end
         | 
| 105 | 
            +
            end
         |