Merge pull request #114 from freyes/add-git-shallow-clone
[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   ensurable do
44     attr_accessor :latest
45
46     def insync?(is)
47       @should ||= []
48
49       case should
50       when :present
51         return true unless [:absent, :purged, :held].include?(is)
52       when :latest
53         if is == :latest
54           return true
55         else
56           return false
57         end
58       when :bare
59         return is == :bare
60       end
61     end
62
63     newvalue :present do
64       notice "Creating repository from present"
65       provider.create
66     end
67
68     newvalue :bare, :required_features => [:bare_repositories] do
69       if !provider.exists?
70         provider.create
71       end
72     end
73
74     newvalue :absent do
75       provider.destroy
76     end
77
78     newvalue :latest, :required_features => [:reference_tracking] do
79       if provider.exists?
80         if provider.respond_to?(:update_references)
81           provider.update_references
82         end
83         if provider.respond_to?(:latest?)
84             reference = provider.latest || provider.revision
85         else
86           reference = resource.value(:revision) || provider.revision
87         end
88         notice "Updating to latest '#{reference}' revision"
89         provider.revision = reference
90       else
91         notice "Creating repository from latest"
92         provider.create
93       end
94     end
95
96     def retrieve
97       prov = @resource.provider
98       if prov
99         if prov.working_copy_exists?
100           (@should.include?(:latest) && prov.latest?) ? :latest : :present
101         elsif prov.class.feature?(:bare_repositories) and prov.bare_exists?
102           :bare
103         else
104           :absent
105         end
106       else
107         raise Puppet::Error, "Could not find provider"
108       end
109     end
110
111   end
112
113   newparam :path do
114     desc "Absolute path to repository"
115     isnamevar
116     validate do |value|
117       path = Pathname.new(value)
118       unless path.absolute?
119         raise ArgumentError, "Path must be absolute: #{path}"
120       end
121     end
122   end
123
124   newparam :source do
125     desc "The source URI for the repository"
126   end
127
128   newparam :fstype, :required_features => [:filesystem_types] do
129     desc "Filesystem type"
130   end
131
132   newproperty :revision do
133     desc "The revision of the repository"
134     newvalue(/^\S+$/)
135   end
136
137   newparam :owner do
138     desc "The user/uid that owns the repository files"
139   end
140
141   newparam :group do
142     desc "The group/gid that owns the repository files"
143   end
144
145   newparam :user do
146     desc "The user to run for repository operations"
147   end
148
149   newparam :excludes do
150     desc "Files to be excluded from the repository"
151   end
152
153   newparam :force do
154     desc "Force repository creation, destroying any files on the path in the process."
155     newvalues(:true, :false)
156     defaultto false
157   end
158
159   newparam :compression, :required_features => [:gzip_compression] do
160     desc "Compression level"
161     validate do |amount|
162       unless Integer(amount).between?(0, 6)
163         raise ArgumentError, "Unsupported compression level: #{amount} (expected 0-6)"
164       end
165     end
166   end
167
168   newparam :basic_auth_username, :required_features => [:basic_auth] do
169     desc "HTTP Basic Auth username"
170   end
171
172   newparam :basic_auth_password, :required_features => [:basic_auth] do
173     desc "HTTP Basic Auth password"
174   end
175
176   newparam :identity, :required_features => [:ssh_identity] do
177     desc "SSH identity file"
178   end
179
180   newparam :module, :required_features => [:modules] do
181     desc "The repository module to manage"
182   end
183
184   newparam :remote, :required_features => [:multiple_remotes] do
185     desc "The remote repository to track"
186     defaultto "origin"
187   end
188
189   newparam :configuration, :required_features => [:configuration]  do
190     desc "The configuration directory to use"
191   end
192
193   newparam :cvs_rsh, :required_features => [:cvs_rsh] do
194     desc "The value to be used for the CVS_RSH environment variable."
195   end
196
197   newparam :depth, :required_features => [:depth] do
198     desc "The value to be used to do a shallow clone."
199   end
200
201   autorequire(:package) do
202     ['git', 'git-core']
203   end
204
205 end