kameleon-builder 2.10.2 → 2.10.3

Sign up to get free protection for your applications and to get access to all the features.
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"