quaker 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.gitmodules +3 -0
- data/Gemfile +5 -0
- data/README.md +3 -0
- data/exe/quaker +2 -0
- data/lib/quaker/compose_file.rb +9 -7
- data/lib/quaker/git_resolver.rb +40 -23
- data/lib/quaker/include.rb +13 -11
- data/lib/quaker/path_extensions.rb +23 -0
- data/lib/quaker/tag_filter.rb +26 -24
- data/lib/quaker/tag_matcher.rb +23 -0
- data/lib/quaker/templates.rb +28 -0
- data/lib/quaker/version.rb +1 -1
- data/lib/quaker.rb +34 -28
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 44ce3293ce8c169eedc97c4a6433fcdf865542e3
|
4
|
+
data.tar.gz: 085a92c69d42eaa6455c61e9edbcced63597343e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5ff78b67637e14828190df6f2e627a50813a7d0d884290aeb5e7a706701503939549f9afb94fda62e4a5a796d974e3e8282550b54a7d7301fc45e8f435a221c4
|
7
|
+
data.tar.gz: dd0f33de4a2c3830ab34385c69111d9bbcef8f9d4c80e1d98873f6500fed1a86b5bc80e1e33b1e4d6100ce6ed8fb7711c068280181f885e4ad17453a056178d5
|
data/.gitignore
CHANGED
data/.gitmodules
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,7 @@
|
|
1
1
|
[](https://codeclimate.com/github/igorshapiro/quaker)
|
2
|
+
[](https://badge.fury.io/rb/quaker)
|
3
|
+
[](https://circleci.com/gh/igorshapiro/quaker)
|
4
|
+
[](https://codeclimate.com/github/igorshapiro/quaker/coverage)
|
2
5
|
|
3
6
|
# Quaker
|
4
7
|
|
data/exe/quaker
CHANGED
data/lib/quaker/compose_file.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
-
|
1
|
+
module Quaker
|
2
|
+
require 'yaml'
|
2
3
|
|
3
|
-
class ComposeFile
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
class ComposeFile
|
5
|
+
def build spec
|
6
|
+
{
|
7
|
+
'version' => '2',
|
8
|
+
'services' => spec
|
9
|
+
}.to_yaml
|
10
|
+
end
|
9
11
|
end
|
10
12
|
end
|
data/lib/quaker/git_resolver.rb
CHANGED
@@ -1,31 +1,48 @@
|
|
1
|
-
|
1
|
+
module Quaker
|
2
|
+
require 'open3'
|
3
|
+
require 'git_clone_url'
|
2
4
|
|
3
|
-
class GitResolver
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
5
|
+
class GitResolver
|
6
|
+
# Parses repository url to { username: ..., repository: ...}
|
7
|
+
def parse_url url
|
8
|
+
begin
|
9
|
+
uri = GitCloneUrl.parse(url)
|
10
|
+
|
11
|
+
if uri.path.match /^\/?(.*?)\/(.*?)(.git)?$/
|
12
|
+
return { username: $1, repo: $2 }
|
13
|
+
end
|
14
|
+
rescue URI::InvalidComponentError => ex
|
15
|
+
end
|
16
|
+
url
|
17
|
+
end
|
18
|
+
|
19
|
+
def find_dir_for_repo repo
|
20
|
+
dir = Dir.glob('*')
|
21
|
+
.select {|f| File.directory? f}
|
22
|
+
.select {|dir|
|
23
|
+
stdin, stdout, stderr = Open3.popen3("cd #{dir} && git remote -v | awk '{print $2}'")
|
24
|
+
stdout.each_line
|
25
|
+
.map(&:strip)
|
26
|
+
.map {|l| parse_url(l) }
|
27
|
+
.include?(parse_url(repo))
|
28
|
+
}
|
29
|
+
.first
|
30
|
+
return nil unless dir
|
31
|
+
"./#{dir}"
|
32
|
+
end
|
16
33
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
next unless git_repo
|
34
|
+
def resolve services_map
|
35
|
+
for name, spec in services_map
|
36
|
+
git_repo = spec.delete("git")
|
37
|
+
next unless git_repo
|
22
38
|
|
23
|
-
|
39
|
+
dir = find_dir_for_repo git_repo
|
24
40
|
|
25
|
-
|
41
|
+
$stderr.puts "ERROR: Unable to find dir for repo #{git_repo}" and return unless dir
|
26
42
|
|
27
|
-
|
43
|
+
spec["build"] = dir
|
44
|
+
end
|
45
|
+
services_map
|
28
46
|
end
|
29
|
-
services_map
|
30
47
|
end
|
31
48
|
end
|
data/lib/quaker/include.rb
CHANGED
@@ -1,15 +1,17 @@
|
|
1
|
-
|
1
|
+
module Quaker
|
2
|
+
require 'yaml'
|
2
3
|
|
3
|
-
class Include
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
class Include
|
5
|
+
INCLUDE_KEY = 'include'
|
6
|
+
def process filepath
|
7
|
+
dir = File.join(filepath, '..')
|
8
|
+
spec = YAML.load(File.read(filepath))
|
9
|
+
return spec unless spec.has_key?(INCLUDE_KEY)
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
spec
|
12
|
+
.delete(INCLUDE_KEY)
|
13
|
+
.map {|file| File.expand_path(file, dir) }
|
14
|
+
.inject(spec) { |acc, file| acc.merge(process file) }
|
15
|
+
end
|
14
16
|
end
|
15
17
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Quaker
|
2
|
+
class PathExtensions
|
3
|
+
def expand_path volumes_desc, build_path
|
4
|
+
parts = volumes_desc.split(':')
|
5
|
+
parts[0].gsub! /^\~/, build_path
|
6
|
+
parts.join(':')
|
7
|
+
end
|
8
|
+
|
9
|
+
def expand_service_volumes spec
|
10
|
+
build_path = spec['build']
|
11
|
+
return unless build_path
|
12
|
+
|
13
|
+
volumes = spec['volumes']
|
14
|
+
return unless volumes
|
15
|
+
|
16
|
+
spec['volumes'] = volumes.map{|v| expand_path(v, build_path) }
|
17
|
+
end
|
18
|
+
|
19
|
+
def expand services
|
20
|
+
services.each {|name, spec| expand_service_volumes(spec) }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/quaker/tag_filter.rb
CHANGED
@@ -1,32 +1,34 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
1
|
+
module Quaker
|
2
|
+
class TagFilter
|
3
|
+
def dependencies services_map, name
|
4
|
+
spec = services_map[name]
|
5
|
+
depends_on = spec["depends_on"] || []
|
6
|
+
links = (spec["links"] || []).map{|l| l.split(':')[0]}
|
7
|
+
deps = links + depends_on
|
8
|
+
deps + deps.map{|d| dependencies(services_map, d)}.flatten
|
9
|
+
end
|
9
10
|
|
10
|
-
|
11
|
-
|
11
|
+
def is_tagged_service spec, tags_list
|
12
|
+
svc_tags = spec.delete("tags") || []
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
# Skip service if no common tags
|
15
|
+
common = svc_tags & tags_list
|
16
|
+
common && !common.empty?
|
17
|
+
end
|
17
18
|
|
18
|
-
|
19
|
-
|
19
|
+
def filter services_map, tags_list
|
20
|
+
return services_map if !tags_list || tags_list.empty?
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
|
22
|
+
services_map.inject({}){|acc, (name, spec)|
|
23
|
+
if is_tagged_service(spec, tags_list)
|
24
|
+
acc[name] = spec
|
24
25
|
|
25
|
-
|
26
|
-
|
27
|
-
|
26
|
+
dependencies(services_map, name)
|
27
|
+
.inject(acc){|acc, d| acc.update(d => services_map[d])}
|
28
|
+
end
|
28
29
|
|
29
|
-
|
30
|
-
|
30
|
+
acc
|
31
|
+
}
|
32
|
+
end
|
31
33
|
end
|
32
34
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Quaker
|
2
|
+
module TagMatcher
|
3
|
+
def self.match tags, patterns
|
4
|
+
return true if patterns.nil? || patterns.empty?
|
5
|
+
return false if tags.nil? || tags.empty?
|
6
|
+
|
7
|
+
patterns.any? {|pattern|
|
8
|
+
tags.any? {|tag| pattern_matches_string?(tag, pattern)}
|
9
|
+
}
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.pattern_matches_string? s, pattern
|
13
|
+
s == pattern || wildcard_matches?(s, pattern)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.wildcard_matches? s, pattern
|
17
|
+
return false unless pattern.include?('*')
|
18
|
+
escaped = Regexp.escape(pattern).gsub('\*','.*?')
|
19
|
+
regex = Regexp.new "^#{escaped}$", Regexp::IGNORECASE
|
20
|
+
!!(s =~ regex)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'quaker/tag_matcher'
|
2
|
+
|
3
|
+
module Quaker
|
4
|
+
class Templates
|
5
|
+
def apply services
|
6
|
+
templates = services.select {|name, v| template?(name)}
|
7
|
+
services
|
8
|
+
.reject {|name, v| template?(name)}
|
9
|
+
.inject({}) {|acc, (name, spec)|
|
10
|
+
acc.update(name => extend_with_matchine_templates(spec, templates))
|
11
|
+
}
|
12
|
+
end
|
13
|
+
|
14
|
+
def extend_with_matchine_templates service, templates
|
15
|
+
templates
|
16
|
+
.select {|name, spec| Quaker::TagMatcher::match(service["tags"], spec["tags"])}
|
17
|
+
.inject(service) {|svc, (_, spec)|
|
18
|
+
filtered_template_content = spec
|
19
|
+
.select{|name, spec| name != 'tags' }
|
20
|
+
svc.merge(filtered_template_content)
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
def template?(k)
|
25
|
+
!!(k =~ /_template$/)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/quaker/version.rb
CHANGED
data/lib/quaker.rb
CHANGED
@@ -2,39 +2,45 @@ require "quaker/version"
|
|
2
2
|
require "quaker/include"
|
3
3
|
require "quaker/tag_filter"
|
4
4
|
require "quaker/git_resolver"
|
5
|
+
require "quaker/templates"
|
6
|
+
require "quaker/path_extensions"
|
5
7
|
require "quaker/compose_file"
|
6
8
|
|
7
9
|
module Quaker
|
8
10
|
require 'clamp'
|
9
11
|
|
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
|
-
|
12
|
+
def self.run
|
13
|
+
Clamp do
|
14
|
+
parameter "[SPEC_FILE]", "Extended docker-compose file"
|
15
|
+
option %w(--tags -t), "TAGS", "Filter services (and dependencies) by tag", multivalued: true
|
16
|
+
option %w(--dir -d), "DIR", "Specify base directory"
|
17
|
+
|
18
|
+
def default_spec_file
|
19
|
+
File.expand_path('docker/services/all.yml', dir)
|
20
|
+
end
|
21
|
+
|
22
|
+
def default_dir
|
23
|
+
Dir.pwd
|
24
|
+
end
|
25
|
+
|
26
|
+
def dump_params
|
27
|
+
puts "Spec: #{spec_file}"
|
28
|
+
puts "Dir: #{dir}"
|
29
|
+
end
|
30
|
+
|
31
|
+
def execute
|
32
|
+
# dump_params
|
33
|
+
|
34
|
+
Dir.chdir dir
|
35
|
+
|
36
|
+
spec = Include.new.process spec_file
|
37
|
+
spec = Templates.new.apply spec
|
38
|
+
spec = TagFilter.new.filter spec, tags_list
|
39
|
+
spec = GitResolver.new.resolve spec
|
40
|
+
spec = PathExtensions.new.expand spec
|
41
|
+
spec = ComposeFile.new.build spec
|
42
|
+
puts spec
|
43
|
+
end
|
38
44
|
end
|
39
45
|
end
|
40
46
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: quaker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Igor Shapiro
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-10-
|
11
|
+
date: 2016-10-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -79,7 +79,10 @@ files:
|
|
79
79
|
- lib/quaker/compose_file.rb
|
80
80
|
- lib/quaker/git_resolver.rb
|
81
81
|
- lib/quaker/include.rb
|
82
|
+
- lib/quaker/path_extensions.rb
|
82
83
|
- lib/quaker/tag_filter.rb
|
84
|
+
- lib/quaker/tag_matcher.rb
|
85
|
+
- lib/quaker/templates.rb
|
83
86
|
- lib/quaker/version.rb
|
84
87
|
- quaker.gemspec
|
85
88
|
homepage: https://igorshapiro.github.io/quaker/
|