Class: S3WebsiteDeploy::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/s3_website_deploy/client.rb

Defined Under Namespace

Classes: LocalFile, S3File

Instance Method Summary collapse

Constructor Details

#initialize(config, logger: Logger.new(STDOUT)) ⇒ Client

Returns a new instance of Client.



12
13
14
15
16
# File 'lib/s3_website_deploy/client.rb', line 12

def initialize(config, logger: Logger.new(STDOUT))
  @config = config
  @cache_policy = config.cache_policy
  @logger = logger
end

Instance Method Details

#delete_remote_file(remote_file) ⇒ Object



75
76
77
78
79
80
81
82
# File 'lib/s3_website_deploy/client.rb', line 75

def delete_remote_file(remote_file)
  return if @config.dryrun
  key = "#{@config.prefix}#{remote_file.path}"
  s3.delete_object(
    bucket: @config.bucket,
    key: key,
  )
end

#deploy(file_stats) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/s3_website_deploy/client.rb', line 39

def deploy(file_stats)
  file_stats.each do |path, stat|
    local_file = stat[:local]
    remote_file = stat[:remote]
    if local_file
      if !remote_file
        @logger.info("Creating: #{local_file.path}")
        deploy_local_file(local_file)
      elsif local_file.content_md5 != remote_file.etag
        @logger.info("Updating: #{local_file.path}")
        deploy_local_file(local_file)
      else
        @logger.info("Skip: #{local_file.path}")
      end
    elsif remote_file
      @logger.info("Deleting: #{remote_file.path}")
      delete_remote_file(remote_file)
    end
  end
end

#deploy_local_file(local_file) ⇒ Object



60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/s3_website_deploy/client.rb', line 60

def deploy_local_file(local_file)
  return if @config.dryrun
  key = "#{@config.prefix}#{local_file.path}"
  content_type = MiniMime.lookup_by_filename(local_file.path).content_type
  File.open(local_file.local_path, "rb") do |file|
    s3.put_object(
      body: file,
      bucket: @config.bucket,
      key: key,
      content_type: content_type,
      cache_control: @cache_policy.cache_control(local_file.path),
    )
  end
end

#fetch_file_statsObject



26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/s3_website_deploy/client.rb', line 26

def fetch_file_stats
  stats = {}

  source_files.each do |file|
    stats[file.path] = { local: file }
  end
  remote_files.each do |file|
    stats[file.path] ||= { }
    stats[file.path][:remote] = file
  end
  stats
end

#remote_filesObject



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/s3_website_deploy/client.rb', line 96

def remote_files
  files = []
  prefix_pathname = Pathname.new(@config.prefix)
  next_token = nil
  loop do
    res = s3.list_objects_v2(
      bucket: @config.bucket,
      prefix: @config.prefix,
      continuation_token: next_token,
    )
    res.contents.each do |content|
      pathname = Pathname.new(content.key)
      files << S3File.new(pathname.relative_path_from(prefix_pathname).to_s, JSON.parse(content.etag))
    end
    next_token = res.next_continuation_token
    break unless next_token
  end
  files
end

#runObject



18
19
20
21
22
23
24
# File 'lib/s3_website_deploy/client.rb', line 18

def run
  @logger.info("---- DRY RUN ----") if @config.dryrun
  @logger.info("Start deploying #{@config.source} -> s3://#{@config.bucket}/#{@config.prefix}")
  file_stats = fetch_file_stats
  deploy(file_stats)
  @logger.info("Finish deploying #{@config.source} -> s3://#{@config.bucket}/#{@config.prefix}")
end

#source_filesObject



84
85
86
87
88
89
90
91
92
93
94
# File 'lib/s3_website_deploy/client.rb', line 84

def source_files
  source_directory = Pathname.new(@config.source)
  files = []
  Pathname.glob(source_directory.join("**", "*").to_s).map do |pathname|
    next if pathname.directory?
    path = pathname.to_s
    content_md5 = Digest::MD5.hexdigest(File.binread(path))
    files << LocalFile.new(pathname.relative_path_from(source_directory).to_s, path, content_md5)
  end
  files
end