wright 0.1.2 → 0.2.0

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.
Files changed (142) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +34 -0
  3. data/NEWS.md +22 -0
  4. data/README.md +56 -40
  5. data/lib/wright/dsl.rb +1 -2
  6. data/lib/wright/provider/directory.rb +2 -9
  7. data/lib/wright/provider/file.rb +6 -13
  8. data/lib/wright/provider/group/darwin_directory_service.rb +61 -0
  9. data/lib/wright/provider/group/gnu_passwd.rb +42 -0
  10. data/lib/wright/provider/group.rb +111 -0
  11. data/lib/wright/provider/package/apt.rb +9 -43
  12. data/lib/wright/provider/package/homebrew.rb +68 -0
  13. data/lib/wright/provider/package.rb +26 -0
  14. data/lib/wright/provider/symlink.rb +4 -9
  15. data/lib/wright/provider/user/gnu_passwd.rb +55 -0
  16. data/lib/wright/provider/user.rb +137 -0
  17. data/lib/wright/provider.rb +40 -0
  18. data/lib/wright/resource/file.rb +1 -1
  19. data/lib/wright/resource/group.rb +64 -0
  20. data/lib/wright/resource/package.rb +6 -6
  21. data/lib/wright/resource/user.rb +76 -0
  22. data/lib/wright/util/recursive_autoloader.rb +1 -1
  23. data/lib/wright/util/stolen_from_activesupport.rb +2 -0
  24. data/lib/wright/util.rb +17 -2
  25. data/lib/wright/version.rb +1 -1
  26. data/lib/wright.rb +3 -2
  27. data/spec/provider/group/darwin_directory_service/dscl_._create_SLASHGroupsSLASHfoobar_GroupMembership.return +1 -0
  28. data/spec/provider/group/darwin_directory_service/dscl_._create_SLASHGroupsSLASHfoobar_GroupMembership.stdout +0 -0
  29. data/spec/provider/group/darwin_directory_service/dscl_._create_SLASHGroupsSLASHfoobar_GroupMembership_permission-denied-user.return +1 -0
  30. data/spec/provider/group/darwin_directory_service/dscl_._create_SLASHGroupsSLASHfoobar_GroupMembership_permission-denied-user.stderr +2 -0
  31. data/spec/provider/group/darwin_directory_service/dscl_._create_SLASHGroupsSLASHfoobar_GroupMembership_permission-denied-user.stdout +0 -0
  32. data/spec/provider/group/darwin_directory_service/dscl_._create_SLASHGroupsSLASHfoobar_GroupMembership_user1_user2.return +1 -0
  33. data/spec/provider/group/darwin_directory_service/dscl_._create_SLASHGroupsSLASHfoobar_GroupMembership_user1_user2.stderr +0 -0
  34. data/spec/provider/group/darwin_directory_service/dscl_._create_SLASHGroupsSLASHfoobar_GroupMembership_user1_user2.stdout +0 -0
  35. data/spec/provider/group/darwin_directory_service/dseditgroup_-o_create_-i_1234_newgroup.return +1 -0
  36. data/spec/provider/group/darwin_directory_service/dseditgroup_-o_create_-i_1234_newgroup.stderr +0 -0
  37. data/spec/provider/group/darwin_directory_service/dseditgroup_-o_create_-i_1234_newgroup.stdout +0 -0
  38. data/spec/provider/group/darwin_directory_service/dseditgroup_-o_create_-i_499_newgroup.return +1 -0
  39. data/spec/provider/group/darwin_directory_service/dseditgroup_-o_create_-i_499_newgroup.stderr +0 -0
  40. data/spec/provider/group/darwin_directory_service/dseditgroup_-o_create_-i_499_newgroup.stdout +0 -0
  41. data/spec/provider/group/darwin_directory_service/dseditgroup_-o_create_-i_ERROR_newgroup.return +1 -0
  42. data/spec/provider/group/darwin_directory_service/dseditgroup_-o_create_-i_ERROR_newgroup.stderr +0 -0
  43. data/spec/provider/group/darwin_directory_service/dseditgroup_-o_create_-i_ERROR_newgroup.stdout +1 -0
  44. data/spec/provider/group/darwin_directory_service/dseditgroup_-o_delete_bazqux.return +1 -0
  45. data/spec/provider/group/darwin_directory_service/dseditgroup_-o_delete_bazqux.stderr +1 -0
  46. data/spec/provider/group/darwin_directory_service/dseditgroup_-o_delete_bazqux.stdout +0 -0
  47. data/spec/provider/group/darwin_directory_service/dseditgroup_-o_delete_foobar.return +1 -0
  48. data/spec/provider/group/darwin_directory_service/dseditgroup_-o_delete_foobar.stderr +1 -0
  49. data/spec/provider/group/darwin_directory_service/dseditgroup_-o_delete_foobar.stdout +10 -0
  50. data/spec/provider/group/darwin_directory_service/dseditgroup_-o_edit_-i_52_foobar.return +1 -0
  51. data/spec/provider/group/darwin_directory_service/dseditgroup_-o_edit_-i_52_foobar.stderr +0 -0
  52. data/spec/provider/group/darwin_directory_service/dseditgroup_-o_edit_-i_52_foobar.stdout +0 -0
  53. data/spec/provider/group/darwin_directory_service/dseditgroup_-o_edit_-i_ERROR_foobar.return +1 -0
  54. data/spec/provider/group/darwin_directory_service/dseditgroup_-o_edit_-i_ERROR_foobar.stderr +0 -0
  55. data/spec/provider/group/darwin_directory_service/dseditgroup_-o_edit_-i_ERROR_foobar.stdout +1 -0
  56. data/spec/provider/group/darwin_directory_service_spec.rb +381 -0
  57. data/spec/provider/group/gnu_passwd/gpasswd_-M_''_foobar.return +1 -0
  58. data/spec/provider/group/gnu_passwd/gpasswd_-M_''_foobar.stderr +0 -0
  59. data/spec/provider/group/gnu_passwd/gpasswd_-M_''_foobar.stdout +0 -0
  60. data/spec/provider/group/gnu_passwd/gpasswd_-M_'not-a-user'_foobar.return +1 -0
  61. data/spec/provider/group/gnu_passwd/gpasswd_-M_'not-a-user'_foobar.stderr +1 -0
  62. data/spec/provider/group/gnu_passwd/gpasswd_-M_'not-a-user'_foobar.stdout +0 -0
  63. data/spec/provider/group/gnu_passwd/gpasswd_-M_'user1,user2'_foobar.return +1 -0
  64. data/spec/provider/group/gnu_passwd/gpasswd_-M_'user1,user2'_foobar.stderr +0 -0
  65. data/spec/provider/group/gnu_passwd/gpasswd_-M_'user1,user2'_foobar.stdout +0 -0
  66. data/spec/provider/group/gnu_passwd/groupadd_--system_newgroup.return +1 -0
  67. data/spec/provider/group/gnu_passwd/groupadd_--system_newgroup.stderr +0 -0
  68. data/spec/provider/group/gnu_passwd/groupadd_--system_newgroup.stdout +0 -0
  69. data/spec/provider/group/gnu_passwd/groupadd_-g_1234_newgroup.return +1 -0
  70. data/spec/provider/group/gnu_passwd/groupadd_-g_1234_newgroup.stderr +0 -0
  71. data/spec/provider/group/gnu_passwd/groupadd_-g_1234_newgroup.stdout +0 -0
  72. data/spec/provider/group/gnu_passwd/groupadd_-g_ERROR_newgroup.return +1 -0
  73. data/spec/provider/group/gnu_passwd/groupadd_-g_ERROR_newgroup.stderr +1 -0
  74. data/spec/provider/group/gnu_passwd/groupadd_-g_ERROR_newgroup.stdout +0 -0
  75. data/spec/provider/group/gnu_passwd/groupdel_bazqux.return +1 -0
  76. data/spec/provider/group/gnu_passwd/groupdel_bazqux.stderr +1 -0
  77. data/spec/provider/group/gnu_passwd/groupdel_bazqux.stdout +0 -0
  78. data/spec/provider/group/gnu_passwd/groupdel_foobar.return +1 -0
  79. data/spec/provider/group/gnu_passwd/groupdel_foobar.stderr +0 -0
  80. data/spec/provider/group/gnu_passwd/groupdel_foobar.stdout +0 -0
  81. data/spec/provider/group/gnu_passwd/groupmod_-g_52_foobar.return +1 -0
  82. data/spec/provider/group/gnu_passwd/groupmod_-g_52_foobar.stderr +0 -0
  83. data/spec/provider/group/gnu_passwd/groupmod_-g_52_foobar.stdout +0 -0
  84. data/spec/provider/group/gnu_passwd/groupmod_-g_ERROR_foobar.return +1 -0
  85. data/spec/provider/group/gnu_passwd/groupmod_-g_ERROR_foobar.stderr +1 -0
  86. data/spec/provider/group/gnu_passwd/groupmod_-g_ERROR_foobar.stdout +0 -0
  87. data/spec/provider/group/gnu_passwd_spec.rb +382 -0
  88. data/spec/provider/group_spec.rb +132 -0
  89. data/spec/provider/package/apt/apt-get_install_-qy_not-a-real-package.stderr +1 -0
  90. data/spec/provider/package/apt/{dpkg-query_-s_unknown-package.stderr → dpkg-query_-s_not-a-real-package.stderr} +1 -1
  91. data/spec/provider/package/apt/dpkg-query_-s_not-a-real-package.stdout +0 -0
  92. data/spec/provider/package/apt_spec.rb +27 -15
  93. data/spec/provider/package/homebrew/brew_info_--json=v1_cd-discid.return +1 -0
  94. data/spec/provider/package/homebrew/brew_info_--json=v1_cd-discid.stderr +0 -0
  95. data/spec/provider/package/homebrew/brew_info_--json=v1_cd-discid.stdout +1 -0
  96. data/spec/provider/package/homebrew/brew_info_--json=v1_lame.return +1 -0
  97. data/spec/provider/package/homebrew/brew_info_--json=v1_lame.stderr +0 -0
  98. data/spec/provider/package/homebrew/brew_info_--json=v1_lame.stdout +1 -0
  99. data/spec/provider/package/homebrew/brew_info_--json=v1_not-a-real-package.return +1 -0
  100. data/spec/provider/package/homebrew/brew_info_--json=v1_not-a-real-package.stderr +1 -0
  101. data/spec/provider/package/homebrew/brew_info_--json=v1_not-a-real-package.stdout +0 -0
  102. data/spec/provider/package/homebrew/brew_install_cd-discid.return +1 -0
  103. data/spec/provider/package/homebrew/brew_install_cd-discid.stderr +0 -0
  104. data/spec/provider/package/homebrew/brew_install_cd-discid.stdout +9 -0
  105. data/spec/provider/package/homebrew/brew_install_not-a-real-package.return +1 -0
  106. data/spec/provider/package/homebrew/brew_install_not-a-real-package.stderr +1 -0
  107. data/spec/provider/package/homebrew/brew_install_not-a-real-package.stdout +2 -0
  108. data/spec/provider/package/homebrew/brew_uninstall_lame.return +1 -0
  109. data/spec/provider/package/homebrew/brew_uninstall_lame.stderr +0 -0
  110. data/spec/provider/package/homebrew/brew_uninstall_lame.stdout +1 -0
  111. data/spec/provider/package/homebrew_spec.rb +268 -0
  112. data/spec/provider/user/gnu_passwd/useradd_johndoe.return +1 -0
  113. data/spec/provider/user/gnu_passwd/useradd_johndoe.stderr +0 -0
  114. data/spec/provider/user/gnu_passwd/useradd_johndoe.stdout +0 -0
  115. data/spec/provider/user/gnu_passwd/useradd_with_options.return +1 -0
  116. data/spec/provider/user/gnu_passwd/useradd_with_options.stderr +0 -0
  117. data/spec/provider/user/gnu_passwd/useradd_with_options.stdout +0 -0
  118. data/spec/provider/user/gnu_passwd/userdel_johndoe.return +1 -0
  119. data/spec/provider/user/gnu_passwd/userdel_johndoe.stderr +0 -0
  120. data/spec/provider/user/gnu_passwd/userdel_johndoe.stdout +0 -0
  121. data/spec/provider/user/gnu_passwd/usermod_-u_42_johndoe.return +1 -0
  122. data/spec/provider/user/gnu_passwd/usermod_-u_42_johndoe.stderr +0 -0
  123. data/spec/provider/user/gnu_passwd/usermod_-u_42_johndoe.stdout +0 -0
  124. data/spec/provider/user/gnu_passwd_spec.rb +107 -0
  125. data/spec/provider/user_spec.rb +327 -0
  126. data/spec/resource/group_spec.rb +29 -0
  127. data/spec/resource/package_spec.rb +37 -0
  128. data/spec/resource/user_spec.rb +29 -0
  129. data/spec/spec_helper.rb +5 -11
  130. data/spec/spec_helpers/fake_capture3.rb +11 -7
  131. data/spec/spec_helpers/test_coverage.rb +26 -0
  132. data/spec/util/activesupport_spec.rb +1 -0
  133. data/spec/util/file_permissions_spec.rb +2 -2
  134. data/spec/util/file_spec.rb +1 -0
  135. data/spec/util/user_spec.rb +2 -0
  136. metadata +246 -23
  137. data/NEWS +0 -18
  138. data/spec/provider/package/apt/apt-get_install_-qy_unknown-package.stderr +0 -1
  139. /data/spec/provider/{package/apt/dpkg-query_-s_unknown-package.stdout → group/darwin_directory_service/dscl_._create_SLASHGroupsSLASHfoobar_GroupMembership.stderr} +0 -0
  140. /data/spec/provider/package/apt/{apt-get_install_-qy_unknown-package.return → apt-get_install_-qy_not-a-real-package.return} +0 -0
  141. /data/spec/provider/package/apt/{apt-get_install_-qy_unknown-package.stdout → apt-get_install_-qy_not-a-real-package.stdout} +0 -0
  142. /data/spec/provider/package/apt/{dpkg-query_-s_unknown-package.return → dpkg-query_-s_not-a-real-package.return} +0 -0
@@ -1,5 +1,6 @@
1
- require 'wright/provider'
2
1
  require 'fileutils'
2
+ require 'wright/provider'
3
+ require 'wright/util/file'
3
4
 
4
5
  module Wright
5
6
  class Provider
@@ -49,10 +50,7 @@ module Wright
49
50
 
50
51
  def create_link
51
52
  symlink = symlink_to_s(@resource.name, @resource.to)
52
- if Wright.dry_run?
53
- Wright.log.info "(would) create symlink: #{symlink}"
54
- else
55
- Wright.log.info "create symlink: #{symlink}"
53
+ unless_dry_run("create symlink: #{symlink}") do
56
54
  Wright::Util::File.ln_sfn(link_to, link_name)
57
55
  end
58
56
  end
@@ -62,10 +60,7 @@ module Wright
62
60
  end
63
61
 
64
62
  def remove_symlink
65
- if Wright.dry_run?
66
- Wright.log.info "(would) remove symlink: '#{@resource.name}'"
67
- else
68
- Wright.log.info "remove symlink: '#{@resource.name}'"
63
+ unless_dry_run("remove symlink: '#{@resource.name}'") do
69
64
  FileUtils.rm(link_name)
70
65
  end
71
66
  end
@@ -0,0 +1,55 @@
1
+ require 'wright/dry_run'
2
+ require 'wright/provider'
3
+ require 'wright/provider/user'
4
+
5
+ module Wright
6
+ class Provider
7
+ class User
8
+ # GNU passwd user provider. Used as a provider for
9
+ # {Resource::User} on GNU systems.
10
+ class GnuPasswd < Wright::Provider::User
11
+ private
12
+
13
+ def add_user
14
+ user = @resource.name
15
+ cmd = 'useradd'
16
+ args = [*user_options, user]
17
+ exec_or_fail(cmd, args, "cannot create user '#{user}'")
18
+ end
19
+
20
+ def update_user
21
+ user = @resource.name
22
+ cmd = 'usermod'
23
+ args = [*user_options, user]
24
+ exec_or_fail(cmd, args, "cannot create user '#{user}'")
25
+ end
26
+
27
+ def user_options
28
+ options = {
29
+ '-u' => @resource.uid,
30
+ '-g' => @resource.primary_group,
31
+ '-c' => comment,
32
+ '-G' => groups,
33
+ '-s' => @resource.shell,
34
+ '-d' => @resource.home
35
+ }.reject { |_k, v| v.nil? }.flatten
36
+ options << '-r' if @resource.system
37
+ options.map(&:to_s)
38
+ end
39
+
40
+ def comment
41
+ @resource.full_name.nil? ? nil : "#{@resource.full_name},,,"
42
+ end
43
+
44
+ def groups
45
+ @resource.groups.nil? ? nil : @resource.groups.join(',')
46
+ end
47
+
48
+ def delete_user
49
+ user = @resource.name
50
+ exec_or_fail('userdel', [user], "cannot remove user '#{user}'")
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,137 @@
1
+ require 'etc'
2
+ require 'wright/provider'
3
+ require 'wright/util/user'
4
+
5
+ module Wright
6
+ class Provider
7
+ # User provider. Used as a base class for {Resource::User}
8
+ # providers.
9
+ class User < Wright::Provider
10
+ # Adds the user.
11
+ #
12
+ # @return [void]
13
+ def create
14
+ if uptodate?(:create)
15
+ Wright.log.debug "user already created: '#{@resource.name}'"
16
+ return
17
+ end
18
+
19
+ create_user
20
+ @updated = true
21
+ end
22
+
23
+ # Removes the user.
24
+ #
25
+ # @return [void]
26
+ def remove
27
+ if uptodate?(:remove)
28
+ Wright.log.debug "user already removed: '#{@resource.name}'"
29
+ return
30
+ end
31
+
32
+ remove_user
33
+ @updated = true
34
+ end
35
+
36
+ private
37
+
38
+ # @api public
39
+ # Checks if the user is up-to-date for a given action.
40
+ #
41
+ # @param action [Symbol] the action. Currently supports
42
+ # +:create+ and +:remove+.
43
+ #
44
+ # @return [Bool] +true+ if the user is up-to-date and +false+
45
+ # otherwise
46
+ # @raise [ArgumentError] if the action is invalid
47
+ def uptodate?(action)
48
+ case action
49
+ when :create
50
+ user_exists? && attributes_uptodate?
51
+ when :remove
52
+ !user_exists?
53
+ else
54
+ fail ArgumentError, "invalid action '#{action}'"
55
+ end
56
+ end
57
+
58
+ def attributes_uptodate?
59
+ uid_uptodate? &&
60
+ full_name_uptodate? &&
61
+ groups_uptodate? &&
62
+ shell_uptodate? &&
63
+ home_uptodate? &&
64
+ primary_group_uptodate?
65
+ end
66
+
67
+ def create_user
68
+ unless_dry_run("create user: '#{@resource.name}'") do
69
+ if user_exists?
70
+ update_user
71
+ else
72
+ add_user
73
+ end
74
+ end
75
+ end
76
+
77
+ def remove_user
78
+ unless_dry_run("remove user: '#{@resource.name}'") do
79
+ delete_user
80
+ end
81
+ end
82
+
83
+ def user_data
84
+ Etc.getpwnam(@resource.name)
85
+ rescue ArgumentError
86
+ nil
87
+ end
88
+
89
+ def uid_uptodate?
90
+ @resource.uid.nil? || user_data.uid == @resource.uid
91
+ end
92
+
93
+ def full_name_uptodate?
94
+ @resource.full_name.nil? ||
95
+ user_data.gecos.split(',').first == @resource.full_name
96
+ end
97
+
98
+ def groups_uptodate?
99
+ return true if @resource.groups.nil?
100
+ groups = []
101
+ Etc.group { |g| groups << g.name if g.mem.include?(@resource.name) }
102
+ groups.uniq.sort == @resource.groups.uniq.sort
103
+ end
104
+
105
+ def shell_uptodate?
106
+ @resource.shell.nil? || user_data.shell == @resource.shell
107
+ end
108
+
109
+ def home_uptodate?
110
+ @resource.home.nil? || user_data.dir == @resource.home
111
+ end
112
+
113
+ def primary_group_uptodate?
114
+ return true if @resource.primary_group.nil?
115
+
116
+ gid = Wright::Util::User.group_to_gid(@resource.primary_group)
117
+ user_data.gid == gid
118
+ end
119
+
120
+ def user_exists?
121
+ !user_data.nil?
122
+ end
123
+
124
+ def add_user
125
+ fail NotImplementedError
126
+ end
127
+
128
+ def update_user
129
+ fail NotImplementedError
130
+ end
131
+
132
+ def delete_user
133
+ fail NotImplementedError
134
+ end
135
+ end
136
+ end
137
+ end
@@ -1,4 +1,5 @@
1
1
  require 'wright/config'
2
+ require 'wright/dry_run'
2
3
  require 'wright/util/recursive_autoloader'
3
4
 
4
5
  module Wright
@@ -27,5 +28,44 @@ module Wright
27
28
  @updated = false
28
29
  updated
29
30
  end
31
+
32
+ private
33
+
34
+ # @api public
35
+ # Logs an info message and runs a code block unless dry run mode
36
+ # is active.
37
+ #
38
+ # @param message [String] the message that is passed to the logger
39
+ def unless_dry_run(message)
40
+ if Wright.dry_run?
41
+ Wright.log.info "(would) #{message}"
42
+ else
43
+ Wright.log.info message
44
+ yield
45
+ end
46
+ end
47
+
48
+ # @api public
49
+ # Runs a command or fails with an error message.
50
+ #
51
+ # @param command [String] the command to run
52
+ # @param args [Array<String>] the arguments that are passed to the
53
+ # command
54
+ # @param error_message [String] the error message to display in
55
+ # case of an error
56
+ # @raise [RuntimeError] if the command did not exit successfully
57
+ # @return [void]
58
+ def exec_or_fail(command, args, error_message)
59
+ stdout, stderr, status = Open3.capture3(env, command, *args)
60
+ return if status.success?
61
+
62
+ error = stderr.chomp
63
+ error = stdout.chomp if error.empty?
64
+ fail %(#{error_message}: "#{error}")
65
+ end
66
+
67
+ def env
68
+ {}
69
+ end
30
70
  end
31
71
  end
@@ -13,7 +13,7 @@ module Wright
13
13
  # @return [String] the file's intended content
14
14
  attr_accessor :content
15
15
 
16
- # @return [String] the file's intended group.
16
+ # @return [String] the file's intended group
17
17
  attr_accessor :group
18
18
 
19
19
  # @return [String, Integer] the file's intended mode
@@ -0,0 +1,64 @@
1
+ require 'wright/resource'
2
+ require 'wright/dsl'
3
+
4
+ module Wright
5
+ class Resource
6
+ # Group resource, represents a group.
7
+ #
8
+ # @example
9
+ # admins = Wright::Resource::Group.new('admins')
10
+ # admins.members = ['root']
11
+ # admins.create
12
+ # @todo Use GnuPasswd provider on all GNU-flavoured systems
13
+ class Group < Wright::Resource
14
+ # @return [Array<String>] the group's intended members
15
+ attr_accessor :members
16
+
17
+ # @return [Integer] the group's intended group id
18
+ attr_accessor :gid
19
+
20
+ # @return [Bool] true if the group should be a system
21
+ # group. Ignored if {#gid} is set.
22
+ attr_accessor :system
23
+
24
+ # Initializes a Group.
25
+ #
26
+ # @param name [String] the group's name
27
+ def initialize(name)
28
+ super
29
+ @action = :create
30
+ @system = false
31
+ end
32
+
33
+ # Creates or updates the group.
34
+ #
35
+ # @return [Bool] true if the group was updated and false
36
+ # otherwise
37
+ def create
38
+ might_update_resource do
39
+ @provider.create
40
+ end
41
+ end
42
+
43
+ # Removes the group.
44
+ #
45
+ # @return [Bool] true if the group was updated and false
46
+ # otherwise
47
+ def remove
48
+ might_update_resource do
49
+ @provider.remove
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ Wright::DSL.register_resource(Wright::Resource::Group)
57
+
58
+ group_providers = {
59
+ 'debian' => 'Wright::Provider::Group::GnuPasswd',
60
+ 'macosx' => 'Wright::Provider::Group::DarwinDirectoryService'
61
+ }
62
+ Wright::Config[:resources][:group] ||= {}
63
+ Wright::Config[:resources][:group][:provider] ||=
64
+ group_providers[Wright::Util.os_family]
@@ -64,10 +64,10 @@ end
64
64
 
65
65
  Wright::DSL.register_resource(Wright::Resource::Package)
66
66
 
67
+ package_providers = {
68
+ 'debian' => 'Wright::Provider::Package::Apt',
69
+ 'macosx' => 'Wright::Provider::Package::Homebrew'
70
+ }
67
71
  Wright::Config[:resources][:package] ||= {}
68
-
69
- case Wright::Util.os_family
70
- when 'debian'
71
- Wright::Config[:resources][:package][:provider] ||=
72
- 'Wright::Provider::Package::Apt'
73
- end
72
+ Wright::Config[:resources][:package][:provider] ||=
73
+ package_providers[Wright::Util.os_family]
@@ -0,0 +1,76 @@
1
+ require 'wright/resource'
2
+ require 'wright/dsl'
3
+
4
+ module Wright
5
+ class Resource
6
+ # User resource, represents a user.
7
+ #
8
+ # @example
9
+ # johndoe = Wright::Resource::User.new('johndoe')
10
+ # johndoe.home = '/home/johndoe'
11
+ # johndoe.create
12
+ class User < Wright::Resource
13
+ # @return [Integer] the user's intended user id
14
+ attr_accessor :uid
15
+
16
+ # @return [String] the user's intended full name
17
+ attr_accessor :full_name
18
+
19
+ # @return [Array<String>] the user's intended groups
20
+ attr_accessor :groups
21
+
22
+ # @return [String] the user's intended shell
23
+ attr_accessor :shell
24
+
25
+ # @return [String] the user's intended home directory path
26
+ attr_accessor :home
27
+ alias_method :homedir, :home
28
+
29
+ # @return [String, Integer] the user's intended primary group
30
+ attr_accessor :primary_group
31
+ alias_method :login_group, :primary_group
32
+
33
+ # @return [Bool] true if the user should be a system
34
+ # user. Ignored if {#uid} is set.
35
+ attr_accessor :system
36
+
37
+ # Initializes a user.
38
+ #
39
+ # @param name [String] the user's name
40
+ def initialize(name)
41
+ super
42
+ @action = :create
43
+ @system = false
44
+ end
45
+
46
+ # Creates or updates the user.
47
+ #
48
+ # @return [Bool] true if the user was updated and false
49
+ # otherwise
50
+ def create
51
+ might_update_resource do
52
+ @provider.create
53
+ end
54
+ end
55
+
56
+ # Removes the user.
57
+ #
58
+ # @return [Bool] true if the user was updated and false
59
+ # otherwise
60
+ def remove
61
+ might_update_resource do
62
+ @provider.remove
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+
69
+ Wright::DSL.register_resource(Wright::Resource::User)
70
+
71
+ user_providers = {
72
+ 'debian' => 'Wright::Provider::User::GnuPasswd'
73
+ }
74
+ Wright::Config[:resources][:user] ||= {}
75
+ Wright::Config[:resources][:user][:provider] ||=
76
+ user_providers[Wright::Util.os_family]
@@ -78,7 +78,7 @@ module Wright
78
78
  subclass = Wright::Util.filename_to_classname(dir)
79
79
  ensure_subclass_exists(parent_class, subclass)
80
80
  new_parent = Wright::Util.filename_to_classname(
81
- ::File.join(parent_class, dir))
81
+ ::File.join(parent_class, dir))
82
82
  add_autoloads_unsafe(dir, new_parent)
83
83
  end
84
84
  end
@@ -168,6 +168,8 @@ module Wright
168
168
  # @return [Class, NilClass] the constant or nil if the name is
169
169
  # not in CamelCase or the constant is unknown
170
170
  def self.safe_constantize(camel_cased_word)
171
+ return nil if camel_cased_word.nil?
172
+
171
173
  constantize(camel_cased_word)
172
174
  rescue NameError => e
173
175
  error_re = /(uninitialized constant|wrong constant name)/
data/lib/wright/util.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'wright/util/stolen_from_activesupport'
2
+ require 'open3'
2
3
 
3
4
  module Wright
4
5
  # @api private
@@ -37,10 +38,14 @@ module Wright
37
38
  end
38
39
 
39
40
  def self.distro
40
- os_release = ::File.read('/etc/os-release')
41
+ default = 'linux'
42
+ release_file = '/etc/os-release'
43
+ return default unless ::File.exist?(release_file)
44
+
45
+ os_release = ::File.read(release_file)
41
46
  /^ID_LIKE=(?<id_like>.*)$/ =~ os_release
42
47
  /^ID=(?<id>.*)$/ =~ os_release
43
- id_like || id || 'linux'
48
+ id_like || id || default
44
49
  end
45
50
  private_class_method :distro
46
51
 
@@ -66,5 +71,15 @@ module Wright
66
71
  'other'
67
72
  end
68
73
  end
74
+
75
+ # :nocov:
76
+ def self.bundler_clean_env
77
+ if defined?(Bundler)
78
+ Bundler.with_clean_env { yield }
79
+ else
80
+ yield
81
+ end
82
+ end
83
+ # :nocov:
69
84
  end
70
85
  end
@@ -1,4 +1,4 @@
1
1
  module Wright # rubocop:disable Documentation
2
2
  # Current wright version
3
- VERSION = '0.1.2'
3
+ VERSION = '0.2.0'
4
4
  end
data/lib/wright.rb CHANGED
@@ -7,8 +7,9 @@ require 'wright/resource/directory'
7
7
  require 'wright/resource/file'
8
8
  require 'wright/resource/package'
9
9
  require 'wright/resource/symlink'
10
+ require 'wright/resource/group'
11
+ require 'wright/resource/user'
10
12
 
11
- # @todo add proper documentation
12
- # Lightweight configuration management.
13
+ # Top-level namespace for wright.
13
14
  module Wright
14
15
  end
@@ -0,0 +1,2 @@
1
+ <main> attribute status: eDSPermissionError
2
+ <dscl_cmd> DS Error: -14120 (eDSPermissionError)
@@ -0,0 +1 @@
1
+ GID contains non-numeric characters
@@ -0,0 +1 @@
1
+ Group record below will be deleted:
@@ -0,0 +1,10 @@
1
+ dsAttrTypeStandard:GeneratedUID -
2
+ 56CE5EAF-4311-4C01-A45E-7FBB28C607CC
3
+ dsAttrTypeStandard:PrimaryGroupID -
4
+ 42
5
+ dsAttrTypeStandard:RecordName -
6
+ foobar
7
+ dsAttrTypeStandard:RecordType -
8
+ dsRecTypeStandard:Groups
9
+ dsAttrTypeStandard:AppleMetaNodeLocation -
10
+ /Local/Default
@@ -0,0 +1 @@
1
+ GID contains non-numeric characters