class Simp::Rake::Build::Deps

Public Class Methods

new( base_dir ) click to toggle source
# File lib/simp/rake/build/deps.rb, line 184
def initialize( base_dir )
  @base_dir = base_dir
  @verbose = ENV.fetch('SIMP_PKG_verbose','no') == 'yes'
  define_tasks
end

Public Instance Methods

define_tasks() click to toggle source
# File lib/simp/rake/build/deps.rb, line 190
    def define_tasks
      namespace :deps do
        desc <<-EOM
        Checks out all dependency repos.

        This task used R10k to update all dependencies.

        Arguments:
          * :method  => The update method to use (Default => 'tracking')
               tracking => checks out each dep (by branch) according to Puppetfile.tracking
               stable   => checks out each dep (by ref) according to in Puppetfile.stable
        EOM
        task :checkout, [:method] do |t,args|
          args.with_defaults(:method => 'tracking')

          r10k_helper = R10KHelper.new("Puppetfile.#{args[:method]}")

          r10k_issues = Parallel.map(
            Array(r10k_helper.modules),
            :in_processes => get_cpu_limit,
            :progress => 'Submodule Checkout'
          ) do |mod|
            issues = []

            Dir.chdir(@base_dir) do
              unless File.directory?(mod[:path])
                FileUtils.mkdir_p(mod[:path])
              end

              # Only for known modules...
              unless mod[:status] == :unknown
                # Since r10k is destructive, we're enumerating all valid states
                if [
                    :absent,
                    :mismatched,
                    :outdated,
                    :insync,
                    :dirty
                ].include?(mod[:r10k_module].status)
                  unless mod[:r10k_cache].synced?
                    mod[:r10k_cache].sync
                  end

                  if mod[:status] == :known
                    mod[:r10k_module].sync
                  else
                    # If we get here, the module was dirty and should be skipped
                    issues << "#{mod[:name]}: Skipped - #{mod[:status]}"
                    next
                  end
                else
                  issues << "#{mod[:name]}: Skipped - Unknown status type #{mod[:r10k_module].status}"
                end
              end
            end

            issues
          end

          r10k_issues.flatten!

          unless r10k_issues.empty?
            $stderr.puts('='*80)

            unless @verbose
              $stderr.puts('Warning: Some repositories were skipped!')
              $stderr.puts('  * If this is a fresh build, this could be an issue')
              $stderr.puts('  * This is expected if re-running a build')
              $stderr.puts('  * Run with SIMP_PKG_verbose=yes for full details')
            else
              $stderr.puts("R10k Checkout Issues:")
              r10k_issues.each do |issue|
                $stderr.puts("  * #{issue}")
              end
            end

            $stderr.puts('='*80)
          end
        end

        desc <<-EOM
        Get the status of the project Git repositories

        Arguments:
          * :method  => The update method to use (Default => 'tracking')
               tracking => checks out each dep (by branch) according to Puppetfile.tracking
               stable   => checks out each dep (by ref) according to in Puppetfile.stable
        EOM
        task :status, [:method] do |t,args|
          args.with_defaults(:method => 'tracking')
          @dirty_repos = nil

          r10k_helper = R10KHelper.new("Puppetfile.#{args[:method]}")

          mods_with_changes = {}

          r10k_helper.each_module do |mod|
            unless File.directory?(mod[:path])
              $stderr.puts("Warning: '#{mod[:path]}' is not a module...skipping") if File.exist?(mod[:path])
              next
            end

            if mod[:status] != :known
              # Clean up the path a bit for printing
              dirty_path = mod[:path].split(r10k_helper.basedir.to_s).last
              if dirty_path[0].chr == File::SEPARATOR
                dirty_path[0] = ''
              end

              mods_with_changes[mod[:name]] = dirty_path
            end
          end

          if mods_with_changes.empty?
            puts "No repositories have changes."
            @dirty_repos = false
          else
            puts "The following repositories have changes:"
            puts mods_with_changes.map{|k,v| "  + #{k} => #{v}"}.join("\n")

            @dirty_repos = true
          end

          unknown_mods = r10k_helper.unknown_modules
          unless unknown_mods.empty?
            puts "The following modules were unknown:"
            puts unknown_mods.map{|k,v| "  ? #{k}"}.join("\n")
          end
        end

        desc <<-EOM
        Records the current dependencies into Puppetfile.stable.

        Arguments:
          * :method    => Save to Puppetfile.[method] (Default => 'stable')
          * :reference => Use Puppetfile.[reference] to reference which repos
                          should be recorded (Default => 'tracking')
        EOM
        task :record, [:method,:reference] do |t,args|
          args.with_defaults(:method => 'stable')
          args.with_defaults(:reference => 'tracking')

          r10k_helper = R10KHelper.new("Puppetfile.#{args[:reference]}")
          File.open("Puppetfile.#{args[:method]}",'w'){|f| f.puts r10k_helper.puppetfile }
        end

        desc <<-EOM
        Provide a log of changes to all modules from the given top level Git reference.

        Arguments:
          * :ref => The top level git ref to use as the oldest point for all logs.
          * :source => The source Puppetfile to use (Default => 'tracking')
        EOM
        task :changelog, [:ref] do |t,args|
          args.with_defaults(:source => 'tracking')

          r10k_helper = R10KHelper.new("Puppetfile.#{args[:source]}")

          git_logs = Hash.new

          Dir.chdir(r10k_helper.basedir) do
            ref = args[:ref]
            refdate = nil
            begin
              refdate = %x(git log -1 --format=%ai '#{ref}')
              refdate = nil unless $?.success?
            rescue Exception
              #noop
            end

            fail("You must specify a valid reference") unless ref
            fail("Could not find a Git log for #{ref}") unless refdate

            mods_with_changes = {}

            log_output = %x(git log --since='#{refdate}' --stat --reverse).chomp
            git_logs['__SIMP CORE__'] = log_output unless log_output.strip.empty?

            r10k_helper.each_module do |mod|
              if File.directory?(mod[:path])
                Dir.chdir(mod[:path]) do
                  log_output = %x(git log --since='#{refdate}' --stat --reverse).chomp
                  git_logs[mod[:name]] = log_output unless log_output.strip.empty?
                end
              end
            end

            if git_logs.empty?
              puts( "No changes found for any components since #{refdate}")
            else
              page

              git_logs.keys.sort.each do |mod_name|
                puts <<-EOM
  ========
  #{mod_name}:

  #{git_logs[mod_name].gsub(/^/,'  ')}

                EOM
              end
            end
          end
        end
      end
    end