1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
require File.join(File.dirname(__FILE__), '..', 'vcsrepo')
Puppet::Type.type(:vcsrepo).provide(:git, :parent => Puppet::Provider::Vcsrepo) do
desc "Supports Git repositories"
commands :git => 'git'
defaultfor :git => :exists
has_features :bare_repositories, :reference_tracking
def create
if !@resource.value(:source)
init_repository(@resource.value(:path))
else
clone_repository(@resource.value(:source), @resource.value(:path))
if @resource.value(:revision)
if @resource.value(:ensure) == :bare
notice "Ignoring revision for bare repository"
else
reset(@resource.value(:revision))
end
end
end
end
def destroy
FileUtils.rm_rf(@resource.value(:path))
end
def revision
current = at_path { git('rev-parse', 'HEAD') }
canonical = at_path { git('rev-parse', @resource.value(:revision)) }
if current == canonical
@resource.value(:revision)
else
current
end
end
def revision=(desired)
fetch
reset(desired)
end
def bare_exists?
bare_git_config_exists? && !working_copy_exists?
end
def working_copy_exists?
File.directory?(File.join(@resource.value(:path), '.git'))
end
def exists?
working_copy_exists? || bare_exists?
end
def update_references
at_path do
git('fetch', '--tags', 'origin')
end
end
private
def path_exists?
File.directory?(@resource.value(:path))
end
def bare_git_config_exists?
File.exist?(File.join(@resource.value(:path), 'config'))
end
def clone_repository(source, path)
args = ['clone']
if @resource.value(:ensure) == :bare
args << '--bare'
end
args.push(source, path)
git(*args)
end
def fetch
at_path do
git('fetch', 'origin')
end
end
def init_repository(path)
if @resource.value(:ensure) == :bare && working_copy_exists?
convert_working_copy_to_bare
elsif @resource.value(:ensure) == :present && bare_exists?
convert_bare_to_working_copy
elsif File.directory?(@resource.value(:path))
raise Puppet::Error, "Could not create repository (non-repository at path)"
else
normal_init
end
end
# Convert working copy to bare
#
# Moves:
# <path>/.git
# to:
# <path>/
def convert_working_copy_to_bare
notice "Converting working copy repository to bare repository"
FileUtils.mv(File.join(@resource.value(:path), '.git'), tempdir)
FileUtils.rm_rf(@resource.value(:path))
FileUtils.mv(tempdir, @resource.value(:path))
end
# Convert bare to working copy
#
# Moves:
# <path>/
# to:
# <path>/.git
def convert_bare_to_working_copy
notice "Converting bare repository to working copy repository"
FileUtils.mv(@resource.value(:path), tempdir)
FileUtils.mkdir(@resource.value(:path))
FileUtils.mv(tempdir, File.join(@resource.value(:path), '.git'))
if commits_in?(File.join(@resource.value(:path), '.git'))
reset('HEAD')
git('checkout', '-f')
end
end
def normal_init
FileUtils.mkdir(@resource.value(:path))
args = ['init']
if @resource.value(:ensure) == :bare
args << '--bare'
end
at_path do
git(*args)
end
end
def commits_in?(dot_git)
Dir.glob(File.join(dot_git, 'objects/info/*'), File::FNM_DOTMATCH) do |e|
return true unless %w(. ..).include?(File::basename(e))
end
false
end
def reset(desired)
at_path do
git('reset', '--hard', desired)
end
end
end
|