Merge pull request #238 from anodelman/master
[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   feature :basic_auth,
9           "The provider supports HTTP Basic Authentication"
10   feature :bare_repositories,
11           "The provider differentiates between bare repositories
12           and those with working copies",
13           :methods => [:bare_exists?, :working_copy_exists?]
14
15   feature :filesystem_types,
16           "The provider supports different filesystem types"
17
18   feature :reference_tracking,
19           "The provider supports tracking revision references that can change
20            over time (eg, some VCS tags and branch names)"
21
22   feature :ssh_identity,
23           "The provider supports a configurable SSH identity file"
24
25   feature :user,
26           "The provider can run as a different user"
27
28   feature :modules,
29           "The repository contains modules that can be chosen of"
30
31   feature :multiple_remotes,
32           "The repository tracks multiple remote repositories"
33
34   feature :configuration,
35           "The configuration directory to use"
36
37   feature :cvs_rsh,
38           "The provider understands the CVS_RSH environment variable"
39
40   feature :depth,
41           "The provider can do shallow clones"
42
43   feature :p4config,
44           "The provider understands Perforce Configuration"
45
46   feature :submodules,
47           "The repository contains submodules which can be optionally initialized"
48
49   ensurable do
50     attr_accessor :latest
51
52     def insync?(is)
53       @should ||= []
54
55       case should
56       when :present
57         return true unless [:absent, :purged, :held].include?(is)
58       when :latest
59         if is == :latest
60           return true
61         else
62           return false
63         end
64       when :bare
65         return is == :bare
66       end
67     end
68
69     newvalue :present do
70       notice "Creating repository from present"
71       provider.create
72     end
73
74     newvalue :bare, :required_features => [:bare_repositories] do
75       if !provider.exists?
76         provider.create
77       end
78     end
79
80     newvalue :absent do
81       provider.destroy
82     end
83
84     newvalue :latest, :required_features => [:reference_tracking] do
85       if provider.exists? && !@resource.value(:force)
86         if provider.respond_to?(:update_references)
87           provider.update_references
88         end
89         if provider.respond_to?(:latest?)
90             reference = provider.latest || provider.revision
91         else
92           reference = resource.value(:revision) || provider.revision
93         end
94         notice "Updating to latest '#{reference}' revision"
95         provider.revision = reference
96       else
97         notice "Creating repository from latest"
98         provider.create
99       end
100     end
101
102     def retrieve
103       prov = @resource.provider
104       if prov
105         if prov.working_copy_exists?
106           (@should.include?(:latest) && prov.latest?) ? :latest : :present
107         elsif prov.class.feature?(:bare_repositories) and prov.bare_exists?
108           :bare
109         else
110           :absent
111         end
112       else
113         raise Puppet::Error, "Could not find provider"
114       end
115     end
116
117   end
118
119   newparam :path do
120     desc "Absolute path to repository"
121     isnamevar
122     validate do |value|
123       path = Pathname.new(value)
124       unless path.absolute?
125         raise ArgumentError, "Path must be absolute: #{path}"
126       end
127     end
128   end
129
130   newparam :source do
131     desc "The source URI for the repository"
132   end
133
134   newparam :fstype, :required_features => [:filesystem_types] do
135     desc "Filesystem type"
136   end
137
138   newproperty :revision do
139     desc "The revision of the repository"
140     newvalue(/^\S+$/)
141   end
142
143   newparam :owner do
144     desc "The user/uid that owns the repository files"
145   end
146
147   newparam :group do
148     desc "The group/gid that owns the repository files"
149   end
150
151   newparam :user do
152     desc "The user to run for repository operations"
153   end
154
155   newparam :excludes do
156     desc "Files to be excluded from the repository"
157   end
158
159   newparam :force do
160     desc "Force repository creation, destroying any files on the path in the process."
161     newvalues(:true, :false)
162     defaultto false
163   end
164
165   newparam :compression, :required_features => [:gzip_compression] do
166     desc "Compression level"
167     validate do |amount|
168       unless Integer(amount).between?(0, 6)
169         raise ArgumentError, "Unsupported compression level: #{amount} (expected 0-6)"
170       end
171     end
172   end
173
174   newparam :basic_auth_username, :required_features => [:basic_auth] do
175     desc "HTTP Basic Auth username"
176   end
177
178   newparam :basic_auth_password, :required_features => [:basic_auth] do
179     desc "HTTP Basic Auth password"
180   end
181
182   newparam :identity, :required_features => [:ssh_identity] do
183     desc "SSH identity file"
184   end
185
186   newparam :module, :required_features => [:modules] do
187     desc "The repository module to manage"
188   end
189
190   newparam :remote, :required_features => [:multiple_remotes] do
191     desc "The remote repository to track"
192     defaultto "origin"
193   end
194
195   newparam :configuration, :required_features => [:configuration]  do
196     desc "The configuration directory to use"
197   end
198
199   newparam :cvs_rsh, :required_features => [:cvs_rsh] do
200     desc "The value to be used for the CVS_RSH environment variable."
201   end
202
203   newparam :depth, :required_features => [:depth] do
204     desc "The value to be used to do a shallow clone."
205   end
206
207   newparam :p4config, :required_features => [:p4config] do
208     desc "The Perforce P4CONFIG environment."
209   end
210
211   newparam :submodules, :required_features => [:submodules] do
212     desc "Initialize and update each submodule in the repository."
213     newvalues(:true, :false)
214     defaultto true
215   end
216
217   autorequire(:package) do
218     ['git', 'git-core']
219   end
220 end