Module: SupermarketSync::Sync

Defined in:
lib/supermarket_sync/sync.rb

Overview

> Supermarket Synchronization Logic Controller

Class Method Summary collapse

Class Method Details

.run!Object

rubocop: disable AbcSize, CyclomaticComplexity, MethodLength, PerceivedComplexity



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/supermarket_sync/sync.rb', line 26

def run! # rubocop: disable AbcSize, CyclomaticComplexity, MethodLength, PerceivedComplexity
  Config.supermarkets.each do |name, cfg| # rubocop: disable BlockLength
    puts "Synchronizing #{name}"

    # => Set Configuration
    configure(cfg)

    # => Parse the Cookbooks List
    cookbooks = Array(Util.parse_json(Config.cookbooks_file)[:cookbooks])

    cookbooks.each do |cookbook| # rubocop: disable BlockLength
      cookbook = cookbook.keys.first if cookbook.is_a?(Hash)
      puts "Checking #{cookbook}"
      # => Grab Source Metadata
      source_meta = begin
                      src.get("/api/v1/cookbooks/#{cookbook}")
                    rescue Net::HTTPServerException => e
                      raise e unless e.response.code == '404'
                      puts 'Cookbook not available on Source Supermarket'
                      next
                    end
      # => Grab Latest Available Version Number
      latest = ::Gem::Version.new(::File.basename(source_meta['latest_version']))

      # => Grab Destination Metadata
      dest_meta = begin
                    dest.get("/api/v1/cookbooks/#{cookbook}")
                  rescue Net::HTTPServerException => e
                    raise e unless e.response.code == '404'
                    # => Cookbook not found -- Initial Upload
                    { 'latest_version' => '0.0.0' }
                  end
      # => Determine Current Version
      current = ::Gem::Version.new(::File.basename(dest_meta['latest_version']))

      if latest > current
        puts 'Updating...'
        puts "Source: #{latest}"
        puts "Destination: #{current}"

        # => Retrieve the Cookbook
        tgz = src.streaming_request("/api/v1/cookbooks/#{cookbook}/versions/#{latest}/download")

        # => Upload the Cookbook
        upload('other', tgz) unless Config.read_only

        # => Remove the Tempfile
        begin
          retries ||= 2
          ::File.delete(tgz)
        rescue => e # rubocop: disable RescueStandardError
          raise e if (retries -= 1).negative?
          puts "#{e.class}::#{e.message}"
          puts 'Could not delete Tempfile... Retrying'
          sleep 2
          retry
        end
        @notify&.updated&.push(source: source_meta, dest: dest_meta)
      end
      # => Identify Deprecated Cookbooks
      next unless source_meta['deprecated'] && !dest_meta['deprecated']
      @notify&.deprecated&.push(source: source_meta, dest: dest_meta)
    end
  ensure
    # => Send Notifications
    @notify&.send!
  end
end

.src(url = nil) ⇒ Object

> API Clients

Raises:

  • (ArgumentError)


122
123
124
125
126
127
# File 'lib/supermarket_sync/sync.rb', line 122

def src(url = nil)
  url ||= @src&.url
  raise ArgumentError, 'No URL supplied!' unless url
  return @src if @src&.url == url
  @src = Chef::HTTP::SimpleJSON.new(url)
end