kameleon-builder 2.10.2 → 2.10.3

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
  SHA256:
3
- metadata.gz: 5ba36ddda8ead18d06bc94412de565662a2cbed76a2ce71e4994e4f5ee665477
4
- data.tar.gz: 8a1e67a68923b413654682b87e14e6c91102b57dc9fd4ed45164f0827b1483cb
3
+ metadata.gz: c3e726c2e8f9ca4aa09d3e5c6ef46ddc96f76f815ed8d740c431deb7e46f9433
4
+ data.tar.gz: 2fc324e1b1f507886d628ff27c6daa94ec50ef7e04f57f30af6614f8db7d3f1d
5
5
  SHA512:
6
- metadata.gz: 6993ca5f73661525c8a44133eb715d383144b75d5e4c9cc66f73aab1896643d9db09165ddc9af46e1474c2a82b856f1dc8a894582fb398f8d25ec472019878f1
7
- data.tar.gz: 205ac5b41d50af596f7428196bfc1c1c6633e6408d5643e3d4e71f323f5117755e863e98432febcca98f0461b421d40a6a3ec08634da50a66f1afe101c38eba8
6
+ metadata.gz: 83abce13fbf9368ed09392794a572065fc6959ff3071a61d2a4f1231288f2d4ad176d1003d57027320728042de7b8c5a5abf0e068c52c7b203faaae4d29faff7
7
+ data.tar.gz: c6f6f3bb93d99b960fd1650fb1247d21a5e306c5f334e19bc969a6d2195d3c93fe931de68640c84d87f2e6afc75c36b938c3b490a0aef482e5d66af31ce8cb0e
@@ -1,7 +1,7 @@
1
1
  [bumpversion]
2
2
  commit = True
3
3
  tag = True
4
- current_version = 2.10.2
4
+ current_version = 2.10.3
5
5
  parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(\.(?P<release>[a-z]+))?
6
6
  serialize =
7
7
  {major}.{minor}.{patch}.{release}
data/CHANGES CHANGED
@@ -1,6 +1,16 @@
1
1
  Kameleon CHANGELOG
2
2
  ==================
3
3
 
4
+ Version 2.10.3
5
+ --------------
6
+
7
+ Released on April 10th 2020
8
+
9
+ - Rework kameleon template list: add color add progress bar
10
+ - Make bash completion understand the subcommands
11
+ - Fix the command help -> `kameleon <command> -h`
12
+ - Add support for custom extend erb templates
13
+
4
14
  Version 2.10.2
5
15
  --------------
6
16
 
@@ -2,12 +2,23 @@
2
2
 
3
3
  _kameleon() {
4
4
  COMPREPLY=()
5
- local word="${COMP_WORDS[COMP_CWORD]}"
6
-
7
- if [ "$COMP_CWORD" -eq 1 ]; then
8
- local commands="$(compgen -W "$(kameleon commands)" -- "$word")"
5
+ local i=1
6
+ while [ $i -le "$COMP_CWORD" -a "${COMP_WORDS[$i]:0:1}" == "-" ]; do
7
+ ((i++))
8
+ done
9
+ if [ "$COMP_CWORD" -eq $i ]; then
10
+ local commands="$(compgen -W "$(kameleon commands)" -- "${COMP_WORDS[$i]}")"
9
11
  COMPREPLY=( $commands $projects )
10
12
  fi
13
+ while [ $i -le "$COMP_CWORD" -a "${COMP_WORDS[$i]:0:1}" == "-" ]; do
14
+ ((i++))
15
+ done
16
+ if [ "$COMP_CWORD" -eq $((i+1)) ] && kameleon commands | grep -q "${COMP_WORDS[$i]}" ; then
17
+ if wordlist=$(kameleon ${COMP_WORDS[$i]} commands); then
18
+ local commands="$(compgen -W "$wordlist" -- "${COMP_WORDS[$((i+1))]}")"
19
+ COMPREPLY=( $commands $projects )
20
+ fi
21
+ fi
11
22
  }
12
23
 
13
24
  complete -o default -F _kameleon kameleon
@@ -0,0 +1,24 @@
1
+ #==============================================================================
2
+ # vim: softtabstop=2 shiftwidth=2 expandtab fenc=utf-8 cc=81 tw=80
3
+ #==============================================================================
4
+ #
5
+ # DESCRIPTION: <MY RECIPE DESCRIPTION>
6
+ #
7
+ #==============================================================================
8
+ # This recipe extends another. To look at the step involed, run:
9
+ # kameleon dryrun <%= recipe_name %>
10
+ # To see the variables that you can override, use the following command:
11
+ # kameleon info <%= recipe_name %>
12
+ ---
13
+ extend: <%= tpl.relative_path_from_recipe(recipe_path) %>
14
+
15
+ global:
16
+
17
+ bootstrap:
18
+ - "@base"
19
+
20
+ setup:
21
+ - "@base"
22
+
23
+ export:
24
+ - "@base"
File without changes
@@ -18,7 +18,7 @@ Gem::Specification.new do |s|
18
18
  'pierre.neyron@imag.fr',
19
19
  'bruno.bzeznik@imag.fr']
20
20
  s.description = %q{The mindful appliance builder}
21
- s.summary = %q{Kameleon is a tool to build virtual machines from scratch}
21
+ s.summary = %q{Kameleon is a tool to build system appliances from scratch}
22
22
  s.homepage = 'http://kameleon.imag.fr/'
23
23
  s.license = 'GPL-2.0'
24
24
 
@@ -33,6 +33,7 @@ Gem::Specification.new do |s|
33
33
  s.add_dependency 'table_print', '~> 1.5'
34
34
  s.add_dependency 'psych', '~> 2.0'
35
35
  s.add_dependency 'ruby-graphviz', '~> 1.2'
36
+ s.add_dependency 'progressbar', '~> 1'
36
37
 
37
38
  s.requirements = ['polipo 1.0.3, or greater', 'graphviz 2.38.0 or greater']
38
39
  end
@@ -46,7 +46,7 @@ module Kameleon
46
46
  def init_userconf()
47
47
  if not File.exists?(Kameleon.userconf_path) or File.zero?(Kameleon.userconf_path)
48
48
  File.open(Kameleon.userconf_path, 'w+') do |file|
49
- userconf_erb = File.join(Kameleon.erb_dirpath, "userconf.erb")
49
+ userconf_erb = File.join(Kameleon.erb_dirpath, "userconf.yaml.erb")
50
50
  erb = ERB.new(File.open(userconf_erb, 'rb') { |f| f.read })
51
51
  result = erb.result(binding)
52
52
  file.write(result)
@@ -11,7 +11,7 @@ module Kameleon
11
11
  class Repository < Thor
12
12
  include Thor::Actions
13
13
 
14
- desc "add <NAME> <GIT_URL>", "Adds a new repository named <NAME> cloned from at <GIT_URL>."
14
+ desc "add <NAME> <GIT_URL>", "Adds a new repository named <NAME> cloned from <GIT_URL>."
15
15
  method_option :branch, :type => :string ,
16
16
  :default => nil,
17
17
  :desc => "checkout <BRANCH>",
@@ -32,33 +32,38 @@ module Kameleon
32
32
  def update(name)
33
33
  Kameleon::Repository.update(name)
34
34
  end
35
- map %w(-h --help) => :help
36
- map %w(ls) => :list
37
35
 
38
36
  desc "remove <NAME>", "Remove repository named <NAME>"
39
37
  def remove(name)
40
38
  Kameleon::Repository.remove(name)
41
39
  end
42
- map %w(-h --help) => :help
40
+
41
+ desc "commands", "Lists all available commands", :hide => true
42
+ def commands
43
+ puts Repository.all_commands.keys - ["commands"]
44
+ end
45
+
43
46
  map %w(ls) => :list
44
47
  map %w(rm) => :remove
48
+ map %w(completions) => :commands
45
49
  end
46
50
 
47
51
 
48
52
  class Template < Thor
49
53
  include Thor::Actions
50
54
 
51
- # register CLI::Repository, 'repository', 'repository', 'Manages set of remote git repositories'
52
-
53
55
  def self.source_root
54
56
  Kameleon.env.repositories_path
55
57
  end
56
58
 
57
59
  desc "list", "Lists all available templates"
60
+ method_option :progress, :type => :boolean, :default => true,
61
+ :desc => "Show progress bar while resolving templates",
62
+ :aliases => "-p"
58
63
  def list
59
- Kameleon.ui.info "The following templates are available in " \
60
- "#{ Kameleon.env.repositories_path }:"
61
- Utils.list_recipes(Kameleon.env.repositories_path)
64
+ Kameleon.ui.shell.say "Recipe templates available in: ", :red, false
65
+ Kameleon.ui.shell.say Kameleon.env.repositories_path.to_s, :yellow
66
+ Utils.list_recipes(Kameleon.env.repositories_path, options[:progress], true)
62
67
  end
63
68
 
64
69
  desc "import <TEMPLATE_NAME>", "Imports the given template"
@@ -110,8 +115,14 @@ module Kameleon
110
115
  tpl.resolve! :strict => false
111
116
  tpl.display_info(false)
112
117
  end
113
- map %w(-h --help) => :help
118
+
119
+ desc "commands", "Lists all available commands", :hide => true
120
+ def commands
121
+ puts Template.all_commands.keys - ["commands"]
122
+ end
123
+
114
124
  map %w(ls) => :list
125
+ map %w(completions) => :commands
115
126
  end
116
127
  end
117
128
 
@@ -133,23 +144,24 @@ module Kameleon
133
144
  class_option :script, :type => :boolean, :default => Kameleon.default_values[:script],
134
145
  :desc => "Never prompts for user intervention",
135
146
  :aliases => "-s"
136
- map %w(-h --help) => :help
137
147
 
138
148
  desc "version", "Prints the Kameleon's version information"
139
149
  def version
140
150
  puts "Kameleon version #{Kameleon::VERSION}"
141
151
  end
142
- map %w(-v --version) => :version
143
152
 
144
153
  def self.source_root
145
154
  Kameleon.env.repositories_path
146
155
  end
147
156
 
148
157
  desc "list", "Lists all defined recipes in the current directory"
158
+ method_option :progress, :type => :boolean, :default => false,
159
+ :desc => "Show progress bar while resolving templates",
160
+ :aliases => "-p"
149
161
  def list
150
- Utils.list_recipes(Kameleon.env.workspace)
162
+ Kameleon.ui.shell.say "Workspace recipes:", :red
163
+ Utils.list_recipes(Kameleon.env.workspace, options[:progress])
151
164
  end
152
- map %w(ls) => :list
153
165
 
154
166
  desc "new <RECIPE_PATH> <TEMPLATE_NAME>", "Creates a new recipe from template <TEMPLATE_NAME>"
155
167
  method_option :global, :type => :hash ,
@@ -192,7 +204,18 @@ module Kameleon
192
204
  recipe_temp = File.join(tmp_dir, File.basename(recipe_path))
193
205
  ## copying recipe
194
206
  File.open(recipe_temp, 'w+') do |file|
195
- extend_erb_tpl = File.join(Kameleon.erb_dirpath, "extend.erb")
207
+ message="Use extend ERB template: "
208
+ extend_erb_tpl = [
209
+ Kameleon.env.repositories_path.join(template_name + ".erb"),
210
+ Pathname.new(template_name).dirname.ascend.to_a.push(Pathname.new("")).map do |p|
211
+ Kameleon.env.repositories_path.join(p, ".kameleon-extend.yaml.erb")
212
+ end,
213
+ Pathname.new(Kameleon.erb_dirpath).join("extend.yaml.erb")
214
+ ].flatten.find do |f|
215
+ Kameleon.ui.verbose(message + f.to_s)
216
+ message = "-> Not found, fallback: "
217
+ File.readable?(f)
218
+ end
196
219
  erb = ERB.new(File.open(extend_erb_tpl, 'rb') { |f| f.read })
197
220
  result = erb.result(binding)
198
221
  file.write(result)
@@ -209,9 +232,6 @@ module Kameleon
209
232
  method_option :from_cache, :type => :string ,
210
233
  :default => nil,
211
234
  :desc => "Get info from a persistent cache tar file (ignore recipe path)"
212
- method_option :dryrun, :type => :boolean ,
213
- :default => false,
214
- :desc => "Show the build sequence but do not actually build"
215
235
  method_option :relative, :type => :boolean ,
216
236
  :default => false,
217
237
  :desc => "Make pathnames relative to the current working directory"
@@ -419,8 +439,16 @@ module Kameleon
419
439
  end
420
440
 
421
441
  desc "commands", "Lists all available commands", :hide => true
422
- def commands
423
- puts Main.all_commands.keys - ["commands", "completions"]
442
+ def commands(context="main")
443
+ Kameleon.ui.debug("Commands for '#{context}':")
444
+ case context
445
+ when "main"
446
+ puts Main.all_commands.keys - ["commands"]
447
+ when "repository"
448
+ invoke CLI::Repository, "commands", [], []
449
+ when "template"
450
+ invoke CLI::Template, "commands", [], []
451
+ end
424
452
  end
425
453
 
426
454
  desc "source_root", "Prints the kameleon directory path", :hide => true
@@ -428,6 +456,10 @@ module Kameleon
428
456
  puts Kameleon.source_root
429
457
  end
430
458
 
459
+ map %w(-v --version) => :version
460
+ map %w(ls) => :list
461
+ map %w(completions) => :commands
462
+
431
463
  def initialize(*args)
432
464
  super
433
465
  self.options ||= {}
@@ -445,7 +477,17 @@ module Kameleon
445
477
  Kameleon.ui.verbose("The level of output is set to #{Kameleon.ui.level}")
446
478
  end
447
479
 
448
- def self.start(*)
480
+ def self.start(*args)
481
+ # `kameleon build -h` does not work without the following, except for subcommands...
482
+ # Ref: https://stackoverflow.com/a/49044225/6431461
483
+ if (Thor::HELP_MAPPINGS & ARGV).any? and subcommands.grep(/^#{ARGV[0]}/).empty?
484
+ Kameleon.ui.debug("Apply workaround to handle the help command in #{ARGV}")
485
+ Thor::HELP_MAPPINGS.each do |cmd|
486
+ if match = ARGV.delete(cmd)
487
+ ARGV.unshift match
488
+ end
489
+ end
490
+ end
449
491
  super
450
492
  rescue Exception => e
451
493
  Kameleon.ui = Kameleon::UI::Shell.new
@@ -93,7 +93,7 @@ module Kameleon
93
93
  unless File.file? @path
94
94
  yaml_recipe = YAML.load_file @path
95
95
  unless yaml_recipe.kind_of? Hash
96
- fail RecipeError, "Invalid yaml error : #{@path}"
96
+ fail RecipeError, "Invalid yaml: #{@path}"
97
97
  end
98
98
 
99
99
  update_steps_dirs()
@@ -242,7 +242,7 @@ module Kameleon
242
242
  unless File.file? path
243
243
  base_yaml_recipe = YAML.load_file base_recipe_path
244
244
  unless yaml_recipe.kind_of? Hash
245
- fail RecipeError, "Invalid yaml error : #{base_yaml_recipe}"
245
+ fail RecipeError, "Invalid yaml: #{base_yaml_recipe}"
246
246
  end
247
247
  base_yaml_recipe.keys.each do |key|
248
248
  if ["export", "bootstrap", "setup"].include? key
@@ -1,3 +1,5 @@
1
+ require 'progressbar'
2
+
1
3
  module Kameleon
2
4
  module Utils
3
5
 
@@ -123,33 +125,63 @@ module Kameleon
123
125
  end
124
126
  end
125
127
 
126
- def self.list_recipes(repository_path, kwargs = {})
127
- Kameleon.env.root_dir = repository_path
128
+ def self.list_recipes(recipes_path, do_progressbar = false, is_repository = false, kwargs = {})
129
+ Kameleon.env.root_dir = recipes_path
128
130
  catch_exception = kwargs.fetch(:catch_exception, true)
129
131
  recipes_hash = []
130
- recipes_files = get_recipes(repository_path)
132
+ recipes_files = get_recipes(recipes_path)
133
+ if recipes_files.empty?
134
+ Kameleon.ui.shell.say " <None>", :cyan
135
+ return
136
+ end
137
+ if do_progressbar
138
+ progressbar = ProgressBar.create(:format => '%t (%p%%) %bᗧ%i',
139
+ :title => 'Resolving ' + if is_repository; 'templates' else 'recipes' end,
140
+ :progress_mark => '.',
141
+ :remainder_mark => '・',
142
+ :total => recipes_files.size + 10,
143
+ :starting_at => 10)
144
+ end
131
145
  recipes_files.each do |f|
132
146
  path = f.to_s
133
147
  begin
134
148
  recipe = RecipeTemplate.new(path)
135
- name = path.gsub(repository_path.to_s + '/', '').chomp('.yaml')
149
+ name = path.gsub(recipes_path.to_s + '/', '').chomp('.yaml')
136
150
  recipes_hash.push({
137
151
  "name" => name,
138
152
  "description" => recipe.metainfo['description'],
139
153
  })
154
+ progressbar.increment if do_progressbar
140
155
  rescue => e
141
156
  raise e if Kameleon.env.debug or not catch_exception
142
157
  end
143
158
  end
144
159
  unless recipes_hash.empty?
145
- recipes_hash = recipes_hash.sort_by{ |k| k["name"] }
146
160
  name_width = recipes_hash.map { |k| k['name'].size }.max
147
161
  desc_width = Kameleon.ui.shell.terminal_width - name_width - 3
148
162
  desc_width = (80 - name_width - 3) if desc_width < 0
149
163
  end
150
- tp(recipes_hash,
151
- {"name" => {:width => name_width}},
152
- { "description" => {:width => desc_width}})
164
+ repo_str_old = nil
165
+ recipes_hash.sort_by{ |k| k["name"] }.each do |r|
166
+ if is_repository
167
+ repo_str,recipe_dir_str,recipe_str = r["name"].match(%r{^([^/]+/)(.+/)?([^/]+)$}).to_a[1..3].map{|m| m.to_s}
168
+ else
169
+ repo_str,recipe_dir_str,recipe_str = r["name"].match(%r{^()(.+/)?([^/]+)$}).to_a[1..3].map{|m| m.to_s}
170
+ end
171
+ if not repo_str_old.nil? and repo_str_old != repo_str
172
+ Kameleon.ui.shell.say "#{'-' * name_width} | #{'-' * desc_width}"
173
+ end
174
+ repo_str_old = repo_str
175
+ Kameleon.ui.debug("#{r["name"]} -> repo=#{repo_str}, recipe_dir=#{recipe_dir_str}, recipee=#{recipe_str}")
176
+ Kameleon.ui.shell.say "#{repo_str}", :yellow, false
177
+ Kameleon.ui.shell.say "#{recipe_dir_str}", :cyan, false
178
+ Kameleon.ui.shell.say sprintf("%-#{name_width - repo_str.length - recipe_dir_str.length}s", recipe_str), :magenta, false
179
+ Kameleon.ui.shell.say " | ", nil, false
180
+ if r["description"].to_s.length > desc_width - 4
181
+ r["description"] = r["description"][0..(desc_width - 4)] + "..."
182
+ end
183
+ Kameleon.ui.shell.say sprintf("%-#{desc_width}s", r["description"]), :blue
184
+ end
153
185
  end
154
186
 
155
187
  def self.get_recipes(path)
@@ -1 +1 @@
1
- 2.10.2
1
+ 2.10.3
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kameleon-builder
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.10.2
4
+ version: 2.10.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Salem Harrache
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2020-04-09 00:00:00.000000000 Z
15
+ date: 2020-04-11 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: childprocess
@@ -96,6 +96,20 @@ dependencies:
96
96
  - - "~>"
97
97
  - !ruby/object:Gem::Version
98
98
  version: '1.2'
99
+ - !ruby/object:Gem::Dependency
100
+ name: progressbar
101
+ requirement: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - "~>"
104
+ - !ruby/object:Gem::Version
105
+ version: '1'
106
+ type: :runtime
107
+ prerelease: false
108
+ version_requirements: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - "~>"
111
+ - !ruby/object:Gem::Version
112
+ version: '1'
99
113
  description: The mindful appliance builder
100
114
  email:
101
115
  - salem.harrache@inria.fr
@@ -157,8 +171,8 @@ files:
157
171
  - contrib/steps/setup/root_ssh_config.yaml
158
172
  - contrib/steps/setup/set_user_password.yaml
159
173
  - contrib/steps/setup/system_optimization.yaml
160
- - erb/extend.erb
161
- - erb/userconf.erb
174
+ - erb/extend.yaml.erb
175
+ - erb/userconf.yaml.erb
162
176
  - kameleon-builder.gemspec
163
177
  - lib/kameleon.rb
164
178
  - lib/kameleon/cli.rb
@@ -226,7 +240,7 @@ rubyforge_project:
226
240
  rubygems_version: 2.7.6.2
227
241
  signing_key:
228
242
  specification_version: 4
229
- summary: Kameleon is a tool to build virtual machines from scratch
243
+ summary: Kameleon is a tool to build system appliances from scratch
230
244
  test_files:
231
245
  - tests/helper.rb
232
246
  - tests/issue76/fail.stdout
@@ -1,33 +0,0 @@
1
- #==============================================================================
2
- # vim: softtabstop=2 shiftwidth=2 expandtab fenc=utf-8 cc=81 tw=80
3
- #==============================================================================
4
- #
5
- # DESCRIPTION: <MY RECIPE DESCRIPTION>
6
- #
7
- #==============================================================================
8
- ---
9
- extend: <%= tpl.relative_path_from_recipe(recipe_path) %>
10
-
11
- global:
12
- # This is the backend you have imported to switch to an other backend BCKD do:
13
- #
14
- # kameleon template import <%= tpl.relative_path_from_recipe(recipe_path) %> --global backend:BCKB
15
- #
16
- # Then, uncomment and update the following variable.
17
- <% if Kameleon.env.global["backend"] %>
18
- backend: <%= Kameleon.env.global["backend"] %>
19
- <% else %>
20
- # backend: qemu
21
- <% end %>
22
- # To see the variables that you can override, use the following command:
23
- #
24
- # kameleon info <%= recipe_name %>
25
-
26
- bootstrap:
27
- - "@base"
28
-
29
- setup:
30
- - "@base"
31
-
32
- export:
33
- - "@base"