Fix #7534: provider.revision should not get called when repo doesn't exist.
[puppet_vcsrepo.git] / lib / puppet / type / vcsrepo.rb
1 require 'pathname'
2
3 Puppet::Type.newtype(:vcsrepo) do
4   desc "A local version control repository"
5
6   feature :gzip_compression,
7           "The provider supports explicit GZip compression levels"
8
9   feature :bare_repositories,
10           "The provider differentiates between bare repositories
11           and those with working copies",
12           :methods => [:bare_exists?, :working_copy_exists?]
13
14   feature :filesystem_types,
15           "The provider supports different filesystem types"
16
17   feature :reference_tracking,
18           "The provider supports tracking revision references that can change
19            over time (eg, some VCS tags and branch names)"
20
21   ensurable do
22     attr_accessor :latest
23
24     def insync?(is)
25       @should ||= []
26
27       case should
28         when :present
29           return true unless [:absent, :purged, :held].include?(is)
30         when :latest
31           if is == :latest
32             return true
33           else
34             return false
35           end
36       end
37     end
38
39     newvalue :present do
40       provider.create
41     end
42
43     newvalue :bare, :required_features => [:bare_repositories] do
44       provider.create
45     end
46
47     newvalue :absent do
48       provider.destroy
49     end
50
51     newvalue :latest, :required_features => [:reference_tracking] do
52       if provider.exists?
53         if provider.respond_to?(:update_references)
54           provider.update_references
55         end
56         if provider.respond_to?(:latest?)
57             reference = provider.latest || provider.revision
58         else
59           reference = resource.value(:revision) || provider.revision
60         end
61         notice "Updating to latest '#{reference}' revision"
62         provider.revision = reference
63       else
64         provider.create
65       end
66     end
67
68     def retrieve
69       prov = @resource.provider
70       if prov
71         if prov.working_copy_exists?
72           prov.latest? ? :latest : :present
73         elsif prov.class.feature?(:bare_repositories) and prov.bare_exists?
74           :bare
75         else
76           :absent
77         end
78       else
79         raise Puppet::Error, "Could not find provider"
80       end
81     end
82
83   end
84
85   newparam(:path) do
86     desc "Absolute path to repository"
87     isnamevar
88     validate do |value|
89       path = Pathname.new(value)
90       unless path.absolute?
91         raise ArgumentError, "Path must be absolute: #{path}"
92       end
93     end
94   end
95
96   newparam(:source) do
97     desc "The source URI for the repository"
98   end
99
100   newparam(:fstype, :required_features => [:filesystem_types]) do
101     desc "Filesystem type"
102   end
103
104   newproperty(:revision) do
105     desc "The revision of the repository"
106     newvalue(/^\S+$/)
107   end
108
109   newparam(:owner) do
110     desc "The user/uid that owns the repository files"
111   end
112
113   newparam(:group) do
114     desc "The group/gid that owns the repository files"
115   end
116
117   newparam(:excludes) do
118     desc "Files to be excluded from the repository"
119   end
120
121   newparam(:force) do
122     desc "Force repository creation, destroying any files on the path in the process."
123     newvalues(:true, :false)
124     defaultto false
125   end
126
127   newparam :compression, :required_features => [:gzip_compression] do
128     desc "Compression level"
129     validate do |amount|
130       unless Integer(amount).between?(0, 6)
131         raise ArgumentError, "Unsupported compression level: #{amount} (expected 0-6)"
132       end
133     end
134   end
135
136 end