Skip to content
This repository has been archived by the owner on Jul 14, 2021. It is now read-only.

Extract Table Printing Logic #167

Merged
merged 5 commits into from
Sep 24, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
70 changes: 70 additions & 0 deletions lib/chef-dk/policyfile/reports/install.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#
# Copyright:: Copyright (c) 2014 Chef Software Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

require 'chef-dk/policyfile/reports/table_printer'

module ChefDK
module Policyfile
module Reports

class Install

attr_reader :ui
attr_reader :policyfile_compiler

def initialize(ui: nil, policyfile_compiler: nil)
@ui = ui
@policyfile_compiler = policyfile_compiler

@fixed_version_install_table = nil
@install_table = nil
end

def installing_fixed_version_cookbook(cookbook_spec)
verb = cookbook_spec.installed? ? "Using " : "Installing"
fixed_version_install_table.print_row(verb, cookbook_spec.name, cookbook_spec.version_constraint.to_s, "from #{cookbook_spec.source_type}")
end

def installing_cookbook(cookbook_spec)
verb = cookbook_spec.installed? ? "Using " : "Installing"
install_table.print_row(verb, cookbook_spec.name, cookbook_spec.version_constraint.version)
end

private

def fixed_version_install_table
@fixed_version_install_table ||= TablePrinter.new(ui) do |t|
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@adamedx down here, calling new() with a block that takes a value.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, nice. Hadn't really seen that use before, makes sense.

t.column(["Using", "Installing"])
t.column(policyfile_compiler.fixed_version_cookbooks_specs.keys)
t.column
t.column
end
end

def install_table
@install_table ||= TablePrinter.new(ui) do |t|
t.column(["Using", "Installing"])
t.column(policyfile_compiler.graph_solution.keys)
t.column(policyfile_compiler.graph_solution.values)
end
end

end
end
end
end

58 changes: 58 additions & 0 deletions lib/chef-dk/policyfile/reports/table_printer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#
# Copyright:: Copyright (c) 2014 Chef Software Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

module ChefDK
module Policyfile
module Reports

# Defines a table with a flexible number of columns and prints rows in
# the table. Columns are defined ahead of time, by calling the #column
# method, individual rows are printed by calling #print_row with the data
# for each cell.
class TablePrinter

attr_reader :ui

def initialize(ui)
@ui = ui
@column_widths = []

yield self
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whoa -- how is the caller using this?

end

# Defines a column. If a collection is given, it is mapped to an array
# of strings and the longest string is used as the left justify width
# for that column when rows are printed.
def column(collection = [])
@column_widths << (collection.map(&:to_s).map(&:size).max || 0)
end

# Print a row.
def print_row(*cells)
row = ""
cells.each_with_index do |cell_data, i|
row << cell_data.to_s.ljust(@column_widths[i])
row << " "
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may be personal preference, but when printing tables I think a tab (two spaces) between columns makes it more readable. Otherwise the row with the longest values in each column starts to read like a sentence.

end
ui.msg(row.strip)
end

end
end
end
end

70 changes: 70 additions & 0 deletions lib/chef-dk/policyfile/reports/upload.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#
# Copyright:: Copyright (c) 2014 Chef Software Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

require 'chef-dk/policyfile/reports/table_printer'

module ChefDK
module Policyfile
module Reports
class Upload

attr_reader :reused_cbs
attr_reader :uploaded_cbs
attr_reader :ui

def initialize(reused_cbs: [], uploaded_cbs: [], ui: nil)
@reused_cbs = reused_cbs
@uploaded_cbs = uploaded_cbs
@ui = ui

@justify_name_width = nil
@justify_version_width = nil
end

def show
reused_cbs.each do |cb_with_lock|
lock = cb_with_lock.lock
table.print_row("Using", lock.name, lock.version, "(#{lock.identifier[0,8]})")
end

uploaded_cbs.each do |cb_with_lock|
lock = cb_with_lock.lock
table.print_row("Uploaded", lock.name, lock.version, "(#{lock.identifier[0,8]})")
end
end

def table
@table ||= TablePrinter.new(ui) do |t|
t.column(%w[ Using Uploaded ])
t.column(cookbook_names)
t.column(cookbook_version_numbers)
t.column
end
end

def cookbook_names
(reused_cbs + uploaded_cbs).map { |e| e.lock.name }
end

def cookbook_version_numbers
(reused_cbs + uploaded_cbs).map { |e| e.lock.version }
end

end
end
end
end
50 changes: 2 additions & 48 deletions lib/chef-dk/policyfile/uploader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,60 +19,14 @@
require 'chef-dk/policyfile/read_cookbook_for_compat_mode_upload'

require 'chef-dk/ui'
require 'chef-dk/policyfile/reports/upload'

module ChefDK
module Policyfile
class Uploader

LockedCookbookForUpload = Struct.new(:cookbook, :lock)

class UploadReport

attr_reader :reused_cbs
attr_reader :uploaded_cbs
attr_reader :ui

def initialize(reused_cbs: [], uploaded_cbs: [], ui: nil)
@reused_cbs = reused_cbs
@uploaded_cbs = uploaded_cbs
@ui = ui

@justify_name_width = nil
@justify_version_width = nil
end

def show
reused_cbs.each do |cb_with_lock|
ui.msg("Using #{describe_lock(cb_with_lock.lock, justify_name_width, justify_version_width)}")
end

uploaded_cbs.each do |cb_with_lock|
ui.msg("Uploaded #{describe_lock(cb_with_lock.lock, justify_name_width, justify_version_width)}")
end
end

def justify_name_width
@justify_name_width ||= cookbook_names.map {|e| e.size }.max
end

def justify_version_width
@justify_version_width ||= cookbook_version_numbers.map {|e| e.size }.max
end

def cookbook_names
(reused_cbs + uploaded_cbs).map { |e| e.lock.name }
end

def cookbook_version_numbers
(reused_cbs + uploaded_cbs).map { |e| e.lock.version }
end

def describe_lock(lock, justify_name_width, justify_version_width)
"#{lock.name.ljust(justify_name_width)} #{lock.version.ljust(justify_version_width)} (#{lock.identifier[0,8]})"
end

end

COMPAT_MODE_DATA_BAG_NAME = "policyfiles".freeze

attr_reader :policyfile_lock
Expand Down Expand Up @@ -171,7 +125,7 @@ def upload_cookbooks
remote_already_has_cookbook?(cb_with_lock.cookbook)
end

UploadReport.new(reused_cbs: reused_cbs, uploaded_cbs: uploaded_cbs, ui: ui).show
Reports::Upload.new(reused_cbs: reused_cbs, uploaded_cbs: uploaded_cbs, ui: ui).show

true
end
Expand Down
51 changes: 2 additions & 49 deletions lib/chef-dk/policyfile_compiler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,59 +23,12 @@
require 'chef-dk/policyfile/dsl'
require 'chef-dk/policyfile_lock'
require 'chef-dk/ui'
require 'chef-dk/policyfile/reports/install'

module ChefDK

class PolicyfileCompiler

class InstallReport

attr_reader :ui
attr_reader :policyfile_compiler

def initialize(ui: ui, policyfile_compiler: nil)
@ui = ui
@policyfile_compiler = policyfile_compiler

@fixed_version_cookbooks_name_width = nil
@cookbook_name_width = nil
@cookbook_version_width = nil
end

def installing_fixed_version_cookbook(cookbook_spec)
verb = cookbook_spec.installed? ? "Using " : "Installing"
ui.msg("#{verb} #{format_fixed_version_cookbook(cookbook_spec)}")
end

def installing_cookbook(cookbook_spec)
verb = cookbook_spec.installed? ? "Using " : "Installing"
ui.msg("#{verb} #{format_cookbook(cookbook_spec)}")
end

private

def format_cookbook(cookbook_spec)
"#{cookbook_spec.name.ljust(cookbook_name_width)} #{cookbook_spec.version_constraint.version.to_s.ljust(cookbook_version_width)}"
end

def cookbook_name_width
@cookbook_name_width ||= policyfile_compiler.graph_solution.map { |name, _| name.size }.max
end

def cookbook_version_width
@cookbook_version_width ||= policyfile_compiler.graph_solution.map { |_, version| version.size }.max
end

def format_fixed_version_cookbook(spec)
"#{spec.name.ljust(fixed_version_cookbooks_name_width)} #{spec.version_constraint} from #{spec.source_type}"
end

def fixed_version_cookbooks_name_width
@fixed_version_cookbooks_name_width ||= policyfile_compiler.fixed_version_cookbooks_specs.map { |name, _| name.size }.max
end

end

extend Forwardable

DEFAULT_DEMAND_CONSTRAINT = '>= 0.0.0'.freeze
Expand Down Expand Up @@ -105,7 +58,7 @@ def initialize(ui: nil)
@artifact_server_cookbook_location_specs = {}

@ui = ui || UI.null
@install_report = InstallReport.new(ui: @ui, policyfile_compiler: self)
@install_report = Policyfile::Reports::Install.new(ui: @ui, policyfile_compiler: self)
end

def error!
Expand Down