diff --git a/docs/user-guide/cli.md b/docs/user-guide/cli.md index 11476e45..9a5ed094 100644 --- a/docs/user-guide/cli.md +++ b/docs/user-guide/cli.md @@ -226,6 +226,38 @@ Output: [ ✓ ] [ 1m 0s ] Deployment d-M4FY304KE completed successfully! ``` +## List Builds + +List all the builds from your S3 artifact repository. + +|Description|Long Form|Short Form|Type|Example|Default| +|---|---|---|---|---|---| +|Limit Results|limit|l|numeric||10| +|Filter Results|filter||string|v1.0|| +|Interactive Logger|interactive_logger||boolean||true| +|Verbose|verbose|v|boolean||false| + +Example: + +```shell +./bin/environment list-builds --limit 1 --filter v1.0 +``` + +Output: + +```shell +┌─ Builds +│ +│ 2016-03-03 13:52:30 UTC my-aws-account release-v1.0.0 4.96 MB +│ +└── +``` + +Output format is the following: + +|Last Modified|Owner Account|Build Name (S3 Key)|Size| +|---|---|---|---| + ## Delete Delete an existing environment. diff --git a/lib/moonshot/artifact_repository/s3_bucket.rb b/lib/moonshot/artifact_repository/s3_bucket.rb index 50b0f52f..4f6fd353 100644 --- a/lib/moonshot/artifact_repository/s3_bucket.rb +++ b/lib/moonshot/artifact_repository/s3_bucket.rb @@ -1,3 +1,6 @@ +require 'moonshot/unicode_table' +require 'moonshot/s3_builds_printer' + # The S3Bucket stores builds in an S3 Bucket. # # For example: @@ -35,6 +38,13 @@ def filename_for_version(version_name) "#{version_name}.tar.gz" end + def list_builds_hook(limit, filter) + builds = list_builds + t = Moonshot::UnicodeTable.new('') + Moonshot::S3BuildsPrinter.new(builds, limit, filter, t).print + t.draw_children + end + private def upload_to_s3(file, key) @@ -46,6 +56,13 @@ def upload_to_s3(file, key) ) end + def list_builds + resp = s3_client.list_objects( + bucket: @bucket_name + ) + resp.contents + end + def doctor_check_bucket_exists s3_client.get_bucket_location(bucket: @bucket_name) success "Bucket '#{@bucket_name}' exists." diff --git a/lib/moonshot/cli.rb b/lib/moonshot/cli.rb index e2186dde..5a67b953 100644 --- a/lib/moonshot/cli.rb +++ b/lib/moonshot/cli.rb @@ -131,6 +131,15 @@ def deploy_version(version_name) controller.deploy_version(version_name) end + desc 'list-builds', 'List available builds from your artifact repository.' # rubocop:disable LineLength + option :limit, type: :numeric, default: 10, aliases: '-l', + desc: 'Limit the number of results. 0 stands for no limit.' + option :filter, type: :string, desc: 'Filter the builds by providing a name or part of a name.' + def list_builds + raise Thor::Error, 'Please provide a valid integer for "--limit".' unless options[:limit].is_a? Integer # rubocop:disable LineLength + controller.list_builds(options[:limit], options[:filter]) + end + desc :delete, 'Delete an existing environment.' option :show_all_events, desc: 'Show all stack events during update. (Default: errors only)' def delete diff --git a/lib/moonshot/controller.rb b/lib/moonshot/controller.rb index e61d4a85..4754b186 100644 --- a/lib/moonshot/controller.rb +++ b/lib/moonshot/controller.rb @@ -56,6 +56,11 @@ def deploy_version(version_name) run_plugins(:post_deploy) end + def list_builds(limit, filter) + run_plugins(:list_builds) + run_hook(:repo, :list_builds, limit, filter) + end + def delete run_plugins(:pre_delete) run_hook(:deploy, :pre_delete) diff --git a/lib/moonshot/s3_builds_printer.rb b/lib/moonshot/s3_builds_printer.rb new file mode 100644 index 00000000..13a62e53 --- /dev/null +++ b/lib/moonshot/s3_builds_printer.rb @@ -0,0 +1,43 @@ +# coding: utf-8 +require 'colorize' + +module Moonshot + # Display a list of builds for the user. + class S3BuildsPrinter + def initialize(builds, limit, filter, table) + @builds = builds + @limit = limit + @filter = filter + @table = table + end + + def print + t = @table.add_leaf('Builds') + + builds = @builds.sort_by(&:last_modified).reverse + builds.select! { |build| build.key.include?(@filter) } if @filter + builds = builds.first(@limit) unless @limit == 0 + + if builds.count == 0 + t.add_line('No builds were found with the provided parameters.'.red) + end + + rows = builds.map do |build| + row_for_build(build) + end + + t.add_table(rows) + end + + private + + def row_for_build(build) + [ + build.last_modified.to_s.light_black, + build.owner.display_name.light_blue, + build.key.chomp('.tar.gz'), + ((build.size * 1.0 / (1024 * 1024)).round(2).to_s << ' MB').light_yellow + ] + end + end +end