wright 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. data/NEWS.md +7 -0
  3. data/README.md +60 -54
  4. data/lib/wright/cli.rb +44 -18
  5. data/lib/wright/dry_run.rb +7 -0
  6. data/lib/wright/provider/directory.rb +26 -30
  7. data/lib/wright/provider/file.rb +34 -34
  8. data/lib/wright/provider/group/darwin_directory_service.rb +8 -7
  9. data/lib/wright/provider/group/gnu_passwd.rb +5 -5
  10. data/lib/wright/provider/group.rb +53 -36
  11. data/lib/wright/provider/package/apt.rb +32 -8
  12. data/lib/wright/provider/package/homebrew.rb +6 -5
  13. data/lib/wright/provider/package/yum.rb +39 -0
  14. data/lib/wright/provider/package.rb +30 -16
  15. data/lib/wright/provider/symlink.rb +32 -33
  16. data/lib/wright/provider/user/darwin_directory_service.rb +14 -17
  17. data/lib/wright/provider/user/gnu_passwd.rb +20 -21
  18. data/lib/wright/provider/user.rb +58 -41
  19. data/lib/wright/resource/group.rb +1 -0
  20. data/lib/wright/resource/package.rb +16 -3
  21. data/lib/wright/resource/user.rb +1 -0
  22. data/lib/wright/resource.rb +4 -2
  23. data/lib/wright/util/user.rb +34 -2
  24. data/lib/wright/version.rb +1 -1
  25. data/man/wright.1 +15 -11
  26. data/spec/cli_spec.rb +18 -0
  27. data/spec/provider/group/darwin_directory_service_spec.rb +76 -220
  28. data/spec/provider/group/gnu_passwd_spec.rb +36 -189
  29. data/spec/provider/group_spec.rb +180 -27
  30. data/spec/provider/package/apt/apt-cache_policy_dmenu.return +1 -0
  31. data/spec/provider/package/apt/apt-cache_policy_dmenu.stderr +0 -0
  32. data/spec/provider/package/apt/apt-cache_policy_dmenu.stdout +4 -0
  33. data/spec/provider/package/apt/apt-cache_policy_htop.stdout +3 -3
  34. data/spec/provider/package/apt/apt-cache_policy_linux-image-3.2.0-4-amd64.return +1 -0
  35. data/spec/provider/package/apt/apt-cache_policy_linux-image-3.2.0-4-amd64.stderr +0 -0
  36. data/spec/provider/package/apt/apt-cache_policy_linux-image-3.2.0-4-amd64.stdout +6 -0
  37. data/spec/provider/package/apt/apt-cache_policy_linux-image.return +1 -0
  38. data/spec/provider/package/apt/apt-cache_policy_linux-image.stderr +0 -0
  39. data/spec/provider/package/apt/apt-cache_policy_linux-image.stdout +4 -0
  40. data/spec/provider/package/apt/apt-cache_policy_suckless-tools.return +1 -0
  41. data/spec/provider/package/apt/apt-cache_policy_suckless-tools.stderr +0 -0
  42. data/spec/provider/package/apt/apt-cache_policy_suckless-tools.stdout +6 -0
  43. data/spec/provider/package/apt/apt-cache_showpkg_dmenu.return +1 -0
  44. data/spec/provider/package/apt/apt-cache_showpkg_dmenu.stderr +0 -0
  45. data/spec/provider/package/apt/apt-cache_showpkg_dmenu.stdout +9 -0
  46. data/spec/provider/package/apt/apt-cache_showpkg_htop.return +1 -0
  47. data/spec/provider/package/apt/apt-cache_showpkg_htop.stderr +0 -0
  48. data/spec/provider/package/apt/apt-cache_showpkg_htop.stdout +20 -0
  49. data/spec/provider/package/apt/apt-cache_showpkg_linux-image.return +1 -0
  50. data/spec/provider/package/apt/apt-cache_showpkg_linux-image.stderr +0 -0
  51. data/spec/provider/package/apt/apt-cache_showpkg_linux-image.stdout +11 -0
  52. data/spec/provider/package/apt/apt-cache_showpkg_not-a-real-package.return +1 -0
  53. data/spec/provider/package/apt/apt-cache_showpkg_not-a-real-package.stderr +0 -0
  54. data/spec/provider/package/apt/apt-cache_showpkg_not-a-real-package.stdout +1 -0
  55. data/spec/provider/package/apt/apt-cache_showpkg_suckless-tools.return +1 -0
  56. data/spec/provider/package/apt/apt-cache_showpkg_suckless-tools.stderr +0 -0
  57. data/spec/provider/package/apt/apt-cache_showpkg_suckless-tools.stdout +26 -0
  58. data/spec/provider/package/apt/apt-get_--purge_remove_-qy_abcde.return +1 -0
  59. data/spec/provider/package/apt/apt-get_--purge_remove_-qy_abcde.stderr +0 -0
  60. data/spec/provider/package/apt/apt-get_--purge_remove_-qy_abcde.stdout +15 -0
  61. data/spec/provider/package/apt_spec.rb +82 -14
  62. data/spec/provider/package/homebrew/brew_install_--with-default-names_gnu-units.return +1 -0
  63. data/spec/provider/package/homebrew/brew_install_--with-default-names_gnu-units.stderr +0 -0
  64. data/spec/provider/package/homebrew/brew_install_--with-default-names_gnu-units.stdout +7 -0
  65. data/spec/provider/package/homebrew/brew_uninstall_--force_lame.return +1 -0
  66. data/spec/provider/package/homebrew/brew_uninstall_--force_lame.stderr +0 -0
  67. data/spec/provider/package/homebrew/brew_uninstall_--force_lame.stdout +1 -0
  68. data/spec/provider/package/homebrew_spec.rb +33 -6
  69. data/spec/provider/package/yum/rpm_-q_httpd.return +1 -0
  70. data/spec/provider/package/yum/rpm_-q_httpd.stderr +0 -0
  71. data/spec/provider/package/yum/rpm_-q_httpd.stdout +1 -0
  72. data/spec/provider/package/yum/rpm_-q_zsh.return +1 -0
  73. data/spec/provider/package/yum/rpm_-q_zsh.stderr +0 -0
  74. data/spec/provider/package/yum/rpm_-q_zsh.stdout +1 -0
  75. data/spec/provider/package/yum/yum_install_-y_mc-4.8.7-8.el7.return +1 -0
  76. data/spec/provider/package/yum/yum_install_-y_mc-4.8.7-8.el7.stderr +0 -0
  77. data/spec/provider/package/yum/yum_install_-y_mc-4.8.7-8.el7.stdout +37 -0
  78. data/spec/provider/package/yum/yum_install_-y_nano.return +1 -0
  79. data/spec/provider/package/yum/yum_install_-y_nano.stderr +0 -0
  80. data/spec/provider/package/yum/yum_install_-y_nano.stdout +36 -0
  81. data/spec/provider/package/yum/yum_install_-y_not-a-real-package.return +1 -0
  82. data/spec/provider/package/yum/yum_install_-y_not-a-real-package.stderr +1 -0
  83. data/spec/provider/package/yum/yum_install_-y_not-a-real-package.stdout +6 -0
  84. data/spec/provider/package/yum/yum_install_with_options.return +1 -0
  85. data/spec/provider/package/yum/yum_install_with_options.stderr +0 -0
  86. data/spec/provider/package/yum/yum_install_with_options.stdout +53 -0
  87. data/spec/provider/package/yum/yum_remove_-y_screen.return +1 -0
  88. data/spec/provider/package/yum/yum_remove_-y_screen.stderr +0 -0
  89. data/spec/provider/package/yum/yum_remove_-y_screen.stdout +31 -0
  90. data/spec/provider/package/yum/yum_remove_with_options.return +1 -0
  91. data/spec/provider/package/yum/yum_remove_with_options.stderr +0 -0
  92. data/spec/provider/package/yum/yum_remove_with_options.stdout +30 -0
  93. data/spec/provider/package/yum_spec.rb +130 -0
  94. data/spec/provider/user/darwin_directory_service_spec.rb +12 -10
  95. data/spec/provider/user/gnu_passwd_spec.rb +9 -9
  96. data/spec/provider/user_spec.rb +26 -18
  97. data/spec/resource/package_spec.rb +8 -0
  98. data/spec/resource_spec.rb +17 -9
  99. metadata +153 -16
@@ -7,13 +7,18 @@ module Wright
7
7
  # User provider. Used as a base class for {Resource::User}
8
8
  # providers.
9
9
  class User < Wright::Provider
10
- # Adds the user.
10
+ # Creates or updates the user.
11
11
  #
12
12
  # @return [void]
13
13
  def create
14
- user = @resource.name
15
- unless_uptodate(:create, "user already created: '#{user}'") do
16
- create_user
14
+ unless_uptodate(:create, "user already created: '#{user_name}'") do
15
+ unless_dry_run("create user: '#{user_name}'") do
16
+ if user_exists?
17
+ update_user
18
+ else
19
+ create_user
20
+ end
21
+ end
17
22
  end
18
23
  end
19
24
 
@@ -21,14 +26,47 @@ module Wright
21
26
  #
22
27
  # @return [void]
23
28
  def remove
24
- user = @resource.name
25
- unless_uptodate(:remove, "user already removed: '#{user}'") do
26
- remove_user
29
+ unless_uptodate(:remove, "user already removed: '#{user_name}'") do
30
+ unless_dry_run("remove user: '#{user_name}'") do
31
+ remove_user
32
+ end
27
33
  end
28
34
  end
29
35
 
30
36
  private
31
37
 
38
+ def user_name
39
+ @resource.name
40
+ end
41
+
42
+ def uid
43
+ @resource.uid
44
+ end
45
+
46
+ def primary_group
47
+ @resource.primary_group
48
+ end
49
+
50
+ def full_name
51
+ @resource.full_name
52
+ end
53
+
54
+ def groups
55
+ @resource.groups
56
+ end
57
+
58
+ def shell
59
+ @resource.shell
60
+ end
61
+
62
+ def home
63
+ @resource.home
64
+ end
65
+
66
+ def system_user?
67
+ @resource.system
68
+ end
69
+
32
70
  # @api public
33
71
  # Checks if the user is up-to-date for a given action.
34
72
  #
@@ -58,64 +96,43 @@ module Wright
58
96
  primary_group_uptodate?
59
97
  end
60
98
 
61
- def create_user
62
- unless_dry_run("create user: '#{@resource.name}'") do
63
- if user_exists?
64
- update_user
65
- else
66
- add_user
67
- end
68
- end
69
- end
70
-
71
- def remove_user
72
- unless_dry_run("remove user: '#{@resource.name}'") do
73
- delete_user
74
- end
75
- end
76
-
77
99
  def user_data
78
- Etc.getpwnam(@resource.name)
79
- rescue ArgumentError
80
- nil
100
+ Wright::Util::User.safe_getpwnam(user_name)
81
101
  end
82
102
 
83
103
  def uid_uptodate?
84
- @resource.uid.nil? || user_data.uid == @resource.uid
104
+ uid.nil? || user_data.uid == uid
85
105
  end
86
106
 
87
107
  def full_name_uptodate?
88
- @resource.full_name.nil? ||
89
- user_data.gecos.split(',').first == @resource.full_name
108
+ full_name.nil? || user_data.gecos.split(',').first == full_name
90
109
  end
91
110
 
92
111
  def groups_uptodate?
93
- return true if @resource.groups.nil?
94
- groups = []
95
- Etc.group { |g| groups << g.name if g.mem.include?(@resource.name) }
96
- groups.uniq.sort == @resource.groups.uniq.sort
112
+ return true if groups.nil?
113
+ target_groups = []
114
+ Etc.group { |g| target_groups << g.name if g.mem.include?(user_name) }
115
+ target_groups.sort.uniq == groups.sort.uniq
97
116
  end
98
117
 
99
118
  def shell_uptodate?
100
- @resource.shell.nil? || user_data.shell == @resource.shell
119
+ shell.nil? || user_data.shell == shell
101
120
  end
102
121
 
103
122
  def home_uptodate?
104
- @resource.home.nil? || user_data.dir == @resource.home
123
+ home.nil? || user_data.dir == home
105
124
  end
106
125
 
107
126
  def primary_group_uptodate?
108
- return true if @resource.primary_group.nil?
109
-
110
- gid = Wright::Util::User.group_to_gid(@resource.primary_group)
111
- user_data.gid == gid
127
+ return true if primary_group.nil?
128
+ user_data.gid == Wright::Util::User.group_to_gid(primary_group)
112
129
  end
113
130
 
114
131
  def user_exists?
115
132
  !user_data.nil?
116
133
  end
117
134
 
118
- def add_user
135
+ def create_user
119
136
  fail NotImplementedError
120
137
  end
121
138
 
@@ -123,7 +140,7 @@ module Wright
123
140
  fail NotImplementedError
124
141
  end
125
142
 
126
- def delete_user
143
+ def remove_user
127
144
  fail NotImplementedError
128
145
  end
129
146
  end
@@ -57,6 +57,7 @@ Wright::DSL.register_resource(Wright::Resource::Group)
57
57
 
58
58
  group_providers = {
59
59
  'debian' => 'Wright::Provider::Group::GnuPasswd',
60
+ 'rhel' => 'Wright::Provider::Group::GnuPasswd',
60
61
  'macosx' => 'Wright::Provider::Group::DarwinDirectoryService'
61
62
  }
62
63
  Wright::Config[:resources][:group] ||= {}
@@ -1,3 +1,5 @@
1
+ require 'forwardable'
2
+
1
3
  require 'wright/resource'
2
4
  require 'wright/dsl'
3
5
 
@@ -20,22 +22,32 @@ module Wright
20
22
  # htop.installed_versions
21
23
  # # => []
22
24
  class Package < Wright::Resource
25
+ extend Forwardable
26
+
23
27
  # @return [String] the package version to install or remove
24
28
  attr_accessor :version
25
29
 
30
+ # @return [String, Array<String>] the options passed to the
31
+ # package manager
32
+ attr_accessor :options
33
+
26
34
  # Initializes a Package.
27
35
  #
28
36
  # @param name [String] the package's name
29
37
  def initialize(name)
30
38
  super
31
39
  @version = nil
40
+ @options = nil
32
41
  @action = :install
33
42
  end
34
43
 
44
+ # @!method installed_versions
35
45
  # @return [Array<String>] the installed package versions
36
- def installed_versions
37
- @provider.installed_versions
38
- end
46
+ def_delegator :@provider, :installed_versions
47
+
48
+ # @!method installed?
49
+ # @return [Bool] +true+ if the package is installed
50
+ def_delegator :@provider, :installed?
39
51
 
40
52
  # Installs the Package.
41
53
  #
@@ -66,6 +78,7 @@ Wright::DSL.register_resource(Wright::Resource::Package)
66
78
 
67
79
  package_providers = {
68
80
  'debian' => 'Wright::Provider::Package::Apt',
81
+ 'rhel' => 'Wright::Provider::Package::Yum',
69
82
  'macosx' => 'Wright::Provider::Package::Homebrew'
70
83
  }
71
84
  Wright::Config[:resources][:package] ||= {}
@@ -70,6 +70,7 @@ Wright::DSL.register_resource(Wright::Resource::User)
70
70
 
71
71
  user_providers = {
72
72
  'debian' => 'Wright::Provider::User::GnuPasswd',
73
+ 'rhel' => 'Wright::Provider::User::GnuPasswd',
73
74
  'macosx' => 'Wright::Provider::User::DarwinDirectoryService'
74
75
  }
75
76
  Wright::Config[:resources][:user] ||= {}
@@ -123,10 +123,12 @@ module Wright
123
123
  def run_update_action
124
124
  return if @on_update.nil?
125
125
 
126
+ resource = "#{@resource_name} '#{@name}'"
127
+ notification = "run update action for #{resource}"
126
128
  if Wright.dry_run?
127
- resource = "#{@resource_name} '#{@name}'"
128
- Wright.log.info "(would) run update action for #{resource}"
129
+ Wright.log.info "(would) #{notification}"
129
130
  else
131
+ Wright.log.info notification
130
132
  @on_update.call
131
133
  end
132
134
  end
@@ -46,7 +46,7 @@ module Wright
46
46
  end
47
47
  private_class_method :to_id
48
48
 
49
- # Returns the the next free uid in a range.
49
+ # Returns the next free uid in a range.
50
50
  #
51
51
  # @param uid_range [Range] the uid range
52
52
  #
@@ -60,7 +60,7 @@ module Wright
60
60
  next_free_id(uid_range, :uid)
61
61
  end
62
62
 
63
- # Returns the the next free gid in a range.
63
+ # Returns the next free gid in a range.
64
64
  #
65
65
  # @param gid_range [Range] the gid range
66
66
  #
@@ -92,6 +92,38 @@ module Wright
92
92
  id_type == :uid ? Etc.method(:passwd) : Etc.method(:group)
93
93
  end
94
94
  private_class_method :id_iterator
95
+
96
+ # Returns a user entry.
97
+ #
98
+ # @param username [String] the name of the user
99
+ #
100
+ # @example
101
+ # Wright::Util::User.safe_getpwnam('this_user_does_not_exist')
102
+ # # => nil
103
+ #
104
+ # @return [Struct::Passwd, nil] the user entry or nil if the
105
+ # user does not exist
106
+ def self.safe_getpwnam(username)
107
+ Etc.getpwnam(username)
108
+ rescue ArgumentError
109
+ nil
110
+ end
111
+
112
+ # Returns a group entry.
113
+ #
114
+ # @param groupname [String] the name of the group
115
+ #
116
+ # @example
117
+ # Wright::Util::User.safe_getgrnam('this_group_does_not_exist')
118
+ # # => nil
119
+ #
120
+ # @return [Struct::Group, nil] the group entry or nil if the
121
+ # group does not exist
122
+ def self.safe_getgrnam(groupname)
123
+ Etc.getgrnam(groupname)
124
+ rescue ArgumentError
125
+ nil
126
+ end
95
127
  end
96
128
  end
97
129
  end
@@ -1,4 +1,4 @@
1
1
  module Wright # rubocop:disable Documentation
2
2
  # Current wright version
3
- VERSION = '0.3.2'
3
+ VERSION = '0.4.0'
4
4
  end
data/man/wright.1 CHANGED
@@ -2,12 +2,12 @@
2
2
  .\" Title: wright
3
3
  .\" Author: [see the "AUTHOR" section]
4
4
  .\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
5
- .\" Date: 04/22/2015
5
+ .\" Date: 06/03/2015
6
6
  .\" Manual: \ \&
7
7
  .\" Source: \ \&
8
8
  .\" Language: English
9
9
  .\"
10
- .TH "WRIGHT" "1" "04/22/2015" "\ \&" "\ \&"
10
+ .TH "WRIGHT" "1" "06/03/2015" "\ \&" "\ \&"
11
11
  .\" -----------------------------------------------------------------
12
12
  .\" * Define some portability stuff
13
13
  .\" -----------------------------------------------------------------
@@ -48,6 +48,18 @@ Run
48
48
  as a wright script\&. When multiple commands are passed, they are joined and run in sequence\&.
49
49
  .RE
50
50
  .PP
51
+ \fB\-r\fR \fILIBRARY\fR
52
+ .RS 4
53
+ Require
54
+ \fILIBRARY\fR
55
+ before running the wright script\&. When multiple libraries are passed, they are loaded in sequence\&.
56
+ .RE
57
+ .PP
58
+ \fB\-n, \-\-dry\-run\fR
59
+ .RS 4
60
+ Enable dry\-run mode\&. In dry\-run mode, wright resources do not modify the system, but you still have to make sure your own code does not cause any unwanted changes\&.
61
+ .RE
62
+ .PP
51
63
  \fB\-v, \-\-verbose\fR
52
64
  .RS 4
53
65
  Print debugging information\&.
@@ -143,15 +155,7 @@ To install tmux and update its config file from a wright script, create the foll
143
155
  .\}
144
156
  .nf
145
157
  package \*(Aqtmux\*(Aq
146
- .fi
147
- .if n \{\
148
- .RE
149
- .\}
150
- .sp
151
- .if n \{\
152
- .RS 4
153
- .\}
154
- .nf
158
+
155
159
  file \*(Aq/etc/tmux\&.conf\*(Aq do |f|
156
160
  f\&.content = <<EOF
157
161
  unbind C\-b
data/spec/cli_spec.rb CHANGED
@@ -21,6 +21,18 @@ describe Wright::CLI do
21
21
  @cli.send(:commands).must_equal %w(foo bar)
22
22
  end
23
23
 
24
+ it 'parses -r LIBRARY' do
25
+ argv = %w(-r library1 -r library2 -rlibrary3 file.rb)
26
+ @cli.parse(argv).must_equal %w(file.rb)
27
+ @cli.send(:requires).must_equal %w(library1 library2 library3)
28
+ end
29
+
30
+ it 'parses --dry-run' do
31
+ argv = %w(--dry-run file.rb)
32
+ @cli.parse(argv).must_equal %w(file.rb)
33
+ @cli.send(:dry_run).must_equal true
34
+ end
35
+
24
36
  it 'parses --verbose' do
25
37
  argv = ['--verbose']
26
38
  @cli.parse(argv)
@@ -38,8 +50,14 @@ describe Wright::CLI do
38
50
  it 'parses --version' do
39
51
  argv = ['--version']
40
52
  expected = "wright version #{Wright::VERSION}\n"
53
+ -> { @cli.run(argv) }.must_output expected
54
+ end
41
55
 
56
+ it 'enables dry-run mode when requested to do so' do
57
+ argv = ['--dry-run', '-e', 'print Wright.dry_run?']
58
+ expected = 'true'
42
59
  -> { @cli.run(argv) }.must_output expected
60
+ Wright.instance_variable_set(:@dry_run, false)
43
61
  end
44
62
 
45
63
  it 'loads files' do