Skip to content

Commit

Permalink
add filter_command directive (git only)
Browse files Browse the repository at this point in the history
  • Loading branch information
mhumpula committed Jul 12, 2018
1 parent 1dafec0 commit f864726
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 3 deletions.
18 changes: 18 additions & 0 deletions doc/dynamic-environments/configuration.mkd
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,24 @@ sources:
- 'dev'
```

### filter_command

You can filter out any branch based on the result of the command specified as 'filter_command'. Non zero return
status of the command results in a branch beeing removed. The command is passed additional environment variables
* GIT_DIR – path to the cached git repository
* R10K_BRANCH – brach which is beeing filtered
* R10K_NAME – source name from r10k configuration

This can be used for example for filtering out the branches with invalid gpg signature of their latests commit

```yaml
---
sources:
mysource:
basedir: '/etc/puppet/environments'
filter_command: 'git verify-commit $R10K_BRANCH 2> /dev/null'
```

Examples
--------

Expand Down
24 changes: 22 additions & 2 deletions lib/r10k/source/git.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ class R10K::Source::Git < R10K::Source::Base
# that will be deployed as environments.
attr_reader :ignore_branch_prefixes

# @!attribute [r] filter_command
# @return [String] Command to run to filter branches
attr_reader :filter_command

# Initialize the given source.
#
# @param name [String] The identifier for this source.
Expand All @@ -61,6 +65,7 @@ def initialize(name, basedir, options = {})
@remote = options[:remote]
@invalid_branches = (options[:invalid_branches] || 'correct_and_warn')
@ignore_branch_prefixes = options[:ignore_branch_prefixes]
@filter_command = options[:filter_command]

@cache = R10K::Git.cache.generate(@remote)
end
Expand Down Expand Up @@ -115,7 +120,7 @@ def desired_contents
environments.map {|env| env.dirname }
end

def filter_branches(branches, ignore_prefixes)
def filter_branches_by_regexp(branches, ignore_prefixes)
filter = Regexp.new("^#{Regexp.union(ignore_prefixes)}")
branches = branches.reject do |branch|
result = filter.match(branch)
Expand All @@ -127,14 +132,29 @@ def filter_branches(branches, ignore_prefixes)
branches
end

def filter_branches_by_command(branches, command)
branches.select do |branch|
result = system({'GIT_DIR' => @cache.git_dir.to_s, 'R10K_BRANCH' => branch, 'R10K_NAME' => @name.to_s}, command)
unless result
logger.warn _("Branch `%{name}:%{branch}` filtered out by filter_command %{cmd}") % {name: @name, branch: branch, cmd: command}
end
result
end
end

private

def branch_names
opts = {:prefix => @prefix, :invalid => @invalid_branches, :source => @name}
branches = @cache.branches
if @ignore_branch_prefixes && !@ignore_branch_prefixes.empty?
branches = filter_branches(branches, @ignore_branch_prefixes)
branches = filter_branches_by_regexp(branches, @ignore_branch_prefixes)
end

if @filter_command && !@filter_command.empty?
branches = filter_branches_by_command(branches, @filter_command)
end

branches.map do |branch|
R10K::Environment::Name.new(branch, opts)
end
Expand Down
38 changes: 37 additions & 1 deletion spec/unit/source/git_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,45 @@
let(:ignore_prefixes) { ['dev', 'test'] }

it "filters branches" do
expect(subject.filter_branches(branches, ignore_prefixes)).to eq(['master', 'production', 'not_dev_test_me'])
expect(subject.filter_branches_by_regexp(branches, ignore_prefixes)).to eq(['master', 'production', 'not_dev_test_me'])
end
end

describe "filtering branches with command" do
let(:branches) { ['master', 'development', 'production'] }
let(:filter_command) { 'sh -c "[ $R10K_BRANCH != development ]"' }

it "filters branches" do
expect(subject.filter_branches_by_command(branches, filter_command)).to eq(['master', 'production'])
end
end

describe "generate_environments respects filter_command setting" do
before do
allow(subject.cache).to receive(:branches).and_return ['master', 'development', 'production']
subject.instance_variable_set(:@filter_command, '[ $R10K_BRANCH != master ]')
end

let(:environments) { subject.generate_environments }

it "creates an environment for each branch not filtered by filter_command" do
expect(subject.generate_environments.size).to eq(2)
end
end

describe "generate_environments respects filter_command setting and name" do
before do
allow(subject.cache).to receive(:branches).and_return ['master', 'development', 'production']
subject.instance_variable_set(:@filter_command, '[ $R10K_NAME = mysource ]')
end

let(:environments) { subject.generate_environments }

it "creates an environment for each branch not filtered by filter_command" do
expect(subject.generate_environments.size).to eq(3)
end
end

end

describe R10K::Source::Git, "handling invalid branch names" do
Expand Down

0 comments on commit f864726

Please sign in to comment.