Skip to content

Commit

Permalink
support force-cleaning git repos
Browse files Browse the repository at this point in the history
'git clean -fd' should have the most reasonably expected result (files
in .gitignore are still ignored). This change is written to support
other cleaning methods in the future, if desired.
  • Loading branch information
bugfood committed Dec 29, 2023
1 parent 5ba1953 commit 45c2f94
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 2 deletions.
19 changes: 18 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,22 @@ It only comes into effect if the revision parameter is different from the local

**WARNING:** This overwrites any conflicting local changes to the repository.

To remove untracked changes in the local repository, set `repository_status` to `default_clean`.

~~~ puppet
vcsrepo { '/path/to/repo':
ensure => present,
provider => git,
source => 'git://example.com/repo.git',
repository_status => 'default_clean',
}
~~~

The `default_clean` value directs vcsrepo to run `git clean -fd`, which does
not affect files specified in the `.gitignore` file; future versions of
vcsrepo may support other values for `repository_status`. Note that when this
is in use, the `keep_local_changes` parameter has no net effect.

To keep the repository at the latest revision, set `ensure` to 'latest':

~~~ puppet
Expand Down Expand Up @@ -797,7 +813,7 @@ For information on the classes and types, see the [REFERENCE.md](https://github.

##### `git` - Supports the Git VCS.

Features: `bare_repositories`, `depth`, `multiple_remotes`, `reference_tracking`, `ssh_identity`, `submodules`, `user`
Features: `bare_repositories`, `depth`, `multiple_remotes`, `reference_tracking`, `ssh_identity`, `submodules`, `user`, `working_copy_status'

Parameters: `depth`, `ensure`, `excludes`, `force`, `group`, `identity`, `owner`, `path`, `provider`, `remote`, `revision`, `source`, `user`

Expand Down Expand Up @@ -852,6 +868,7 @@ Parameters: `basic_auth_password`, `basic_auth_username`, `configuration`, `conf
* `ssh_identity` - Lets you specify an SSH identity file. (Available with `git` and `hg`.)
* `submodules` - Supports repository submodules which can be optionally initialized. (Available with `git`.)
* `user` - Can run as a different user. (Available with `git`, `hg` and `cvs`.)
* `working_copy_status` - Can enforce the status of a working copy. (Available with `git`.)

<a id="limitations"></a>
## Limitations
Expand Down
37 changes: 36 additions & 1 deletion lib/puppet/provider/vcsrepo/git.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

has_features :bare_repositories, :reference_tracking, :ssh_identity, :multiple_remotes,
:user, :depth, :branch, :submodules, :safe_directory, :hooks_allowed,
:umask, :http_proxy, :tmpdir
:umask, :http_proxy, :tmpdir, :repository_status

def create
check_force
Expand Down Expand Up @@ -72,6 +72,8 @@ def revision
# @param [String] desired The desired revision to which the repo should be
# set.
def revision=(desired)
# Set the working copy status first
set_repository_status(@resource.value(:repository_status))
# just checkout tags and shas; fetch has already happened so they should be updated.
checkout(desired)
# branches require more work.
Expand Down Expand Up @@ -232,6 +234,39 @@ def update_references
end
end

# Return the status of the working copy.
def repository_status
# Optimization: if we don't care about the status, then return right away.
# This avoids running 'git status', which may be costly on very large repos
# on slow, uncached filesystems.
if @resource.value(:repository_status) == :ignore
return :ignore
end

at_path do
# This allows files specified in .gitignore.
status = exec_git('status', '--porcelain')
return :default_clean if status.empty?
return :default_dirty
end
end

def repository_status=(desired)
set_repository_status(desired)
end

def set_repository_status(desired)
case desired
when :default_clean
at_path do
exec_git('clean', '-fd')
end
when :ignore

Check failure on line 264 in lib/puppet/provider/vcsrepo/git.rb

View workflow job for this annotation

GitHub Actions / Spec / Spec tests (Puppet: ~> 7.24, Ruby Ver: 2.7)

Lint/EmptyWhen: Avoid `when` branches without a body.

Check failure on line 264 in lib/puppet/provider/vcsrepo/git.rb

View workflow job for this annotation

GitHub Actions / Spec / Spec tests (Puppet: ~> 8.0, Ruby Ver: 3.2)

Lint/EmptyWhen: Avoid `when` branches without a body.
else
raise Puppet::Error, "Desired repository_status not implemented: #{desired}"
end
end

# Convert working copy to bare
#
# Moves:
Expand Down
17 changes: 17 additions & 0 deletions lib/puppet/type/vcsrepo.rb
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@
feature :tmpdir,
'The provider supports setting the temp directory used for wrapper scripts.'

feature :repository_status,
'The provider supports setting the local repository status (to remove uncommitted local changes).'

ensurable do
desc 'Ensure the version control repository.'
attr_accessor :latest
Expand Down Expand Up @@ -355,6 +358,20 @@ def insync?(is)
desc 'The temp directory used for wrapper scripts.'
end

newproperty :repository_status do
newvalue :default_clean
newvalue :ignore
defaultto :ignore

def insync?(is)
# unwrap @should
should = @should[0]
return true if should == :ignore
return true if is == should
false
end
end

autorequire(:package) do
['git', 'git-core', 'mercurial', 'subversion']
end
Expand Down
28 changes: 28 additions & 0 deletions spec/unit/puppet/provider/vcsrepo/git_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,34 @@ def branch_a_list(include_branch = nil?)
provider.create
end
end

context 'when with an ensure of present - with repository_status of ignore' do
it "does not check the status" do

Check failure on line 176 in spec/unit/puppet/provider/vcsrepo/git_spec.rb

View workflow job for this annotation

GitHub Actions / Spec / Spec tests (Puppet: ~> 7.24, Ruby Ver: 2.7)

Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols. (https://rubystyle.guide#consistent-string-literals)

Check failure on line 176 in spec/unit/puppet/provider/vcsrepo/git_spec.rb

View workflow job for this annotation

GitHub Actions / Spec / Spec tests (Puppet: ~> 8.0, Ruby Ver: 3.2)

Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols. (https://rubystyle.guide#consistent-string-literals)
resource[:repository_status] = :ignore
expect(provider).to_not receive(:exec_git)

Check failure on line 178 in spec/unit/puppet/provider/vcsrepo/git_spec.rb

View workflow job for this annotation

GitHub Actions / Spec / Spec tests (Puppet: ~> 7.24, Ruby Ver: 2.7)

RSpec/NotToNot: Prefer `not_to` over `to_not`. (https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/NotToNot)

Check failure on line 178 in spec/unit/puppet/provider/vcsrepo/git_spec.rb

View workflow job for this annotation

GitHub Actions / Spec / Spec tests (Puppet: ~> 8.0, Ruby Ver: 3.2)

RSpec/NotToNot: Prefer `not_to` over `to_not`. (https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/NotToNot)
provider.repository_status
end

it "does not clean" do

Check failure on line 182 in spec/unit/puppet/provider/vcsrepo/git_spec.rb

View workflow job for this annotation

GitHub Actions / Spec / Spec tests (Puppet: ~> 7.24, Ruby Ver: 2.7)

Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols. (https://rubystyle.guide#consistent-string-literals)

Check failure on line 182 in spec/unit/puppet/provider/vcsrepo/git_spec.rb

View workflow job for this annotation

GitHub Actions / Spec / Spec tests (Puppet: ~> 8.0, Ruby Ver: 3.2)

Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols. (https://rubystyle.guide#consistent-string-literals)
expect(provider).to_not receive(:exec_git)

Check failure on line 183 in spec/unit/puppet/provider/vcsrepo/git_spec.rb

View workflow job for this annotation

GitHub Actions / Spec / Spec tests (Puppet: ~> 7.24, Ruby Ver: 2.7)

RSpec/NotToNot: Prefer `not_to` over `to_not`. (https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/NotToNot)

Check failure on line 183 in spec/unit/puppet/provider/vcsrepo/git_spec.rb

View workflow job for this annotation

GitHub Actions / Spec / Spec tests (Puppet: ~> 8.0, Ruby Ver: 3.2)

RSpec/NotToNot: Prefer `not_to` over `to_not`. (https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/NotToNot)
provider.repository_status=(:ignore)

Check failure on line 184 in spec/unit/puppet/provider/vcsrepo/git_spec.rb

View workflow job for this annotation

GitHub Actions / Spec / Spec tests (Puppet: ~> 7.24, Ruby Ver: 2.7)

Layout/SpaceAroundOperators: Surrounding space missing for operator `=`. (https://rubystyle.guide#spaces-operators)

Check failure on line 184 in spec/unit/puppet/provider/vcsrepo/git_spec.rb

View workflow job for this annotation

GitHub Actions / Spec / Spec tests (Puppet: ~> 8.0, Ruby Ver: 3.2)

Layout/SpaceAroundOperators: Surrounding space missing for operator `=`. (https://rubystyle.guide#spaces-operators)
end
end

context 'when with an ensure of present - with repository_status of default_clean' do
it "checks the status" do

Check failure on line 189 in spec/unit/puppet/provider/vcsrepo/git_spec.rb

View workflow job for this annotation

GitHub Actions / Spec / Spec tests (Puppet: ~> 7.24, Ruby Ver: 2.7)

Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols. (https://rubystyle.guide#consistent-string-literals)

Check failure on line 189 in spec/unit/puppet/provider/vcsrepo/git_spec.rb

View workflow job for this annotation

GitHub Actions / Spec / Spec tests (Puppet: ~> 8.0, Ruby Ver: 3.2)

Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols. (https://rubystyle.guide#consistent-string-literals)
resource[:repository_status] = :default_clean
expect(Dir).to receive(:chdir).with('/tmp/test').at_least(:once).and_yield
expect(provider).to receive(:exec_git).with('status', '--porcelain').and_return('')
provider.repository_status
end

it "cleans the repo" do

Check failure on line 196 in spec/unit/puppet/provider/vcsrepo/git_spec.rb

View workflow job for this annotation

GitHub Actions / Spec / Spec tests (Puppet: ~> 7.24, Ruby Ver: 2.7)

Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols. (https://rubystyle.guide#consistent-string-literals)

Check failure on line 196 in spec/unit/puppet/provider/vcsrepo/git_spec.rb

View workflow job for this annotation

GitHub Actions / Spec / Spec tests (Puppet: ~> 8.0, Ruby Ver: 3.2)

Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols. (https://rubystyle.guide#consistent-string-literals)
expect(Dir).to receive(:chdir).with('/tmp/test').at_least(:once).and_yield
expect(provider).to receive(:exec_git).with('clean', '-fd').and_return('')
provider.repository_status=(:default_clean)

Check failure on line 199 in spec/unit/puppet/provider/vcsrepo/git_spec.rb

View workflow job for this annotation

GitHub Actions / Spec / Spec tests (Puppet: ~> 7.24, Ruby Ver: 2.7)

Layout/SpaceAroundOperators: Surrounding space missing for operator `=`. (https://rubystyle.guide#spaces-operators)

Check failure on line 199 in spec/unit/puppet/provider/vcsrepo/git_spec.rb

View workflow job for this annotation

GitHub Actions / Spec / Spec tests (Puppet: ~> 8.0, Ruby Ver: 3.2)

Layout/SpaceAroundOperators: Surrounding space missing for operator `=`. (https://rubystyle.guide#spaces-operators)
end
end
end

context 'when with an ensure of bare' do
Expand Down

0 comments on commit 45c2f94

Please sign in to comment.