wright 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. data/NEWS.md +8 -0
  3. data/README.md +2 -0
  4. data/Rakefile +6 -0
  5. data/bin/wright +6 -0
  6. data/lib/wright/cli.rb +68 -0
  7. data/lib/wright/dsl.rb +1 -1
  8. data/lib/wright/provider/directory.rb +17 -12
  9. data/lib/wright/provider/file.rb +24 -17
  10. data/lib/wright/provider/group/darwin_directory_service.rb +1 -8
  11. data/lib/wright/provider/group/gnu_passwd.rb +0 -1
  12. data/lib/wright/provider/group.rb +6 -12
  13. data/lib/wright/provider/package/apt.rb +9 -21
  14. data/lib/wright/provider/package/homebrew.rb +5 -18
  15. data/lib/wright/provider/package.rb +22 -11
  16. data/lib/wright/provider/symlink.rb +17 -22
  17. data/lib/wright/provider/user/darwin_directory_service.rb +65 -0
  18. data/lib/wright/provider/user/gnu_passwd.rb +6 -7
  19. data/lib/wright/provider/user.rb +6 -12
  20. data/lib/wright/provider.rb +20 -2
  21. data/lib/wright/resource/directory.rb +19 -20
  22. data/lib/wright/resource/file.rb +19 -15
  23. data/lib/wright/resource/symlink.rb +1 -0
  24. data/lib/wright/resource/user.rb +2 -1
  25. data/lib/wright/resource.rb +1 -1
  26. data/lib/wright/util/file_owner.rb +61 -0
  27. data/lib/wright/util/file_permissions.rb +21 -30
  28. data/lib/wright/util/stolen_from_activesupport.rb +1 -1
  29. data/lib/wright/util/user.rb +48 -23
  30. data/lib/wright/util.rb +10 -6
  31. data/lib/wright/version.rb +1 -1
  32. data/lib/wright.rb +1 -0
  33. data/man/wright.1 +202 -0
  34. data/spec/cli/shebang.rb +3 -0
  35. data/spec/cli_spec.rb +64 -0
  36. data/spec/dsl_spec.rb +8 -3
  37. data/spec/provider/group/darwin_directory_service_spec.rb +3 -2
  38. data/spec/provider/package/apt/apt-cache_policy_abcde.stdout +7 -0
  39. data/spec/provider/package/apt/apt-cache_policy_htop.stdout +6 -0
  40. data/spec/provider/package/apt/apt-cache_policy_not-a-real-package.return +1 -0
  41. data/spec/provider/package/apt_spec.rb +17 -211
  42. data/spec/provider/package/homebrew_spec.rb +11 -164
  43. data/spec/provider/package_spec.rb +151 -7
  44. data/spec/provider/user/darwin_directory_service/dscl-delete-user.return +1 -0
  45. data/spec/provider/user/darwin_directory_service/dscl-delete-user.stderr +0 -0
  46. data/spec/provider/user/darwin_directory_service/dscl-delete-user.stdout +0 -0
  47. data/spec/provider/user/darwin_directory_service/dscl-new-user-full-name.return +1 -0
  48. data/spec/provider/user/darwin_directory_service/dscl-new-user-full-name.stderr +0 -0
  49. data/spec/provider/user/darwin_directory_service/dscl-new-user-full-name.stdout +0 -0
  50. data/spec/provider/user/darwin_directory_service/dscl-new-user-home.return +1 -0
  51. data/spec/provider/user/darwin_directory_service/dscl-new-user-home.stderr +0 -0
  52. data/spec/provider/user/darwin_directory_service/dscl-new-user-home.stdout +0 -0
  53. data/spec/provider/user/darwin_directory_service/dscl-new-user-password.return +1 -0
  54. data/spec/provider/user/darwin_directory_service/dscl-new-user-password.stderr +0 -0
  55. data/spec/provider/user/darwin_directory_service/dscl-new-user-password.stdout +0 -0
  56. data/spec/provider/user/darwin_directory_service/dscl-new-user-primary-group.return +1 -0
  57. data/spec/provider/user/darwin_directory_service/dscl-new-user-primary-group.stderr +0 -0
  58. data/spec/provider/user/darwin_directory_service/dscl-new-user-primary-group.stdout +0 -0
  59. data/spec/provider/user/darwin_directory_service/dscl-new-user-shell.return +1 -0
  60. data/spec/provider/user/darwin_directory_service/dscl-new-user-shell.stderr +0 -0
  61. data/spec/provider/user/darwin_directory_service/dscl-new-user-shell.stdout +0 -0
  62. data/spec/provider/user/darwin_directory_service/dscl-new-user-uid.return +1 -0
  63. data/spec/provider/user/darwin_directory_service/dscl-new-user-uid.stderr +0 -0
  64. data/spec/provider/user/darwin_directory_service/dscl-new-user-uid.stdout +0 -0
  65. data/spec/provider/user/darwin_directory_service_spec.rb +167 -0
  66. data/spec/provider/user/gnu_passwd_spec.rb +5 -5
  67. data/spec/resource/directory_spec.rb +17 -15
  68. data/spec/resource/file_spec.rb +17 -15
  69. data/spec/resource_spec.rb +1 -1
  70. data/spec/spec_helpers/test_coverage.rb +1 -1
  71. data/spec/util/file_owner_spec.rb +36 -0
  72. data/spec/util/file_permissions_spec.rb +6 -6
  73. data/spec/util/user_spec.rb +0 -17
  74. data/spec/util_spec.rb +64 -5
  75. metadata +91 -41
  76. data/spec/provider/package/apt/dpkg-query_-s_abcde.stdout +0 -23
  77. data/spec/provider/package/apt/dpkg-query_-s_htop.stdout +0 -19
  78. data/spec/provider/package/apt/dpkg-query_-s_not-a-real-package.return +0 -1
  79. data/spec/provider/package/apt/dpkg-query_-s_not-a-real-package.stderr +0 -3
  80. data/spec/provider/package/apt/dpkg-query_-s_vlc.return +0 -1
  81. data/spec/provider/package/apt/dpkg-query_-s_vlc.stderr +0 -3
  82. /data/spec/provider/group/darwin_directory_service/{dseditgroup_-o_create_-i_499_newgroup.return → dseditgroup_-o_create_-i_2_newgroup.return} +0 -0
  83. /data/spec/provider/group/darwin_directory_service/{dseditgroup_-o_create_-i_499_newgroup.stderr → dseditgroup_-o_create_-i_2_newgroup.stderr} +0 -0
  84. /data/spec/provider/group/darwin_directory_service/{dseditgroup_-o_create_-i_499_newgroup.stdout → dseditgroup_-o_create_-i_2_newgroup.stdout} +0 -0
  85. /data/spec/provider/package/apt/{dpkg-query_-s_abcde.return → apt-cache_policy_abcde.return} +0 -0
  86. /data/spec/provider/package/apt/{dpkg-query_-s_abcde.stderr → apt-cache_policy_abcde.stderr} +0 -0
  87. /data/spec/provider/package/apt/{dpkg-query_-s_htop.return → apt-cache_policy_htop.return} +0 -0
  88. /data/spec/provider/package/apt/{dpkg-query_-s_htop.stderr → apt-cache_policy_htop.stderr} +0 -0
  89. /data/spec/provider/package/apt/{dpkg-query_-s_not-a-real-package.stdout → apt-cache_policy_not-a-real-package.stderr} +0 -0
  90. /data/spec/provider/package/apt/{dpkg-query_-s_vlc.stdout → apt-cache_policy_not-a-real-package.stdout} +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6d159205080df87b4a9c8935b0486335c74ef84e
4
- data.tar.gz: 35cdf663151ab32900d9be2566574cfc0648f980
3
+ metadata.gz: e035155341d50577a99a8dedbc1a74c071ac65a7
4
+ data.tar.gz: fcef2683e975dcee23bf413fbc5ee66b5f4d264e
5
5
  SHA512:
6
- metadata.gz: 0dd9b03ffecb5ca5bd6bbe272f672fcd8546fdeebc7df4ac307f94148ca10312734ab99afd78720ba1d56e458e6c277424b6479decadbd0181b528fa05451316
7
- data.tar.gz: 61b6d41688576e1736bf63d9e75eb4fd25c3a5de1d480f7a546df90f8802b4e91387556b38cbcb1393a2a7094b5f72117a65ddf336a8022bb416008880009475
6
+ metadata.gz: 2cf56d882eb3350b70fe16dad983dfc9b25d89ca2c403a50874e8b39d71be4fd39e9e63f28134f3afeda334442c4f4148f7f6a10ff3515932c2bd26d0cc96acc
7
+ data.tar.gz: 54ebbd48c70c41b5699e527e4e3e1d599bb0247befe191ff1b19a7b6cf9799cad6fb659198919e5f5456c31708cc79e120038db823c78c8bc2b522c0342cef81
data/NEWS.md CHANGED
@@ -1,4 +1,12 @@
1
1
  # wright NEWS
2
+ ## 0.3.0 (2015-04-23)
3
+ - Add bin/wright
4
+ - Add wright(1) manpage
5
+ - Add OS X user provider
6
+ - Improve performance of the apt provider
7
+ - Improve error message for resources without names (#5)
8
+ - Improve error message for symlinks without target (#6)
9
+
2
10
  ## 0.2.0 (2015-03-13)
3
11
  - Add Homebrew package provider for OS X
4
12
  - Add group resource
data/README.md CHANGED
@@ -5,10 +5,12 @@ wright
5
5
  [![Build Status](https://img.shields.io/travis/sometimesfood/wright.svg?style=flat-square)][travis]
6
6
  [![Code Climate](https://img.shields.io/codeclimate/github/sometimesfood/wright.svg?style=flat-square)][codeclimate]
7
7
  [![Test Coverage](https://img.shields.io/codeclimate/coverage/github/sometimesfood/wright.svg?style=flat-square)][codeclimate]
8
+ [![Gem Dependencies](https://img.shields.io/gemnasium/sometimesfood/wright.svg?style=flat-square)][gemnasium]
8
9
 
9
10
  [gem]: https://rubygems.org/gems/wright
10
11
  [travis]: https://travis-ci.org/sometimesfood/wright
11
12
  [codeclimate]: https://codeclimate.com/github/sometimesfood/wright
13
+ [gemnasium]: https://gemnasium.com/sometimesfood/wright
12
14
 
13
15
  Lightweight configuration management.
14
16
 
data/Rakefile CHANGED
@@ -5,3 +5,9 @@ require 'rake/testtask'
5
5
  Rake::TestTask.new do |t|
6
6
  t.pattern = 'spec/**/*_spec.rb'
7
7
  end
8
+
9
+ file 'man/wright.1' => 'man/wright.1.txt' do
10
+ sh 'a2x --format manpage man/wright.1.txt'
11
+ end
12
+
13
+ task build: 'man/wright.1'
data/bin/wright ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ require 'wright/cli'
3
+
4
+ main = self
5
+ wright = Wright::CLI.new(main)
6
+ wright.run(ARGV)
data/lib/wright/cli.rb ADDED
@@ -0,0 +1,68 @@
1
+ require 'optparse'
2
+ require 'wright'
3
+
4
+ module Wright
5
+ # Wright command-line interface.
6
+ class CLI
7
+ def initialize(main)
8
+ @commands = []
9
+ @main = main
10
+ @parser = option_parser
11
+ end
12
+
13
+ # Runs a wright script with the supplied arguments.
14
+ #
15
+ # @param argv [Array<String>] the arguments passed to bin/wright
16
+ def run(argv)
17
+ arguments = parse(argv)
18
+ return if @quit
19
+
20
+ Wright.log.level = @log_level if @log_level
21
+ @main.extend Wright::DSL
22
+
23
+ run_script(arguments)
24
+ end
25
+
26
+ private
27
+
28
+ attr_reader :commands
29
+ attr_reader :log_level
30
+
31
+ def parse(argv)
32
+ # use OptionParser#order! instead of #parse! so CLI#run does not
33
+ # consume --arguments passed to wright scripts
34
+ @parser.order!(argv)
35
+ end
36
+
37
+ def run_script(arguments)
38
+ if @commands.empty? && arguments.any?
39
+ script = arguments.shift
40
+ load script
41
+ else
42
+ commands = @commands.empty? ? $stdin.read : @commands.join("\n")
43
+ @main.instance_eval(commands, '<main>', 1)
44
+ end
45
+ end
46
+
47
+ def option_parser
48
+ OptionParser.new do |opts|
49
+ opts.on('-e COMMAND', 'Run COMMAND') do |e|
50
+ @commands << e
51
+ end
52
+
53
+ opts.on('-v', '--verbose', 'Increase verbosity') do
54
+ @log_level = Wright::Logger::DEBUG
55
+ end
56
+
57
+ opts.on('-q', '--quiet', 'Decrease verbosity') do
58
+ @log_level = Wright::Logger::ERROR
59
+ end
60
+
61
+ opts.on_tail('--version', 'Show wright version') do
62
+ puts "wright version #{Wright::VERSION}"
63
+ @quit = true
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
data/lib/wright/dsl.rb CHANGED
@@ -41,7 +41,7 @@ module Wright
41
41
  def self.register_resource(resource_class)
42
42
  method_name = Util.class_to_resource_name(resource_class)
43
43
  this_module = self
44
- define_method(method_name) do |name = nil, &block|
44
+ define_method(method_name) do |name, &block|
45
45
  this_module.yield_resource(resource_class, name, &block)
46
46
  end
47
47
  end
@@ -12,14 +12,12 @@ module Wright
12
12
  #
13
13
  # @return [void]
14
14
  def create
15
- if ::File.directory?(dirname) && permissions.uptodate?
16
- Wright.log.debug "directory already created: '#{@resource.name}'"
17
- return
18
- end
19
-
20
15
  fail Errno::EEXIST, dirname if regular_file?
21
- create_directory
22
- @updated = true
16
+
17
+ dir = @resource.name
18
+ unless_uptodate(:create, "directory already created: '#{dir}'") do
19
+ create_directory
20
+ end
23
21
  end
24
22
 
25
23
  # Removes the directory.
@@ -30,16 +28,23 @@ module Wright
30
28
  fail "'#{dirname}' exists but is not a directory"
31
29
  end
32
30
 
33
- if ::File.directory?(dirname)
31
+ dir = @resource.name
32
+ unless_uptodate(:remove, "directory already removed: '#{dir}'") do
34
33
  remove_directory
35
- @updated = true
36
- else
37
- Wright.log.debug "directory already removed: '#{@resource.name}'"
38
34
  end
39
35
  end
40
36
 
41
37
  private
42
38
 
39
+ def uptodate?(action)
40
+ case action
41
+ when :create
42
+ ::File.directory?(dirname) && permissions.uptodate?
43
+ when :remove
44
+ !::File.exist?(dirname) && !::File.directory?(dirname)
45
+ end
46
+ end
47
+
43
48
  def permissions
44
49
  Wright::Util::FilePermissions.create_from_resource(@resource,
45
50
  :directory)
@@ -49,7 +54,7 @@ module Wright
49
54
  dir_permissions = permissions
50
55
  unless_dry_run("create directory: '#{@resource.name}'") do
51
56
  FileUtils.mkdir_p(dirname)
52
- dir_permissions.update
57
+ dir_permissions.update unless dir_permissions.uptodate?
53
58
  end
54
59
  end
55
60
 
@@ -2,6 +2,7 @@ require 'fileutils'
2
2
  require 'digest'
3
3
  require 'tempfile'
4
4
  require 'tmpdir'
5
+
5
6
  require 'wright/provider'
6
7
  require 'wright/util/file_permissions'
7
8
  require 'wright/util/user'
@@ -13,29 +14,26 @@ module Wright
13
14
  # Creates or updates the file.
14
15
  #
15
16
  # @return [void]
17
+ # @raise [Errno::EISDIR] if there is already a directory with
18
+ # the specified name
16
19
  def create
17
- fail Errno::EISDIR, filename if ::File.directory?(filename)
18
-
19
- if uptodate?
20
- Wright.log.debug "file already created: '#{@resource.name}'"
21
- return
20
+ fail_if_directory
21
+ file = @resource.name
22
+ unless_uptodate(:create, "file already created: '#{file}'") do
23
+ create_file
22
24
  end
23
-
24
- create_file
25
- @updated = true
26
25
  end
27
26
 
28
27
  # Removes the file.
29
28
  #
30
29
  # @return [void]
30
+ # @raise [Errno::EISDIR] if there is a directory with the
31
+ # specified name
31
32
  def remove
32
- fail Errno::EISDIR, filename if ::File.directory?(filename)
33
-
34
- if ::File.exist?(filename) || ::File.symlink?(filename)
33
+ fail_if_directory
34
+ file = @resource.name
35
+ unless_uptodate(:remove, "file already removed: '#{file}'") do
35
36
  remove_file
36
- @updated = true
37
- else
38
- Wright.log.debug "file already removed: '#{@resource.name}'"
39
37
  end
40
38
  end
41
39
 
@@ -45,7 +43,7 @@ module Wright
45
43
  file_permissions = permissions
46
44
  unless_dry_run("create file: '#{@resource.name}'") do
47
45
  write_content_to_file
48
- file_permissions.update
46
+ file_permissions.update unless file_permissions.uptodate?
49
47
  end
50
48
  end
51
49
 
@@ -85,13 +83,22 @@ module Wright
85
83
  current_checksum == target_checksum
86
84
  end
87
85
 
88
- def uptodate?
89
- content_uptodate? && permissions.uptodate?
86
+ def uptodate?(action)
87
+ case action
88
+ when :create
89
+ content_uptodate? && permissions.uptodate?
90
+ when :remove
91
+ !::File.exist?(filename) && !::File.symlink?(filename)
92
+ end
90
93
  end
91
94
 
92
95
  def filename
93
96
  ::File.expand_path(@resource.name)
94
97
  end
98
+
99
+ def fail_if_directory
100
+ fail Errno::EISDIR, filename if ::File.directory?(filename)
101
+ end
95
102
  end
96
103
  end
97
104
  end
@@ -1,4 +1,3 @@
1
- require 'wright/dry_run'
2
1
  require 'wright/provider'
3
2
  require 'wright/provider/group'
4
3
 
@@ -47,13 +46,7 @@ module Wright
47
46
 
48
47
  def next_system_gid
49
48
  system_gid_range = (1...500)
50
- used_system_gids = []
51
- Etc.group do |g|
52
- used_system_gids << g.gid if system_gid_range.include?(g.gid)
53
- end
54
- free_system_gids = system_gid_range.to_a - used_system_gids
55
- fail 'No free gids in system gid range' if free_system_gids.empty?
56
- free_system_gids.max
49
+ Wright::Util::User.next_free_gid(system_gid_range)
57
50
  end
58
51
  end
59
52
  end
@@ -1,4 +1,3 @@
1
- require 'wright/dry_run'
2
1
  require 'wright/provider'
3
2
  require 'wright/provider/group'
4
3
 
@@ -10,26 +10,20 @@ module Wright
10
10
  #
11
11
  # @return [void]
12
12
  def create
13
- if uptodate?(:create)
14
- Wright.log.debug "group already created: '#{@resource.name}'"
15
- return
13
+ group = @resource.name
14
+ unless_uptodate(:create, "group already created: '#{group}'") do
15
+ create_group
16
16
  end
17
-
18
- create_group
19
- @updated = true
20
17
  end
21
18
 
22
19
  # Removes the group.
23
20
  #
24
21
  # @return [void]
25
22
  def remove
26
- if uptodate?(:remove)
27
- Wright.log.debug "group already removed: '#{@resource.name}'"
28
- return
23
+ group = @resource.name
24
+ unless_uptodate(:remove, "group already removed: '#{group}'") do
25
+ remove_group
29
26
  end
30
-
31
- remove_group
32
- @updated = true
33
27
  end
34
28
 
35
29
  private
@@ -1,6 +1,3 @@
1
- require 'open3'
2
-
3
- require 'wright/dry_run'
4
1
  require 'wright/provider'
5
2
  require 'wright/provider/package'
6
3
 
@@ -12,33 +9,24 @@ module Wright
12
9
  class Apt < Wright::Provider::Package
13
10
  # @return [Array<String>] the installed package versions
14
11
  def installed_versions
15
- cmd = 'dpkg-query'
16
- args = ['-s', @resource.name]
17
- cmd_stdout, _, cmd_status = Open3.capture3(env, cmd, *args)
18
- installed_re = /^Status: install ok installed$/
12
+ package = @resource.name
13
+ err = "Cannot determine installed versions for package '#{package}'"
14
+ apt_policy = exec_or_fail('apt-cache', ['policy', package], err)
19
15
 
20
- if cmd_status.success? && installed_re =~ cmd_stdout
21
- /^Version: (?<version>.*)$/ =~ cmd_stdout
22
- [version]
23
- else
24
- []
25
- end
16
+ version_re = /(?!\(none\)).*/
17
+ installed_re = /^ Installed: (?<version>#{version_re})$/
18
+ match = installed_re.match(apt_policy)
19
+ match ? [match['version']] : []
26
20
  end
27
21
 
28
22
  private
29
23
 
30
24
  def install_package
31
- package = @resource.name
32
- unless_dry_run("install package: '#{package}'") do
33
- apt_get(:install, package, @resource.version)
34
- end
25
+ apt_get(:install, @resource.name, @resource.version)
35
26
  end
36
27
 
37
28
  def remove_package
38
- package = @resource.name
39
- unless_dry_run("remove package: '#{package}'") do
40
- apt_get(:remove, package)
41
- end
29
+ apt_get(:remove, @resource.name)
42
30
  end
43
31
 
44
32
  def apt_get(action, package, version = nil)
@@ -1,7 +1,6 @@
1
1
  require 'open3'
2
2
  require 'json'
3
3
 
4
- require 'wright/dry_run'
5
4
  require 'wright/provider'
6
5
  require 'wright/provider/package'
7
6
 
@@ -29,32 +28,20 @@ module Wright
29
28
  private
30
29
 
31
30
  def install_package
32
- package = @resource.name
33
- unless_dry_run("install package: '#{package}'") do
34
- brew(:install, package, @resource.version)
35
- end
31
+ brew(:install, @resource.name, @resource.version)
36
32
  end
37
33
 
38
34
  def remove_package
39
- package = @resource.name
40
- unless_dry_run("remove package: '#{package}'") do
41
- brew(:uninstall, package)
42
- end
35
+ brew(:uninstall, @resource.name)
43
36
  end
44
37
 
45
38
  def brew(action, package, version = nil)
46
39
  ignore_version(version)
47
40
 
48
- cmd = 'brew'
49
- args = [action.to_s, package]
50
-
51
- _, cmd_stderr, cmd_status = Wright::Util.bundler_clean_env do
52
- Open3.capture3(env, cmd, *args)
41
+ Wright::Util.bundler_clean_env do
42
+ error_message = "cannot #{action} package '#{package}'"
43
+ exec_or_fail('brew', [action.to_s, package], error_message)
53
44
  end
54
- return if cmd_status.success?
55
-
56
- brew_error = cmd_stderr.chomp
57
- fail %(cannot #{action} package '#{package}': "#{brew_error}")
58
45
  end
59
46
 
60
47
  def ignore_version(version)
@@ -9,26 +9,29 @@ module Wright
9
9
  #
10
10
  # @return [void]
11
11
  def install
12
- if uptodate?(:install)
13
- Wright.log.debug "package already installed: '#{@resource.name}'"
14
- return
12
+ package = @resource.name
13
+ unless_uptodate(:install, "package already installed: '#{package}'") do
14
+ unless_dry_run("install package: '#{package}'") do
15
+ install_package
16
+ end
15
17
  end
16
-
17
- install_package
18
- @updated = true
19
18
  end
20
19
 
21
20
  # Removes the package.
22
21
  #
23
22
  # @return [void]
24
23
  def remove
25
- if uptodate?(:remove)
26
- Wright.log.debug "package already removed: '#{@resource.name}'"
27
- return
24
+ package = @resource.name
25
+ unless_uptodate(:remove, "package already removed: '#{package}'") do
26
+ unless_dry_run("remove package: '#{package}'") do
27
+ remove_package
28
+ end
28
29
  end
30
+ end
29
31
 
30
- remove_package
31
- @updated = true
32
+ # @return [Array<String>] the installed package versions
33
+ def installed_versions
34
+ fail NotImplementedError
32
35
  end
33
36
 
34
37
  private
@@ -60,6 +63,14 @@ module Wright
60
63
  !installed_versions.empty?
61
64
  end
62
65
  end
66
+
67
+ def install_package
68
+ fail NotImplementedError
69
+ end
70
+
71
+ def remove_package
72
+ fail NotImplementedError
73
+ end
63
74
  end
64
75
  end
65
76
  end
@@ -10,42 +10,36 @@ module Wright
10
10
  #
11
11
  # @return [void]
12
12
  def create
13
- if exist?
14
- symlink = symlink_to_s(@resource.name, @resource.to)
15
- Wright.log.debug "symlink already created: #{symlink}"
16
- return
17
- end
18
-
19
13
  fail Errno::EEXIST, link_name if regular_file?
20
- create_link
21
- @updated = true
14
+
15
+ symlink = symlink_to_s(@resource.name, @resource.to)
16
+ unless_uptodate(:create, "symlink already created: #{symlink}") do
17
+ create_link
18
+ end
22
19
  end
23
20
 
24
21
  # Removes the symlink.
25
22
  #
26
23
  # @return [void]
27
24
  def remove
28
- if ::File.exist?(link_name) && !::File.symlink?(link_name)
29
- fail "'#{link_name}' is not a symlink"
30
- end
25
+ fail "'#{link_name}' is not a symlink" if regular_file?
31
26
 
32
- if ::File.symlink?(link_name)
27
+ symlink = @resource.name
28
+ unless_uptodate(:remove, "symlink already removed: '#{symlink}'") do
33
29
  remove_symlink
34
- @updated = true
35
- else
36
- Wright.log.debug "symlink already removed: '#{@resource.name}'"
37
30
  end
38
31
  end
39
32
 
40
33
  private
41
34
 
42
- # Checks if the specified link exists.
43
- #
44
- # Returns true if the link exists and points to the specified
45
- # target and false otherwise.
46
- def exist?
47
- ::File.symlink?(link_name) &&
48
- ::File.readlink(link_name) == link_to
35
+ def uptodate?(action)
36
+ case action
37
+ when :create
38
+ ::File.symlink?(link_name) &&
39
+ ::File.readlink(link_name) == link_to
40
+ when :remove
41
+ !::File.symlink?(link_name)
42
+ end
49
43
  end
50
44
 
51
45
  def create_link
@@ -70,6 +64,7 @@ module Wright
70
64
  end
71
65
 
72
66
  def link_to
67
+ return nil if @resource.to.nil?
73
68
  Wright::Util::File.expand_tilde_path(@resource.to)
74
69
  end
75
70
 
@@ -0,0 +1,65 @@
1
+ require 'wright/provider'
2
+ require 'wright/provider/user'
3
+
4
+ module Wright
5
+ class Provider
6
+ class User
7
+ # Darwin DirectoryService user provider. Used as a provider for
8
+ # {Resource::User} on OS X systems.
9
+ class DarwinDirectoryService < User
10
+ private
11
+
12
+ def add_user
13
+ user = @resource.name
14
+ attributes = default_attributes.merge(resource_attributes)
15
+ attributes.each do |k, v|
16
+ args = dscl_args(:create, k, v)
17
+ exec_or_fail('dscl', args, "cannot create user '#{user}'")
18
+ end
19
+ end
20
+
21
+ def update_user
22
+ user = @resource.name
23
+ resource_attributes.each do |k, v|
24
+ args = dscl_args(:create, k, v)
25
+ exec_or_fail('dscl', args, "cannot create user '#{user}'")
26
+ end
27
+ end
28
+
29
+ def delete_user
30
+ user = @resource.name
31
+ exec_or_fail('dscl',
32
+ %W(. -delete /Users/#{user}),
33
+ "cannot remove user '#{user}'")
34
+ end
35
+
36
+ def dscl_args(cmd, key, value)
37
+ %W(. -#{cmd} /Users/#{@resource.name} #{key} #{value})
38
+ end
39
+
40
+ def default_attributes
41
+ uid_range = @resource.system ? 1...500 : 500...1000
42
+ {
43
+ 'UniqueID' => Wright::Util::User.next_free_uid(uid_range),
44
+ 'UserShell' => '/bin/bash',
45
+ 'RealName' => '',
46
+ 'NFSHomeDirectory' => "/Users/#{@resource.name}",
47
+ 'PrimaryGroupID' => Wright::Util::User.group_to_gid('staff'),
48
+ 'Password' => '*'
49
+ }
50
+ end
51
+
52
+ def resource_attributes
53
+ gid = Wright::Util::User.group_to_gid(@resource.primary_group)
54
+ {
55
+ 'UniqueID' => @resource.uid,
56
+ 'UserShell' => @resource.shell,
57
+ 'RealName' => @resource.full_name,
58
+ 'NFSHomeDirectory' => @resource.home,
59
+ 'PrimaryGroupID' => gid
60
+ }.reject { |_k, v| v.nil? }
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -1,4 +1,3 @@
1
- require 'wright/dry_run'
2
1
  require 'wright/provider'
3
2
  require 'wright/provider/user'
4
3
 
@@ -12,16 +11,16 @@ module Wright
12
11
 
13
12
  def add_user
14
13
  user = @resource.name
15
- cmd = 'useradd'
16
- args = [*user_options, user]
17
- exec_or_fail(cmd, args, "cannot create user '#{user}'")
14
+ exec_or_fail('useradd',
15
+ [*user_options, user],
16
+ "cannot create user '#{user}'")
18
17
  end
19
18
 
20
19
  def update_user
21
20
  user = @resource.name
22
- cmd = 'usermod'
23
- args = [*user_options, user]
24
- exec_or_fail(cmd, args, "cannot create user '#{user}'")
21
+ exec_or_fail('usermod',
22
+ [*user_options, user],
23
+ "cannot create user '#{user}'")
25
24
  end
26
25
 
27
26
  def user_options