buildizer 0.0.7 → 0.0.8

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,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NTgxMGMxNTEzOTg5MDhjMmExZGUwOWM3M2JjMmM0NjdhYjNkODBiOA==
4
+ NzJlYTY0NmI3OGFiMTRmOGEwMjg4ZmY2YjFkZmFkNTJlZjc5ZDQyZg==
5
5
  data.tar.gz: !binary |-
6
- MjRhZjU1NzlmOGM3ZjMyMzEzMDk5NDY5ZmQ0ZGJhZGY1ZGI5YjdhMQ==
6
+ OTdiYzQ0YWNjYjZmM2VlYmI3Mzk2ZjNlODNkZjFjYmVkOWZkZTY4ZA==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- Nzk3ZjIyMzVlMmNhOTczMDk5YjQ3NjA3NTIzNjVhZGE4MTY4NjQzMWY4ZjQ5
10
- NDc2OWIxZmYyYTE3NzgxMTE4N2ZkYjNmZDQxNzVkMzFjNzc1MWNjMWNmODI0
11
- ZmI2MzZjYzhiYzY4MmFkMjExMTM3MDJkMDA3M2MzYTNmYmU3ZDk=
9
+ MGVlZmNiYzFkN2U3NDM5NWVmZDg0ZDNmNmU0ZjJiN2UxZmE3OTg0YWJlYWIx
10
+ NGQwYTg4NTA4MDkzYTdhZDFjYzI3MzJkNGI3MTVlZTNlNDlhZGJjNzhkOGRl
11
+ NTA5OGNlN2Y5Y2ZmNzMxOTQ1MDE1OTI1ZDNjZmM1ZTkxODRhNmE=
12
12
  data.tar.gz: !binary |-
13
- YTljMjYyZmJiZDdmY2E3MDRhNTVjNjY1ZTJmMWQ3NjUyYWU5YTAxNTU4OTE3
14
- YjRlOTJhOTA4YTc5NjExZjk0ZWQxOTE3ZmIzMThhYjU2YTc2YmQ4OGRkMmVm
15
- OTNlNWFmZDNmMDBmYWQ2OTE2YWE3ZWQwZGRjYzhjMDQyNjJkNDg=
13
+ ZTU5ZTRhYTgyOTJhMWQ4ZDY4ZjQ1YWFlZWU3ODk4MGMyOGMyMDgxYTBlZWNh
14
+ ZWVjYTE4NzUzMGYzOTIwMTIyMTQ1ZGE2MWI4NTUwYmIxY2JmM2VmZWI5MTM1
15
+ OGIxYzJhYzBiNzhhYjE5NjQ1OTZjZDdhZTcxNDEyMWViZWU0YWM=
data/Gemfile.lock CHANGED
@@ -1,6 +1,6 @@
1
1
  GIT
2
2
  remote: https://github.com/flant/shellfold.git
3
- revision: 7429a46664b45ab246ba7a88eac24f614d1945a7
3
+ revision: 4db6a6a953412f2973fb6a814a0517cd04b0658c
4
4
  specs:
5
5
  shellfold (0.0.3)
6
6
  mixlib-shellout (>= 2.2.6, < 3.0)
@@ -8,8 +8,9 @@ GIT
8
8
  PATH
9
9
  remote: .
10
10
  specs:
11
- buildizer (0.0.7)
11
+ buildizer (0.0.8)
12
12
  net_status (>= 0.0.1, < 1.0)
13
+ overcommit (>= 0.33.0, < 1.0)
13
14
  package_cloud (>= 0.2, < 1.0)
14
15
  shellfold (>= 0.0.1, < 1.0)
15
16
  thor (>= 0.19.1, < 1.0)
@@ -21,6 +22,8 @@ GEM
21
22
  backports (3.6.8)
22
23
  binding_of_caller (0.7.2)
23
24
  debug_inspector (>= 0.0.1)
25
+ childprocess (0.5.9)
26
+ ffi (~> 1.0, >= 1.0.11)
24
27
  coderay (1.1.1)
25
28
  colorize (0.6.0)
26
29
  debug_inspector (0.0.2)
@@ -40,6 +43,7 @@ GEM
40
43
  net-http-persistent (>= 2.7)
41
44
  net-http-pipeline
42
45
  highline (1.6.20)
46
+ iniparse (1.4.2)
43
47
  json (1.8.3)
44
48
  json_pure (1.8.1)
45
49
  launchy (2.4.3)
@@ -52,6 +56,9 @@ GEM
52
56
  net-http-persistent (2.9.4)
53
57
  net-http-pipeline (1.0.1)
54
58
  net_status (0.0.2)
59
+ overcommit (0.33.0)
60
+ childprocess (~> 0.5.8)
61
+ iniparse (~> 1.4)
55
62
  package_cloud (0.2.29)
56
63
  colorize (= 0.6.0)
57
64
  highline (= 1.6.20)
data/bin/buildizer CHANGED
@@ -5,7 +5,7 @@
5
5
  require 'buildizer'
6
6
 
7
7
  begin
8
- Buildizer::Cli.start
8
+ Buildizer::Cli::Main.start
9
9
  rescue Buildizer::Error => e
10
10
  $stderr.puts [e.net_status[:error], e.net_status[:message]].compact.join(': ')
11
11
  exit 1
data/buildizer.gemspec CHANGED
@@ -20,6 +20,7 @@ Gem::Specification.new do |spec|
20
20
  spec.add_dependency "net_status", ">= 0.0.1", "< 1.0"
21
21
  spec.add_dependency "shellfold", ">= 0.0.1", "< 1.0"
22
22
  spec.add_dependency "package_cloud", ">= 0.2", "< 1.0"
23
+ spec.add_dependency "overcommit", ">= 0.33.0", "< 1.0"
23
24
 
24
25
  spec.add_development_dependency "bundler", "~> 1.7"
25
26
  spec.add_development_dependency "rake", "~> 10.0"
@@ -95,7 +95,7 @@ module Buildizer
95
95
  def _required_params!(required_params, params)
96
96
  Array(required_params).each do |param|
97
97
  unless params[param] and not params[param].to_s.empty?
98
- raise Error, error: :input_error, message: "#{param} is not defined"
98
+ raise Error, error: :input_error, message: "Buildizer #{param} is not defined"
99
99
  end
100
100
  end
101
101
  end
@@ -107,7 +107,7 @@ module Buildizer
107
107
  def verify
108
108
  targets.tap do |res|
109
109
  unless res.any?
110
- raise Error, error: :input_error, message: "target is not defined"
110
+ raise Error, error: :input_error, message: "Buildizer target is not defined"
111
111
  end
112
112
  end
113
113
  end
@@ -170,7 +170,7 @@ module Buildizer
170
170
 
171
171
  packager.package_cloud_org.each do |org, token|
172
172
  unless token
173
- warn "No packagecloud token defined for org '#{org}' " +
173
+ warn "No package cloud token defined for org '#{org}' " +
174
174
  "(PACKAGECLOUD_TOKEN or PACKAGECLOUD_TOKEN_#{org.upcase}) [WARN]"
175
175
  end
176
176
  end
@@ -0,0 +1,76 @@
1
+ module Buildizer
2
+ module Ci
3
+ class Base
4
+ using Refine
5
+
6
+ attr_reader :packager
7
+
8
+ def initialize(packager)
9
+ super()
10
+
11
+ @packager = packager
12
+ end
13
+
14
+ def conf
15
+ @conf ||= conf_path.load_yaml
16
+ end
17
+
18
+ def conf_path
19
+ packager.package_path.join(conf_file_name)
20
+ end
21
+
22
+ def conf_file_name
23
+ ".#{ci_name}.yml"
24
+ end
25
+
26
+ def ci_name
27
+ self.class.ci_name
28
+ end
29
+
30
+ def setup!
31
+ raise
32
+ end
33
+
34
+ def configuration_actual?
35
+ raise
36
+ end
37
+
38
+ def git_tag
39
+ res = _git_tag.to_s
40
+ if res.empty? then nil else res end
41
+ end
42
+
43
+ def _git_tag
44
+ raise
45
+ end
46
+
47
+ def buildizer_install_instructions(master: nil)
48
+ if master
49
+ ['git clone https://github.com/flant/buildizer ~/buildizer',
50
+ 'echo "export BUNDLE_GEMFILE=~/buildizer/Gemfile" | tee -a ~/.bashrc',
51
+ 'export BUNDLE_GEMFILE=~/buildizer/Gemfile',
52
+ 'gem install bundler',
53
+ 'gem install overcommit',
54
+ 'bundle install',
55
+ ]
56
+ else
57
+ 'gem install buildizer'
58
+ end
59
+ end
60
+
61
+ def package_cloud_setup!
62
+ raise
63
+ end
64
+
65
+ def docker_cache_setup!
66
+ raise
67
+ end
68
+
69
+ class << self
70
+ def ci_name
71
+ raise
72
+ end
73
+ end # << self
74
+ end # Base
75
+ end # Ci
76
+ end # Buildizer
@@ -0,0 +1,15 @@
1
+ module Buildizer
2
+ module Ci
3
+ class GitlabCi < Base
4
+ def _git_tag
5
+ ENV['CI_BUILD_TAG']
6
+ end
7
+
8
+ class << self
9
+ def ci_name
10
+ 'gitlab-ci'
11
+ end
12
+ end # << self
13
+ end # GitlabCi
14
+ end # Ci
15
+ end # Buildizer
@@ -0,0 +1,47 @@
1
+ module Buildizer
2
+ module Ci
3
+ class Travis
4
+ module DockerCacheMod
5
+ class << self
6
+ def included(base)
7
+ base.class_eval do
8
+ env_vars prefix: :docker_cache, repo: 'BUILDIZER_DOCKER_CACHE',
9
+ user: 'BUILDIZER_DOCKER_CACHE_USERNAME',
10
+ password: 'BUILDIZER_DOCKER_CACHE_PASSWORD',
11
+ email: 'BUILDIZER_DOCKER_CACHE_EMAIL',
12
+ server: 'BUILDIZER_DOCKER_CACHE_SERVER'
13
+ end # class_eval
14
+ end
15
+ end # << self
16
+
17
+ def docker_cache_setup!
18
+ if packager.docker_cache_clear_settings?
19
+ with_travis do
20
+ packager.with_log(desc: "Travis docker cache settings") do |&fin|
21
+ docker_cache_repo_var_delete!
22
+ docker_cache_user_var_delete!
23
+ docker_cache_password_var_delete!
24
+ docker_cache_email_var_delete!
25
+ docker_cache_server_var_delete!
26
+
27
+ fin.call 'DELETED'
28
+ end # with_log
29
+ end # with_travis
30
+ elsif packager.docker_cache_update_settings?
31
+ with_travis do
32
+ packager.with_log(desc: "Travis docker cache settings") do |&fin|
33
+ docker_cache_repo_var_update! packager.setup_docker_cache_repo, public: true
34
+ docker_cache_user_var_update! packager.setup_docker_cache_user, public: false
35
+ docker_cache_password_var_update! packager.setup_docker_cache_password, public: false
36
+ docker_cache_email_var_update! packager.setup_docker_cache_email, public: false
37
+ docker_cache_server_var_update! packager.setup_docker_cache_server, public: true
38
+
39
+ fin.call 'UPDATED'
40
+ end # with_log
41
+ end # with_travis
42
+ end
43
+ end
44
+ end # DockerCacheMod
45
+ end # Travis
46
+ end # Ci
47
+ end # Buildizer
@@ -0,0 +1,76 @@
1
+ module Buildizer
2
+ module Ci
3
+ class Travis
4
+ module PackageCloudMod
5
+ class << self
6
+ def included(base)
7
+ base.class_eval do
8
+ env_vars prefix: :package_cloud, repo_list: 'PACKAGECLOUD'
9
+ end # class_eval
10
+ end
11
+ end # << self
12
+
13
+ def package_cloud_token_var_name(org: nil)
14
+ if org
15
+ "PACKAGECLOUD_TOKEN_#{org.upcase}"
16
+ else
17
+ 'PACKAGECLOUD_TOKEN'
18
+ end
19
+ end
20
+
21
+ def package_cloud_token_var(org: nil)
22
+ repo.env_vars[package_cloud_token_var_name(org: org)]
23
+ end
24
+
25
+ def package_cloud_token_var_delete!(**kwargs)
26
+ var = package_cloud_token_var(**kwargs)
27
+ var.delete if var
28
+ end
29
+
30
+ def package_cloud_token_var_update!(value, org: nil, **kwargs)
31
+ if value
32
+ repo.env_vars.upsert(package_cloud_token_var_name(org: org), value, **kwargs)
33
+ else
34
+ package_cloud_token_var_delete!(org: org)
35
+ end
36
+ end
37
+
38
+ def package_cloud_setup!
39
+ if packager.package_cloud_clear_settings?
40
+ with_travis do
41
+ repo_list = []
42
+ repo_list = package_cloud_repo_list_var.value.split(',') if package_cloud_repo_list_var
43
+ org_list = repo_list.map {|repo| repo.split('/').first}.uniq
44
+ org_list.each do |org|
45
+ packager.with_log(desc: "Travis package cloud token for '#{org}'") do |&fin|
46
+ package_cloud_token_var_delete! org: org
47
+ fin.call 'DELETED'
48
+ end
49
+ end
50
+
51
+ packager.with_log(desc: "Travis package cloud repo list") do |&fin|
52
+ package_cloud_repo_list_var_delete!
53
+ fin.call 'DELETED'
54
+ end
55
+ end # with_travis
56
+ elsif packager.package_cloud_update_settings?
57
+ with_travis do
58
+ packager.with_log(desc: "Travis package cloud repo list") do |&fin|
59
+ package_cloud_repo_list_var_update! packager.setup_package_cloud_repo_list.join(','), public: true
60
+ fin.call 'UPDATED'
61
+ end # with_log
62
+
63
+ packager.setup_package_cloud_org_desc_list.each do |desc|
64
+ next unless desc[:token]
65
+ packager.with_log(desc: "Travis package cloud token for '#{desc[:org]}'") do |&fin|
66
+ package_cloud_token_var_update! desc[:token], org: desc[:org], public: false
67
+ fin.call 'UPDATED'
68
+ end # with_log
69
+ end
70
+ end # with_travis
71
+ end
72
+ end
73
+ end # PackageCloudMod
74
+ end # Travis
75
+ end # Ci
76
+ end # Buildizer
@@ -0,0 +1,42 @@
1
+ module Buildizer
2
+ module Ci
3
+ class Travis
4
+ module PackageVersionTagMod
5
+ using Refine
6
+
7
+ def require_tag_var_name
8
+ 'BUILDIZER_REQUIRE_TAG'
9
+ end
10
+
11
+ def require_tag_var
12
+ repo.env_vars[require_tag_var_name]
13
+ end
14
+
15
+ def require_tag_var_upsert(**kwargs)
16
+ repo.env_vars.upsert(require_tag_var_name, kwargs.delete(:value), public: true, **kwargs)
17
+ end
18
+
19
+ def require_tag_setup!
20
+ with_travis do
21
+ packager.with_log(desc: "Travis require tag for deploy") do |&fin|
22
+ if packager.cli.options['require_tag'].nil?
23
+ unless require_tag_var
24
+ require_tag_var_upsert(value: true.to_env)
25
+ fin.call 'ENABLED'
26
+ else
27
+ fin.call
28
+ end
29
+ elsif packager.cli.options['require_tag']
30
+ require_tag_var_upsert(value: true.to_env)
31
+ fin.call 'ENABLED'
32
+ else
33
+ require_tag_var_upsert(value: false.to_env)
34
+ fin.call 'DISABLED'
35
+ end
36
+ end # with_log
37
+ end # with_travis
38
+ end
39
+ end # PackageVersionTagMod
40
+ end # Travis
41
+ end # Ci
42
+ end # Buildizer
@@ -0,0 +1,124 @@
1
+ module Buildizer
2
+ module Ci
3
+ class Travis < Base
4
+ class << self
5
+ def ci_name
6
+ 'travis'
7
+ end
8
+
9
+ def env_vars(prefix:, **kwargs)
10
+ kwargs.each do |name, var_name|
11
+ define_method("#{prefix}_#{name}_var") {repo.env_vars[var_name]}
12
+ define_method("#{prefix}_#{name}_var_name") {var_name}
13
+ define_method("#{prefix}_#{name}_var_delete!") do
14
+ var = send("#{prefix}_#{name}_var")
15
+ var.delete if var
16
+ end
17
+ define_method("#{prefix}_#{name}_var_update!") do |value, **kwargs|
18
+ if value
19
+ repo.env_vars.upsert(var_name, value, **kwargs)
20
+ else
21
+ send("#{prefix}_#{name}_var_delete!")
22
+ end
23
+ end
24
+ end # each
25
+ end
26
+ end # << self
27
+
28
+ autoload :PackageCloudMod, 'buildizer/ci/travis/package_cloud_mod'
29
+ autoload :DockerCacheMod, 'buildizer/ci/travis/docker_cache_mod'
30
+ autoload :PackageVersionTagMod, 'buildizer/ci/travis/package_version_tag_mod'
31
+
32
+ include PackageCloudMod
33
+ include DockerCacheMod
34
+ include PackageVersionTagMod
35
+
36
+ def setup!
37
+ packager.write_path(conf_path, YAML.dump(actual_conf))
38
+ require_tag_setup!
39
+ end
40
+
41
+ def configuration_actual?
42
+ conf == actual_conf
43
+ end
44
+
45
+ def actual_conf
46
+ install = [
47
+ 'sudo apt-get update',
48
+ 'sudo apt-get install -y apt-transport-https ca-certificates',
49
+ 'sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D',
50
+ 'echo "deb https://apt.dockerproject.org/repo ubuntu-trusty main" | sudo tee /etc/apt/sources.list.d/docker.list',
51
+ 'sudo apt-get update',
52
+
53
+ # FIXME [https://github.com/docker/docker/issues/20316]:
54
+ 'sudo apt-get -o dpkg::options::="--force-confnew" install -y docker-engine=1.9.1-0~trusty',
55
+
56
+ 'echo "docker-engine hold" | sudo dpkg --set-selections',
57
+ ]
58
+ install.push(*Array(buildizer_install_instructions(master: packager.project_settings['master'])))
59
+
60
+ env = packager.targets.map {|t| "BUILDIZER_TARGET=#{t}"}
61
+ conf.merge(
62
+ 'dist' => 'trusty',
63
+ 'sudo' => 'required',
64
+ 'cache' => 'apt',
65
+ 'language' => 'ruby',
66
+ 'rvm' => '2.2.1',
67
+ 'install' => install,
68
+ 'before_script' => 'buildizer prepare',
69
+ 'script' => 'buildizer build',
70
+ 'env' => env,
71
+ 'after_success' => 'buildizer deploy',
72
+ )
73
+ end
74
+
75
+ def _git_tag
76
+ ENV['TRAVIS_TAG']
77
+ end
78
+
79
+ def repo_name
80
+ packager.git_remote_url.split(':')[1].split('.')[0]
81
+ rescue
82
+ raise Error, error: :input_error,
83
+ message: "unable to determine travis repo name " +
84
+ "from git remote url #{packager.git_remote_url}"
85
+ end
86
+
87
+ def repo
88
+ ::Travis::Repository.find(repo_name)
89
+ end
90
+
91
+ def login
92
+ @logged_in ||= begin
93
+ packager.with_log(desc: "Login into travis") do |&fin|
94
+ packager.user_settings['travis'] ||= {}
95
+
96
+ if packager.cli.options['reset_github_token']
97
+ packager.user_settings['travis'].delete('github_token')
98
+ packager.user_settings_save!
99
+ end
100
+
101
+ packager.user_settings['travis']['github_token'] ||= begin
102
+ reset_github_token = true
103
+ packager.cli.ask("GitHub access token:", echo: false).tap{puts}
104
+ end
105
+
106
+ ::Travis.github_auth(packager.user_settings['travis']['github_token'])
107
+ packager.user_settings_save! if reset_github_token
108
+
109
+ fin.call "LOGGED IN: #{::Travis::User.current.name}"
110
+ end # with_log
111
+
112
+ true
113
+ end
114
+ end
115
+
116
+ def with_travis(&blk)
117
+ login
118
+ yield
119
+ rescue ::Travis::Client::Error => err
120
+ raise Error, message: "travis: #{err.message}"
121
+ end
122
+ end # Travis
123
+ end # Ci
124
+ end # Buildizer
@@ -0,0 +1,4 @@
1
+ module Buildizer
2
+ module Ci
3
+ end # Ci
4
+ end # Buildizer
@@ -0,0 +1,17 @@
1
+ module Buildizer
2
+ module Cli
3
+ class Base < ::Thor
4
+ include OptionMod
5
+
6
+ add_shared_options(
7
+ debug: {type: :boolean, default: false, desc: "turn on live logging for external commands"},
8
+ )
9
+
10
+ no_commands do
11
+ def packager
12
+ @packager ||= Buildizer::Packager.new(self)
13
+ end
14
+ end # no_commands
15
+ end # Base
16
+ end # Cli
17
+ end # Buildizer
@@ -0,0 +1,85 @@
1
+ module Buildizer
2
+ module Cli
3
+ class Main < Base
4
+ include OptionMod
5
+
6
+ desc "setup", "Setup buildizer"
7
+ shared_options
8
+ method_option :master, type: :boolean, default: nil,
9
+ desc: "use latest master branch of buildizer from github in ci"
10
+ method_option :verify_ci, type: :boolean, default: false,
11
+ desc: "only verify ci configuration is up to date"
12
+ method_option :reset_github_token, type: :boolean, default: false,
13
+ desc: "delete github token from user settings and enter new"
14
+ method_option :require_tag, type: :boolean, default: nil,
15
+ desc: "pass only git tagged commits for deploy stage"
16
+
17
+ method_option :package_cloud, type: :array, default: nil,
18
+ desc: "package cloud repo list"
19
+ method_option :reset_package_cloud_token, type: :boolean, default: false,
20
+ desc: "delete package cloud tokens " +
21
+ "from user settings for each specified repo " +
22
+ "and enter new"
23
+ method_option :clear_package_cloud, type: :boolean, default: false,
24
+ desc: "clear all package cloud settings"
25
+
26
+ method_option :docker_cache, type: :string, default: nil,
27
+ desc: "docker cache repo name in format '<org>/<name>'"
28
+ method_option :docker_cache_user, type: :string, default: nil,
29
+ desc: "docker cache login user name to access specified repo"
30
+ method_option :docker_cache_email, type: :string, default: nil,
31
+ desc: "docker cache login email to access specified repo"
32
+ method_option :docker_cache_server, type: :string, default: nil,
33
+ desc: "docker cache login server to access specified repo"
34
+ method_option :reset_docker_cache_password, type: :boolean, default: false,
35
+ desc: "delete docker cache user password " +
36
+ "from user settings and enter new"
37
+ method_option :clear_docker_cache, type: :boolean, default: false,
38
+ desc: "clear all docker cache settings"
39
+ def setup
40
+ if options['verify_ci']
41
+ raise(Error, message: "#{packager.ci.ci_name} confugration update needed") unless packager.ci.configuration_actual?
42
+ else
43
+ packager.project_settings_setup!
44
+ packager.user_settings_setup!
45
+ packager.ci.setup!
46
+ packager.package_cloud_setup!
47
+ packager.docker_cache_setup!
48
+ packager.overcommit_setup!
49
+ packager.overcommit_verify_setup!
50
+ packager.overcommit_ci_setup!
51
+ end
52
+ end
53
+
54
+ desc "deinit", "Deinitialize settings (.buildizer.yml, git pre-commit hook)"
55
+ shared_options
56
+ def deinit
57
+ packager.deinit!
58
+ end
59
+
60
+ desc "prepare", "Prepare images for building packages"
61
+ shared_options
62
+ def prepare
63
+ packager.prepare!
64
+ end
65
+
66
+ desc "build", "Build packages"
67
+ shared_options
68
+ def build
69
+ packager.build!
70
+ end
71
+
72
+ desc "deploy", "Deploy packages"
73
+ shared_options
74
+ def deploy
75
+ packager.deploy!
76
+ end
77
+
78
+ desc "verify", "Verify targets params"
79
+ shared_options
80
+ def verify
81
+ packager.verify!
82
+ end
83
+ end # Main
84
+ end # Cli
85
+ end # Buildizer
@@ -0,0 +1,35 @@
1
+ module Buildizer
2
+ module Cli
3
+ module OptionMod
4
+ class << self
5
+ def included(base)
6
+ base.send(:extend, ClassMethods)
7
+ end
8
+ end # << self
9
+
10
+ module ClassMethods
11
+ def _shared_options
12
+ @_shared_options ||= {}
13
+ end
14
+
15
+ def _all_shared_options
16
+ res = _shared_options
17
+ if klass = self.superclass and klass.respond_to?(:_all_shared_options)
18
+ res = res.merge(klass._all_shared_options)
19
+ end
20
+ res
21
+ end
22
+
23
+ def add_shared_options(options)
24
+ _shared_options.merge! options
25
+ end
26
+
27
+ def shared_options
28
+ _all_shared_options.each do |name, options|
29
+ method_option name, options
30
+ end
31
+ end
32
+ end # ClassMethods
33
+ end # OptionMod
34
+ end # Cli
35
+ end # Buildizer