machinery-tool 1.11.1 → 1.11.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3df33176b811549a953814924a963e655a842e3e
4
- data.tar.gz: 4bd71beba06623be5a2333e6adef30eb2c61305a
3
+ metadata.gz: f5d39b671ef2bf800e50ffe8cb48003f1ad6cf50
4
+ data.tar.gz: a5f739eb08389646bd1d6e8d26ee29d6f21b1595
5
5
  SHA512:
6
- metadata.gz: 1f0afb5e850e9f37772ce71d8f60a295a0e57ee494f9bab20a8e63ea1fac56194e1883c73ba74b35cf3a3ff176feca8293d72659b2a957ec6733b02da2bad97f
7
- data.tar.gz: 4a6538e1df02b68cb4800913f4d587b664a843f4589e735a19b6b4186327a2ab424125b09e35e76883c80cc64cabad296f3d7e67147055646f3ef67a0a85a6e6
6
+ metadata.gz: 1992072db448872c81e4179fa7f2a7518179ecf15f12c433b9cd0f6c6a1811bdb4e7f68b4776ea69ac649fcdf8b5c813af213aa7e786f40d0cb02638f2462d1e
7
+ data.tar.gz: 651d2cfa1150a857ca265db080d113d61f845c8ed2cfdaeb626b81b058b5b52193239b751c2385cdf2978f86e7ff42510265f5efdb1dbc6f9f57f8031797a5c0
data/NEWS CHANGED
@@ -1,6 +1,12 @@
1
1
  # Machinery Release Notes
2
2
 
3
3
 
4
+ ## Version 1.11.2 - Thu Jul 30 14:42:44 CEST 2015 - thardeck@suse.de
5
+
6
+ * Fix issue with showing HTML view when not all file scopes are inspected
7
+ (gh#SUSE/machinery#1150)
8
+ * Fix `--all` option of `remove` command (gh#SUSE/machinery#1128)
9
+
4
10
  ## Version 1.11.1 - Tue Jul 21 09:44:16 CEST 2015 - thardeck@suse.de
5
11
 
6
12
  * Fix unmanaged-files diff in HTML view (gh#SUSE/machinery#1143)
data/lib/build_task.rb CHANGED
@@ -19,8 +19,7 @@ class BuildTask
19
19
  def build(system_description, output_path, options = {})
20
20
  LocalSystem.validate_architecture("x86_64")
21
21
  LocalSystem.validate_build_compatibility(system_description)
22
- LocalSystem.validate_existence_of_package("kiwi")
23
- LocalSystem.validate_existence_of_package("kiwi-desc-vmxboot")
22
+ LocalSystem.validate_existence_of_packages(["kiwi", "kiwi-desc-vmxboot"])
24
23
 
25
24
  tmp_config_dir = Dir.mktmpdir("machinery-config", "/tmp")
26
25
  tmp_image_dir = Dir.mktmpdir("machinery-image", "/tmp")
data/lib/cli.rb CHANGED
@@ -35,7 +35,9 @@ class Cli
35
35
  Machinery.logger.level = Logger::INFO
36
36
  end
37
37
 
38
- validate_number_of_arguments(command.arguments, args)
38
+ validate_command_line(command.arguments, args)
39
+
40
+ true
39
41
  end
40
42
 
41
43
  post do |global_options,command,options,args|
@@ -55,8 +57,8 @@ class Cli
55
57
 
56
58
  GLI::Commands::Help.skips_post = false
57
59
 
58
- def self.validate_number_of_arguments(defined, parsed)
59
- if defined.any?(&:multiple?) && parsed.empty?
60
+ def self.validate_command_line(defined, parsed)
61
+ if defined.any?(&:multiple?) && !defined.any?(&:optional?) && parsed.empty?
60
62
  message = "No arguments given. Nothing to do."
61
63
  raise GLI::BadCommandLine.new(message)
62
64
  elsif !defined.any?(&:multiple?) && parsed.size > defined.size
@@ -65,8 +67,6 @@ class Cli
65
67
  message = "Too many arguments: got #{parsed_arguments}, expected #{defined_arguments}"
66
68
  raise GLI::BadCommandLine.new(message)
67
69
  end
68
-
69
- true
70
70
  end
71
71
 
72
72
  def self.buildable_distributions
@@ -594,7 +594,7 @@ class Cli
594
594
 
595
595
  The success of a removal can be shown with the verbose option.
596
596
  LONGDESC
597
- arg "NAME", :multiple
597
+ arg "NAME", [:multiple, :optional]
598
598
 
599
599
  command :remove do |c|
600
600
  c.switch :all, negatable: false,
@@ -603,6 +603,10 @@ class Cli
603
603
  desc: "Explain what is being done"
604
604
 
605
605
  c.action do |global_options,options,args|
606
+ if !options[:all] && args.empty?
607
+ raise GLI::BadCommandLine.new, "You need to either specify `--all` or a list of system descriptions"
608
+ end
609
+
606
610
  task = RemoveTask.new
607
611
  task.remove(system_description_store, args, verbose: options[:verbose], all: options[:all])
608
612
  end
@@ -755,7 +759,8 @@ class Cli
755
759
  LONGDESC
756
760
  arg "NAME"
757
761
  command "serve" do |c|
758
- c.flag [:port, :p], type: Integer, required: false, default_value: 7585,
762
+ c.flag [:port, :p], type: Integer, required: false,
763
+ default_value: Machinery::Config.new.http_server_port,
759
764
  desc: "Listen on port PORT", arg_name: "PORT"
760
765
  c.flag [:ip, :i], type: String, required: false, default_value: "127.0.0.1",
761
766
  desc: "Listen on ip IP", arg_name: "IP"
data/lib/compare_task.rb CHANGED
@@ -39,9 +39,7 @@ There is a web server running, serving the comparison result on #{url}.
39
39
  The server can be closed with Ctrl+C.
40
40
  EOF
41
41
 
42
- server = Html.run_server(description1.store, port: options[:port], ip: options[:ip])
43
-
44
- Html.when_server_ready(options[:ip], options[:port]) do
42
+ server = Html.run_server(description1.store, port: options[:port], ip: options[:ip]) do
45
43
  LoggedCheetah.run("xdg-open", url)
46
44
  end
47
45
 
data/lib/config.rb CHANGED
@@ -21,9 +21,11 @@
21
21
 
22
22
  module Machinery
23
23
  class Config < ConfigBase
24
- def define_entries
25
- default_config_file(Machinery::DEFAULT_CONFIG_FILE)
24
+ def default_config_file
25
+ ENV["MACHINERY_CONFIG_FILE"] || Machinery::DEFAULT_CONFIG_FILE
26
+ end
26
27
 
28
+ def define_entries
27
29
  entry("hints",
28
30
  default: true,
29
31
  description: "Show hints about usage of Machinery in the context of the commands ran by" \
data/lib/config_base.rb CHANGED
@@ -20,16 +20,18 @@
20
20
  # the file 'machinery_config.rb'.
21
21
 
22
22
  class ConfigBase
23
- def initialize
23
+ attr_reader :file
24
+
25
+ def initialize(file = default_config_file)
24
26
  @entries = {}
25
- @file = ""
27
+ @file = file
26
28
  define_entries
27
29
  apply_custom_config(@file) if File.exist?(@file)
28
30
  end
29
31
 
30
- def default_config_file(file)
31
- @file = file
32
- end
32
+ abstract_method :default_config_files
33
+
34
+ abstract_method :define_entries
33
35
 
34
36
  def entry(key, parameters = {})
35
37
  key = normalize_key(key)
@@ -39,10 +41,6 @@ class ConfigBase
39
41
  create_method("#{key}=".to_sym) { |value| set(key, value) }
40
42
  end
41
43
 
42
- def define_entries
43
- raise NotImplementedError.new("No config entries defined for #{self.class}")
44
- end
45
-
46
44
  def each(&block)
47
45
  @entries.map { |key, value| [unnormalize_key(key), value] }.each(&block)
48
46
  end
@@ -82,7 +80,7 @@ class ConfigBase
82
80
  config_table_stripped[key] = value[:value]
83
81
  end
84
82
 
85
- FileUtils.mkdir_p(Machinery::DEFAULT_CONFIG_DIR)
83
+ FileUtils.mkdir_p(File.dirname(file))
86
84
 
87
85
  begin
88
86
  File.write(@file, config_table_stripped.to_yaml)
data/lib/deploy_task.rb CHANGED
@@ -18,7 +18,7 @@
18
18
  class DeployTask
19
19
  def deploy(description, cloud_config, options = {})
20
20
  LocalSystem.validate_architecture("x86_64")
21
- LocalSystem.validate_existence_of_package("python-glanceclient")
21
+ LocalSystem.validate_existence_of_packages(["python-glanceclient", "kiwi", "kiwi-desc-vmxboot"])
22
22
  LocalSystem.validate_build_compatibility(description)
23
23
 
24
24
  if !File.exists?(cloud_config)
data/lib/exceptions.rb CHANGED
@@ -134,5 +134,6 @@ module Machinery
134
134
  class ZypperFailed < MachineryError; end
135
135
  class UnknownConfig < MachineryError; end
136
136
  class UnsupportedArchitecture < MachineryError; end
137
+ class ServeFailed < MachineryError; end
137
138
  end
138
139
  end
data/lib/html.rb CHANGED
@@ -16,184 +16,14 @@
16
16
  # you may find current contact information at www.suse.com
17
17
 
18
18
  class Html
19
- module Helpers
20
- def scope_help(scope)
21
- text = File.read(File.join(Machinery::ROOT, "plugins", "#{scope}/#{scope}.md"))
22
- Kramdown::Document.new(text).to_html
23
- end
24
-
25
- def diff_to_object(diff)
26
- diff = Machinery.scrub(diff)
27
- lines = diff.lines[2..-1]
28
- diff_object = {
29
- file: diff[/--- a(.*)/, 1],
30
- additions: lines.select { |l| l.start_with?("+") }.length,
31
- deletions: lines.select { |l| l.start_with?("-") }.length
32
- }
33
-
34
- original_line_number = 0
35
- new_line_number = 0
36
- diff_object[:lines] = lines.map do |line|
37
- line = ERB::Util.html_escape(line.chomp).
38
- gsub("\\", "&#92;").
39
- gsub("\t", "&nbsp;" * 8)
40
- case line
41
- when /^@.*/
42
- entry = {
43
- type: "header",
44
- content: line
45
- }
46
- original_line_number = line[/-(\d+)/, 1].to_i
47
- new_line_number = line[/\+(\d+)/, 1].to_i
48
- when /^ .*/, ""
49
- entry = {
50
- type: "common",
51
- new_line_number: new_line_number,
52
- original_line_number: original_line_number,
53
- content: line[1..-1]
54
- }
55
- new_line_number += 1
56
- original_line_number += 1
57
- when /^\+.*/
58
- entry = {
59
- type: "addition",
60
- new_line_number: new_line_number,
61
- content: line[1..-1]
62
- }
63
- new_line_number += 1
64
- when /^\-.*/
65
- entry = {
66
- type: "deletion",
67
- original_line_number: original_line_number,
68
- content: line[1..-1]
69
- }
70
- original_line_number += 1
71
- end
72
-
73
- entry
74
- end
75
-
76
- diff_object
77
- end
78
- end
79
-
80
- # this is required for the #generate_comparison method which renders a HAML template manually with
81
- # the local binding, so it expects the helper methods to be available in Html. It can be removed
82
- # once the comparison was move to the webserver approach as well
83
- extend Helpers
84
-
85
19
  # Creates a new thread running a sinatra webserver which serves the local system descriptions
86
20
  # The Thread object is returned so that the caller can `.join` it until it's finished.
87
- def self.run_server(system_description_store, opts)
21
+ def self.run_server(system_description_store, opts, &block)
88
22
  Thread.new do
89
- require "sinatra/base"
90
- require "mimemagic"
91
-
92
- server = Sinatra.new do
93
- set :port, opts[:port] || 7585
94
- set :bind, opts[:ip] || "localhost"
95
- set :public_folder, File.join(Machinery::ROOT, "html")
96
-
97
- helpers Helpers
98
-
99
- get "/descriptions/:id.js" do
100
- description = SystemDescription.load(params[:id], system_description_store)
101
- diffs_dir = description.scope_file_store("analyze/config_file_diffs").path
102
- if description.config_files && diffs_dir
103
- # Enrich description with the config file diffs
104
- description.config_files.files.each do |file|
105
- path = File.join(diffs_dir, file.name + ".diff")
106
- file.diff = diff_to_object(File.read(path)) if File.exists?(path)
107
- end
108
- end
109
-
110
- # Enrich file information with downloadable flag
111
- ["config_files", "changed_managed_files", "unmanaged_files"].each do |scope|
112
- description[scope].files.each do |file|
113
- file.downloadable = file.on_disk?
114
- end
115
- end
116
-
117
- description.to_hash.to_json
118
- end
119
-
120
- get "/descriptions/:id/files/:scope/*" do
121
- description = SystemDescription.load(params[:id], system_description_store)
122
- filename = File.join("/", params["splat"].first)
123
-
124
- file = description[params[:scope]].files.find { |f| f.name == filename }
125
-
126
- if request.accept.first.to_s == "text/plain" && file.binary?
127
- status 406
128
- return "binary file"
129
- end
130
-
131
- content = file.content
132
- type = MimeMagic.by_path(filename) || MimeMagic.by_magic(content) || "text/plain"
133
-
134
- content_type type
135
- attachment File.basename(filename)
136
-
137
- content
138
- end
139
-
140
- get "/compare/:a/:b.json" do
141
- description_a = SystemDescription.load(params[:a], system_description_store)
142
- description_b = SystemDescription.load(params[:b], system_description_store)
143
-
144
- diff = {
145
- meta: {
146
- description_a: description_a.name,
147
- description_b: description_b.name,
148
- }
149
- }
150
-
151
- Inspector.all_scopes.each do |scope|
152
- if description_a[scope] && description_b[scope]
153
- comparison = Comparison.compare_scope(description_a, description_b, scope)
154
- diff[scope] = comparison.as_json
155
- else
156
- diff[:meta][:uninspected] ||= Hash.new
157
-
158
- if !description_a[scope] && description_b[scope]
159
- diff[:meta][:uninspected][description_a.name] ||= Array.new
160
- diff[:meta][:uninspected][description_a.name] << scope
161
- end
162
- if !description_b[scope] && description_a[scope]
163
- diff[:meta][:uninspected][description_b.name] ||= Array.new
164
- diff[:meta][:uninspected][description_b.name] << scope
165
- end
166
- end
167
- end
168
-
169
- diff.to_json
170
- end
171
-
172
- get "/compare/:a/:b" do
173
- haml File.read(File.join(Machinery::ROOT, "html/comparison.html.haml")),
174
- locals: { description_a: params[:a], description_b: params[:b] }
175
- end
176
-
177
- get "/compare/:a/:b/files/:scope/*" do
178
- description1 = SystemDescription.load(params[:a], system_description_store)
179
- description2 = SystemDescription.load(params[:b], system_description_store)
180
- filename = File.join("/", params["splat"].first)
181
-
182
- begin
183
- diff = FileDiff.diff(description1, description2, params[:scope], filename)
184
- rescue Machinery::Errors::BinaryDiffError
185
- status 406
186
- return "binary file"
187
- end
188
-
189
- diff.to_s(:html)
190
- end
191
-
192
- get "/:id" do
193
- haml File.read(File.join(Machinery::ROOT, "html/index.html.haml")),
194
- locals: { description_name: params[:id] }
195
- end
196
- end
23
+ Server.set :system_description_store, system_description_store
24
+ Server.set :port, opts[:port] || Machinery::Config.new.http_server_port
25
+ Server.set :bind, opts[:ip] || "localhost"
26
+ Server.set :public_folder, File.join(Machinery::ROOT, "html")
197
27
 
198
28
  if opts[:ip] != "localhost" && opts[:ip] != "127.0.0.1"
199
29
  Machinery::Ui.puts <<EOF
@@ -205,27 +35,24 @@ EOF
205
35
 
206
36
  begin
207
37
  setup_output_redirection
208
- server.run!
38
+ begin
39
+ Server.run! do
40
+ Thread.new { block.call }
41
+ end
42
+ rescue Errno::EADDRINUSE
43
+ servefailed_error = <<-EOF.chomp
44
+ Port #{Server.settings.port} is already in use.
45
+ Stop the already running server on port #{Server.settings.port} or specify a new port by using --port option.
46
+ EOF
47
+ raise Machinery::Errors::ServeFailed, servefailed_error
48
+ end
49
+ remove_output_redirection
209
50
  rescue => e
51
+ remove_output_redirection
210
52
  # Re-raise exception in main thread
211
53
  Thread.main.raise e
212
- ensure
213
- remove_output_redirection
214
- end
215
- end
216
- end
217
-
218
- def self.when_server_ready(ip, port, &block)
219
- 20.times do
220
- begin
221
- TCPSocket.new(ip, port).close
222
- block.call
223
- return
224
- rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
225
- sleep 0.1
226
54
  end
227
55
  end
228
- raise Machinery::Errors::MachineryError, "The web server did not come up in time."
229
56
  end
230
57
 
231
58
  def self.setup_output_redirection
@@ -240,22 +67,4 @@ EOF
240
67
  STDOUT.reopen @orig_stdout
241
68
  STDERR.reopen @orig_stderr
242
69
  end
243
-
244
- def self.generate_comparison(diff, target)
245
- FileUtils.mkdir_p(File.join(target, "assets"))
246
- template = Haml::Engine.new(
247
- File.read(File.join(Machinery::ROOT, "html", "comparison.html.haml"))
248
- )
249
-
250
- FileUtils.cp_r(File.join(Machinery::ROOT, "html", "assets"), target)
251
- File.write(File.join(target, "index.html"), template.render(binding))
252
- json = diff.to_json.gsub("'", "\\\\'").gsub("\"", "\\\\\"")
253
- File.write(File.join(target, "assets/diff.js"),<<-EOT
254
- function getDiff() {
255
- return JSON.parse('#{json}'
256
- )
257
- }
258
- EOT
259
- )
260
- end
261
70
  end
data/lib/inspector.rb CHANGED
@@ -68,7 +68,10 @@ class Inspector
68
68
  scope_priority = {}
69
69
 
70
70
  scope_list.each do |scope|
71
- scope_priority[self.for(scope).priority] = scope
71
+ inspector = self.for(scope)
72
+ next if !inspector
73
+
74
+ scope_priority[inspector.priority] = scope
72
75
  end
73
76
 
74
77
  scope_priority.sort.map do |key, value|
data/lib/local_system.rb CHANGED
@@ -30,17 +30,41 @@ class LocalSystem < System
30
30
  end
31
31
 
32
32
  def validate_existence_of_package(package)
33
- begin
34
- Cheetah.run("rpm", "-q", package)
35
- rescue
36
- needed_module = os.module_required_by_package(package)
37
- if needed_module
38
- raise(Machinery::Errors::MissingRequirement.new("You need the package '#{package}' from module '#{needed_module}'. You can install it as follows:\n" \
39
- "If you haven't selected the module '#{needed_module}' before, run `yast2 scc` and choose 'Select Extensions' and activate '#{needed_module}'.\nRun `zypper install #{package}` to install the package."))
40
- else
41
- raise(Machinery::Errors::MissingRequirement.new("You need the package '#{package}'. You can install it by running `zypper install #{package}`"))
33
+ validate_existence_of_packages([package])
34
+ end
35
+
36
+ def validate_existence_of_packages(packages)
37
+ missing_packages = []
38
+ needed_modules = []
39
+
40
+ packages.each do |package|
41
+ begin
42
+ Cheetah.run("rpm", "-q", package)
43
+ rescue Cheetah::ExecutionFailed
44
+ missing_packages << package
45
+ needed_module = os.module_required_by_package(package)
46
+ if needed_module
47
+ needed_modules << package
48
+ if needed_module
49
+ output = <<-EOF
50
+ You need the package '#{package}' from module '#{needed_module}'. You can install it as follows:
51
+ If you haven't selected the module '#{needed_module}' before, run `yast2 scc` and choose 'Select Extensions' and activate '#{needed_module}'.
52
+ Run `zypper install #{package}` to install the package.
53
+ EOF
54
+ raise(Machinery::Errors::MissingRequirement.new(output))
55
+ end
56
+ end
42
57
  end
43
58
  end
59
+
60
+ if !missing_packages.empty?
61
+ count = missing_packages.count
62
+ error_string = <<-EOF
63
+ You need the #{Machinery::pluralize(count, "package")} '#{missing_packages.join("\',\'")}'.
64
+ You can install it by running `zypper install #{missing_packages.join(" ")}`.
65
+ EOF
66
+ raise(Machinery::Errors::MissingRequirement.new(error_string))
67
+ end
44
68
  end
45
69
 
46
70
  def validate_machinery_compatibility
data/lib/machinery.rb CHANGED
@@ -35,6 +35,8 @@ require "pathname"
35
35
  require "nokogiri"
36
36
  require "socket"
37
37
  require "diffy"
38
+ require "sinatra/base"
39
+ require "mimemagic"
38
40
 
39
41
  require_relative "machinery_logger"
40
42
  require_relative "zypper"
@@ -76,7 +78,6 @@ require_relative "ui"
76
78
  require_relative "validate_task"
77
79
  require_relative "migration"
78
80
  require_relative "upgrade_format_task"
79
- require_relative "html"
80
81
  require_relative "hint"
81
82
  require_relative "mountpoints"
82
83
  require_relative "config_base"
@@ -99,6 +100,8 @@ require_relative "man_task"
99
100
  require_relative "comparison"
100
101
  require_relative "serve_html_task"
101
102
  require_relative "file_diff"
103
+ require_relative "server"
104
+ require_relative "html"
102
105
 
103
106
  Dir[File.join(Machinery::ROOT, "plugins", "**", "*.rb")].each { |f| require(f) }
104
107
 
data/lib/server.rb ADDED
@@ -0,0 +1,181 @@
1
+ # Copyright (c) 2013-2015 SUSE LLC
2
+ #
3
+ # This program is free software; you can redistribute it and/or
4
+ # modify it under the terms of version 3 of the GNU General Public License as
5
+ # published by the Free Software Foundation.
6
+ #
7
+ # This program is distributed in the hope that it will be useful,
8
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
9
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
+ # GNU General Public License for more details.
11
+ #
12
+ # You should have received a copy of the GNU General Public License
13
+ # along with this program; if not, contact SUSE LLC.
14
+ #
15
+ # To contact SUSE about this file by physical or electronic mail,
16
+ # you may find current contact information at www.suse.com
17
+
18
+ class Server < Sinatra::Base
19
+ module Helpers
20
+ def scope_help(scope)
21
+ text = File.read(File.join(Machinery::ROOT, "plugins", "#{scope}/#{scope}.md"))
22
+ Kramdown::Document.new(text).to_html
23
+ end
24
+
25
+ def diff_to_object(diff)
26
+ diff = Machinery.scrub(diff)
27
+ lines = diff.lines[2..-1]
28
+ diff_object = {
29
+ file: diff[/--- a(.*)/, 1],
30
+ additions: lines.select { |l| l.start_with?("+") }.length,
31
+ deletions: lines.select { |l| l.start_with?("-") }.length
32
+ }
33
+
34
+ original_line_number = 0
35
+ new_line_number = 0
36
+ diff_object[:lines] = lines.map do |line|
37
+ line = ERB::Util.html_escape(line.chomp).
38
+ gsub("\\", "&#92;").
39
+ gsub("\t", "&nbsp;" * 8)
40
+ case line
41
+ when /^@.*/
42
+ entry = {
43
+ type: "header",
44
+ content: line
45
+ }
46
+ original_line_number = line[/-(\d+)/, 1].to_i
47
+ new_line_number = line[/\+(\d+)/, 1].to_i
48
+ when /^ .*/, ""
49
+ entry = {
50
+ type: "common",
51
+ new_line_number: new_line_number,
52
+ original_line_number: original_line_number,
53
+ content: line[1..-1]
54
+ }
55
+ new_line_number += 1
56
+ original_line_number += 1
57
+ when /^\+.*/
58
+ entry = {
59
+ type: "addition",
60
+ new_line_number: new_line_number,
61
+ content: line[1..-1]
62
+ }
63
+ new_line_number += 1
64
+ when /^\-.*/
65
+ entry = {
66
+ type: "deletion",
67
+ original_line_number: original_line_number,
68
+ content: line[1..-1]
69
+ }
70
+ original_line_number += 1
71
+ end
72
+
73
+ entry
74
+ end
75
+
76
+ diff_object
77
+ end
78
+ end
79
+
80
+ helpers Helpers
81
+
82
+ get "/descriptions/:id.js" do
83
+ description = SystemDescription.load(params[:id], settings.system_description_store)
84
+ diffs_dir = description.scope_file_store("analyze/config_file_diffs").path
85
+ if description.config_files && diffs_dir
86
+ # Enrich description with the config file diffs
87
+ description.config_files.files.each do |file|
88
+ path = File.join(diffs_dir, file.name + ".diff")
89
+ file.diff = diff_to_object(File.read(path)) if File.exists?(path)
90
+ end
91
+ end
92
+
93
+ # Enrich file information with downloadable flag
94
+ ["config_files", "changed_managed_files", "unmanaged_files"].each do |scope|
95
+ next if !description[scope]
96
+
97
+ description[scope].files.each do |file|
98
+ file.downloadable = file.on_disk?
99
+ end
100
+ end
101
+
102
+ description.to_hash.to_json
103
+ end
104
+
105
+ get "/descriptions/:id/files/:scope/*" do
106
+ description = SystemDescription.load(params[:id], settings.system_description_store)
107
+ filename = File.join("/", params["splat"].first)
108
+
109
+ file = description[params[:scope]].files.find { |f| f.name == filename }
110
+
111
+ if request.accept.first.to_s == "text/plain" && file.binary?
112
+ status 406
113
+ return "binary file"
114
+ end
115
+
116
+ content = file.content
117
+ type = MimeMagic.by_path(filename) || MimeMagic.by_magic(content) || "text/plain"
118
+
119
+ content_type type
120
+ attachment File.basename(filename)
121
+
122
+ content
123
+ end
124
+
125
+ get "/compare/:a/:b.json" do
126
+ description_a = SystemDescription.load(params[:a], settings.system_description_store)
127
+ description_b = SystemDescription.load(params[:b], settings.system_description_store)
128
+
129
+ diff = {
130
+ meta: {
131
+ description_a: description_a.name,
132
+ description_b: description_b.name,
133
+ }
134
+ }
135
+
136
+ Inspector.all_scopes.each do |scope|
137
+ if description_a[scope] && description_b[scope]
138
+ comparison = Comparison.compare_scope(description_a, description_b, scope)
139
+ diff[scope] = comparison.as_json
140
+ else
141
+ diff[:meta][:uninspected] ||= Hash.new
142
+
143
+ if !description_a[scope] && description_b[scope]
144
+ diff[:meta][:uninspected][description_a.name] ||= Array.new
145
+ diff[:meta][:uninspected][description_a.name] << scope
146
+ end
147
+ if !description_b[scope] && description_a[scope]
148
+ diff[:meta][:uninspected][description_b.name] ||= Array.new
149
+ diff[:meta][:uninspected][description_b.name] << scope
150
+ end
151
+ end
152
+ end
153
+
154
+ diff.to_json
155
+ end
156
+
157
+ get "/compare/:a/:b" do
158
+ haml File.read(File.join(Machinery::ROOT, "html/comparison.html.haml")),
159
+ locals: { description_a: params[:a], description_b: params[:b] }
160
+ end
161
+
162
+ get "/compare/:a/:b/files/:scope/*" do
163
+ description1 = SystemDescription.load(params[:a], settings.system_description_store)
164
+ description2 = SystemDescription.load(params[:b], settings.system_description_store)
165
+ filename = File.join("/", params["splat"].first)
166
+
167
+ begin
168
+ diff = FileDiff.diff(description1, description2, params[:scope], filename)
169
+ rescue Machinery::Errors::BinaryDiffError
170
+ status 406
171
+ return "binary file"
172
+ end
173
+
174
+ diff.to_s(:html)
175
+ end
176
+
177
+ get "/:id" do
178
+ haml File.read(File.join(Machinery::ROOT, "html/index.html.haml")),
179
+ locals: { description_name: params[:id] }
180
+ end
181
+ end
data/lib/show_task.rb CHANGED
@@ -41,9 +41,7 @@ There is a web server running, serving the description on #{url}.
41
41
  The server can be closed with Ctrl+C.
42
42
  EOF
43
43
 
44
- server = Html.run_server(description.store, port: options[:port], ip: options[:ip])
45
-
46
- Html.when_server_ready(options[:ip], options[:port]) do
44
+ server = Html.run_server(description.store, port: options[:port], ip: options[:ip]) do
47
45
  LoggedCheetah.run("xdg-open", url)
48
46
  end
49
47
 
data/lib/version.rb CHANGED
@@ -17,6 +17,6 @@
17
17
 
18
18
  module Machinery
19
19
 
20
- VERSION = "1.11.1"
20
+ VERSION = "1.11.2"
21
21
 
22
22
  end
Binary file
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: machinery-tool
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.11.1
4
+ version: 1.11.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - SUSE
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-21 00:00:00.000000000 Z
11
+ date: 2015-07-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cheetah
@@ -337,6 +337,7 @@ files:
337
337
  - lib/scope_file_access_flat.rb
338
338
  - lib/scope_file_store.rb
339
339
  - lib/serve_html_task.rb
340
+ - lib/server.rb
340
341
  - lib/show_task.rb
341
342
  - lib/system.rb
342
343
  - lib/system_description.rb