tetra 0.40.0 → 0.41.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.
- data/.gitignore +1 -1
- data/Gemfile +2 -0
- data/Gemfile.lock +48 -0
- data/MOTIVATION.md +9 -3
- data/README.md +5 -5
- data/SPECIAL_CASES.md +1 -3
- data/integration-tests/{commons.sh → build-commons.sh} +26 -6
- data/integration-tests/build-obs.sh +21 -0
- data/lib/template/kit_item.spec +53 -0
- data/lib/template/package.spec +4 -2
- data/lib/tetra.rb +5 -3
- data/lib/tetra/archiver.rb +23 -87
- data/lib/tetra/commands/generate_all.rb +13 -16
- data/lib/tetra/commands/generate_kit_archive.rb +4 -4
- data/lib/tetra/commands/generate_kit_spec.rb +4 -2
- data/lib/tetra/commands/generate_package_archive.rb +1 -1
- data/lib/tetra/commands/generate_package_spec.rb +2 -2
- data/lib/tetra/git.rb +19 -10
- data/lib/tetra/glue_kit_item.rb +42 -0
- data/lib/tetra/jar_kit_item.rb +45 -0
- data/lib/tetra/kit.rb +73 -0
- data/lib/tetra/maven_kit_item.rb +64 -0
- data/lib/tetra/package.rb +82 -0
- data/lib/tetra/project.rb +26 -22
- data/lib/tetra/spec_generator.rb +38 -42
- data/lib/tetra/version.rb +1 -1
- data/spec/lib/archiver_spec.rb +30 -86
- data/spec/lib/git_spec.rb +8 -8
- data/spec/lib/glue_kit_item_spec.rb +31 -0
- data/spec/lib/kit_spec.rb +67 -0
- data/spec/lib/maven_kit_item_spec.rb +74 -0
- data/spec/lib/package_spec.rb +78 -0
- data/spec/lib/project_spec.rb +1 -1
- data/spec/lib/spec_generator_spec.rb +59 -87
- metadata +15 -8
- data/lib/template/kit.spec +0 -64
- data/lib/tetra/kit_spec_adapter.rb +0 -28
- data/lib/tetra/package_spec_adapter.rb +0 -59
- data/lib/tetra/template_manager.rb +0 -33
- data/spec/lib/template_manager_spec.rb +0 -54
@@ -3,14 +3,14 @@
|
|
3
3
|
module Tetra
|
4
4
|
# tetra generate-kit-archive
|
5
5
|
class GenerateKitArchiveCommand < Tetra::BaseCommand
|
6
|
-
option %w(-w --whole), :flag, "recreate the whole archive (not incremental)"
|
7
|
-
|
8
6
|
def execute
|
9
7
|
checking_exceptions do
|
10
8
|
project = Tetra::Project.new(".")
|
11
9
|
ensure_dry_running(false, project) do
|
12
|
-
|
13
|
-
|
10
|
+
Tetra::Kit.new(project).items.each do |item|
|
11
|
+
result_path = item.to_archive
|
12
|
+
print_generation_result(project, result_path)
|
13
|
+
end
|
14
14
|
end
|
15
15
|
end
|
16
16
|
end
|
@@ -7,8 +7,10 @@ module Tetra
|
|
7
7
|
checking_exceptions do
|
8
8
|
project = Tetra::Project.new(".")
|
9
9
|
ensure_dry_running(false, project) do
|
10
|
-
|
11
|
-
|
10
|
+
Tetra::Kit.new(project).items.each do |item|
|
11
|
+
result_path, conflict_count = item.to_spec
|
12
|
+
print_generation_result(project, result_path, conflict_count)
|
13
|
+
end
|
12
14
|
end
|
13
15
|
end
|
14
16
|
end
|
@@ -10,7 +10,7 @@ module Tetra
|
|
10
10
|
project = Tetra::Project.new(".")
|
11
11
|
ensure_dry_running(false, project) do
|
12
12
|
package_name = project.get_package_name(directory)
|
13
|
-
result_path = Tetra::
|
13
|
+
result_path = Tetra::Package.new(project, package_name).to_archive
|
14
14
|
print_generation_result(project, result_path)
|
15
15
|
end
|
16
16
|
end
|
@@ -12,8 +12,8 @@ module Tetra
|
|
12
12
|
project = Tetra::Project.new(".")
|
13
13
|
ensure_dry_running(false, project) do
|
14
14
|
package_name = project.get_package_name(directory)
|
15
|
-
result_path, conflict_count =
|
16
|
-
.
|
15
|
+
result_path, conflict_count =
|
16
|
+
Tetra::Package.new(project, package_name, pom, filter).to_spec
|
17
17
|
print_generation_result(project, result_path, conflict_count)
|
18
18
|
end
|
19
19
|
end
|
data/lib/tetra/git.rb
CHANGED
@@ -46,10 +46,10 @@ module Tetra
|
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
-
# adds all files in the current directory
|
50
|
-
# all files not in the current directory
|
51
|
-
#
|
52
|
-
def commit_whole_directory(message, tag
|
49
|
+
# adds all files in the current directory, removes
|
50
|
+
# all files not in the current directory, commits
|
51
|
+
# and tags with prefix
|
52
|
+
def commit_whole_directory(message, tag, tag_message = nil)
|
53
53
|
Dir.chdir(@directory) do
|
54
54
|
log.debug "committing with message: #{message}"
|
55
55
|
|
@@ -65,16 +65,25 @@ module Tetra
|
|
65
65
|
`git add .`
|
66
66
|
`git commit -m "#{message}"`
|
67
67
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
`git tag tetra_#{tag}`
|
73
|
-
end
|
68
|
+
if !tag_message.nil?
|
69
|
+
`git tag tetra_#{tag} -m "#{tag_message}"`
|
70
|
+
else
|
71
|
+
`git tag tetra_#{tag}`
|
74
72
|
end
|
75
73
|
end
|
76
74
|
end
|
77
75
|
|
76
|
+
# commits and tags one single file
|
77
|
+
# if tag is given, commit is also tagged
|
78
|
+
def commit_file(path, message, tag)
|
79
|
+
Dir.chdir(@directory) do
|
80
|
+
log.debug "committing path #{path} with message: #{message}"
|
81
|
+
`git add #{path}`
|
82
|
+
`git commit -m "#{message}"`
|
83
|
+
`git tag tetra_#{tag}`
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
78
87
|
# returns the highest suffix found in tags with the given prefix
|
79
88
|
def get_tag_maximum_suffix(prefix)
|
80
89
|
Dir.chdir(@directory) do
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Tetra
|
4
|
+
# represents a prebuilt package dependency from a jar file
|
5
|
+
# in a kit
|
6
|
+
class GlueKitItem
|
7
|
+
# implement to_spec
|
8
|
+
include SpecGenerator
|
9
|
+
attr_reader :project
|
10
|
+
attr_reader :package_name
|
11
|
+
attr_reader :spec_dir
|
12
|
+
attr_reader :template_spec_name
|
13
|
+
attr_reader :conflicts
|
14
|
+
|
15
|
+
# implement to_archive
|
16
|
+
include Archiver
|
17
|
+
attr_reader :source_dir
|
18
|
+
attr_reader :source_paths
|
19
|
+
attr_reader :destination_dir
|
20
|
+
|
21
|
+
# template-specific attributes
|
22
|
+
attr_reader :provides_symbol
|
23
|
+
attr_reader :provides_version
|
24
|
+
attr_reader :install_dir
|
25
|
+
|
26
|
+
def initialize(project, source_paths)
|
27
|
+
@project = project
|
28
|
+
@package_name = "kit-item-glue-#{project.name}"
|
29
|
+
@spec_dir = "kit"
|
30
|
+
@template_spec_name = "kit_item.spec"
|
31
|
+
@conflicts = true
|
32
|
+
|
33
|
+
@source_dir = File.join("kit")
|
34
|
+
@source_paths = source_paths
|
35
|
+
@destination_dir = @package_name
|
36
|
+
|
37
|
+
@provides_symbol = "tetra-glue"
|
38
|
+
@provides_version = "#{project.name}-#{project.version}"
|
39
|
+
@install_dir = ""
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Tetra
|
4
|
+
# represents a prebuilt package dependency from a jar file
|
5
|
+
# in a kit
|
6
|
+
class JarKitItem
|
7
|
+
# implement to_spec
|
8
|
+
include SpecGenerator
|
9
|
+
attr_reader :project
|
10
|
+
attr_reader :package_name
|
11
|
+
attr_reader :spec_dir
|
12
|
+
attr_reader :template_spec_name
|
13
|
+
attr_reader :conflicts
|
14
|
+
|
15
|
+
# implement to_archive
|
16
|
+
include Archiver
|
17
|
+
attr_reader :source_dir
|
18
|
+
attr_reader :source_paths
|
19
|
+
attr_reader :destination_dir
|
20
|
+
|
21
|
+
# template-specific attributes
|
22
|
+
attr_reader :provides_symbol
|
23
|
+
attr_reader :provides_version
|
24
|
+
attr_reader :install_dir
|
25
|
+
|
26
|
+
def initialize(project, path)
|
27
|
+
_, name = Pathname.new(path).split
|
28
|
+
hash = Digest::SHA1.file(path).hexdigest
|
29
|
+
|
30
|
+
@project = project
|
31
|
+
@package_name = "kit-item-#{name.to_s.gsub(".", "-")}"
|
32
|
+
@spec_dir = "kit"
|
33
|
+
@template_spec_name = "kit_item.spec"
|
34
|
+
@conflicts = false
|
35
|
+
|
36
|
+
@source_dir = File.join("kit", "jars")
|
37
|
+
@source_paths = [path]
|
38
|
+
@destination_dir = @package_name
|
39
|
+
|
40
|
+
@provides_symbol = "tetra-jar(#{name})"
|
41
|
+
@provides_version = hash
|
42
|
+
@install_dir = "jars"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/tetra/kit.rb
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Tetra
|
4
|
+
# represents a set of binary dependency packages
|
5
|
+
class Kit
|
6
|
+
include Logging
|
7
|
+
|
8
|
+
def initialize(project)
|
9
|
+
@project = project
|
10
|
+
end
|
11
|
+
|
12
|
+
def items
|
13
|
+
managed_items = maven_kit_items + jar_kit_items
|
14
|
+
|
15
|
+
managed_items + glue_kit_items(managed_items)
|
16
|
+
end
|
17
|
+
|
18
|
+
def maven_kit_items
|
19
|
+
@project.from_directory(File.join("kit", "m2")) do
|
20
|
+
files_in_dir = {}
|
21
|
+
poms = []
|
22
|
+
Find.find(".") do |file|
|
23
|
+
dir = File.dirname(file)
|
24
|
+
if files_in_dir.key?(dir)
|
25
|
+
files_in_dir[dir] << file
|
26
|
+
else
|
27
|
+
files_in_dir[dir] = [file]
|
28
|
+
end
|
29
|
+
|
30
|
+
if file =~ /\.pom$/
|
31
|
+
log.debug "pom found in #{file}"
|
32
|
+
poms << file
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
poms.map do |pom|
|
37
|
+
Tetra::MavenKitItem.new(@project, pom, files_in_dir[File.dirname(pom)])
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def jar_kit_items
|
43
|
+
@project.from_directory(File.join("kit", "jars")) do
|
44
|
+
Pathname.new(".").children.select do |child|
|
45
|
+
child.to_s =~ /.jar$/
|
46
|
+
end.sort.map do |jar|
|
47
|
+
Tetra::JarKitItem.new(@project, jar)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def glue_kit_items(managed_items)
|
53
|
+
managed_files = managed_items.map do |item|
|
54
|
+
item.source_paths.map do |e|
|
55
|
+
Pathname.new(File.join(item.source_dir, e)).cleanpath
|
56
|
+
end
|
57
|
+
end.flatten
|
58
|
+
|
59
|
+
unmanaged_files = []
|
60
|
+
|
61
|
+
@project.from_directory do
|
62
|
+
Find.find("kit") do |file|
|
63
|
+
pathname = Pathname.new(file)
|
64
|
+
if !managed_files.include?(pathname) && !File.directory?(pathname)
|
65
|
+
unmanaged_files << pathname.relative_path_from(Pathname.new("kit"))
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
[Tetra::GlueKitItem.new(@project, unmanaged_files)]
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Tetra
|
4
|
+
# represents a prebuilt package dependency from a Maven local repo
|
5
|
+
# in a kit
|
6
|
+
class MavenKitItem
|
7
|
+
# implement to_spec
|
8
|
+
include SpecGenerator
|
9
|
+
attr_reader :project
|
10
|
+
attr_reader :package_name
|
11
|
+
attr_reader :spec_dir
|
12
|
+
attr_reader :template_spec_name
|
13
|
+
attr_reader :conflicts
|
14
|
+
|
15
|
+
# implement to_archive
|
16
|
+
include Archiver
|
17
|
+
attr_reader :source_dir
|
18
|
+
attr_reader :source_paths
|
19
|
+
attr_reader :destination_dir
|
20
|
+
|
21
|
+
# template-specific attributes
|
22
|
+
attr_reader :provides_symbol
|
23
|
+
attr_reader :provides_version
|
24
|
+
attr_reader :install_dir
|
25
|
+
|
26
|
+
def initialize(project, pom, source_paths)
|
27
|
+
path, _ = path_split(pom)
|
28
|
+
rest, version = path_split(path)
|
29
|
+
group_directory, artifact_id = path_split(rest)
|
30
|
+
group_id = path_to_group(group_directory)
|
31
|
+
|
32
|
+
@project = project
|
33
|
+
@package_name = "kit-item-#{group_id.gsub(".", "-")}-#{artifact_id}-#{version}"
|
34
|
+
@spec_dir = "kit"
|
35
|
+
@template_spec_name = "kit_item.spec"
|
36
|
+
@conflicts = false
|
37
|
+
|
38
|
+
@provides_symbol = "tetra-mvn(#{group_id}:#{artifact_id})"
|
39
|
+
@provides_version = version
|
40
|
+
@install_dir = "m2"
|
41
|
+
|
42
|
+
@source_dir = File.join("kit", "m2")
|
43
|
+
@source_paths = source_paths
|
44
|
+
@destination_dir = @package_name
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
# splits a path string into a [head, tail] string couple
|
50
|
+
def path_split(path)
|
51
|
+
Pathname.new(path).split.map { |e| e.to_s }
|
52
|
+
end
|
53
|
+
|
54
|
+
# transforms a path into a Maven group
|
55
|
+
def path_to_group(path)
|
56
|
+
splits = path_split(path)
|
57
|
+
if splits[0] == "."
|
58
|
+
return splits[1]
|
59
|
+
else
|
60
|
+
return "#{path_to_group(splits[0])}.#{splits[1]}"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Tetra
|
4
|
+
# represents a Java project package in Tetra, corresponding to a directory
|
5
|
+
# in src/
|
6
|
+
class Package
|
7
|
+
extend Forwardable
|
8
|
+
include SpecGenerator
|
9
|
+
|
10
|
+
attr_reader :name
|
11
|
+
|
12
|
+
def_delegator :@project, :name, :project_name
|
13
|
+
|
14
|
+
def_delegator :@kit, :items, :kit_items
|
15
|
+
|
16
|
+
def_delegator :@pom, :license_name, :license
|
17
|
+
def_delegator :@pom, :url
|
18
|
+
def_delegator :@pom, :group_id
|
19
|
+
def_delegator :@pom, :artifact_id
|
20
|
+
def_delegator :@pom, :version
|
21
|
+
def_delegator :@pom, :runtime_dependency_ids
|
22
|
+
|
23
|
+
# implement to_archive
|
24
|
+
include Archiver
|
25
|
+
attr_reader :source_dir
|
26
|
+
attr_reader :source_paths
|
27
|
+
attr_reader :destination_dir
|
28
|
+
|
29
|
+
def initialize(project, name, pom_path = nil, filter = nil)
|
30
|
+
@project = project
|
31
|
+
@kit = Tetra::Kit.new(project)
|
32
|
+
@name = name
|
33
|
+
@pom = pom_path.nil? ? nil : Tetra::Pom.new(pom_path)
|
34
|
+
@filter = filter
|
35
|
+
|
36
|
+
@source_dir = File.join("src", name)
|
37
|
+
@source_paths = ["*"]
|
38
|
+
@destination_dir = name
|
39
|
+
end
|
40
|
+
|
41
|
+
# a short summary from the POM
|
42
|
+
def summary
|
43
|
+
cleanup_description(@pom.description, 60)
|
44
|
+
end
|
45
|
+
|
46
|
+
# a long summary from the POM
|
47
|
+
def description
|
48
|
+
cleanup_description(@pom.description, 1500)
|
49
|
+
end
|
50
|
+
|
51
|
+
# files produced by this package
|
52
|
+
def outputs
|
53
|
+
@project.get_produced_files(@name).select do |file|
|
54
|
+
File.fnmatch?(@filter, File.basename(file))
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def cleanup_description(raw, max_length)
|
59
|
+
raw
|
60
|
+
.gsub(/[\s]+/, " ")
|
61
|
+
.strip
|
62
|
+
.slice(0..max_length - 1)
|
63
|
+
.sub(/\s\w+$/, "")
|
64
|
+
.sub(/\.+$/, "")
|
65
|
+
end
|
66
|
+
|
67
|
+
# needed by SpecGenerator
|
68
|
+
attr_reader :project
|
69
|
+
|
70
|
+
def package_name
|
71
|
+
name
|
72
|
+
end
|
73
|
+
|
74
|
+
def spec_dir
|
75
|
+
File.join("src", name)
|
76
|
+
end
|
77
|
+
|
78
|
+
def template_spec_name
|
79
|
+
"package.spec"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
data/lib/tetra/project.rb
CHANGED
@@ -61,19 +61,26 @@ module Tetra
|
|
61
61
|
Dir.chdir(dir) do
|
62
62
|
Tetra::Git.new(".").init
|
63
63
|
|
64
|
-
FileUtils.mkdir_p
|
65
|
-
FileUtils.mkdir_p
|
64
|
+
FileUtils.mkdir_p("src")
|
65
|
+
FileUtils.mkdir_p("kit")
|
66
66
|
|
67
67
|
# populate the project with templates and take a snapshot
|
68
68
|
project = Project.new(".")
|
69
69
|
|
70
|
-
|
71
|
-
template_manager.copy "output", "."
|
72
|
-
template_manager.copy "kit", "."
|
73
|
-
template_manager.copy "src", "."
|
74
|
-
template_manager.copy "gitignore", ".gitignore"
|
70
|
+
template_path = File.join(File.dirname(__FILE__), "..", "template")
|
75
71
|
|
76
|
-
|
72
|
+
templates = {
|
73
|
+
"output" => ".",
|
74
|
+
"kit" => ".",
|
75
|
+
"src" => ".",
|
76
|
+
"gitignore" => ".gitignore"
|
77
|
+
}
|
78
|
+
|
79
|
+
templates.each do |source, destination|
|
80
|
+
FileUtils.cp_r(File.join(template_path, source), destination)
|
81
|
+
end
|
82
|
+
|
83
|
+
project.take_snapshot("Template files added", :init)
|
77
84
|
end
|
78
85
|
end
|
79
86
|
|
@@ -83,7 +90,7 @@ module Tetra
|
|
83
90
|
def dry_run
|
84
91
|
return false if dry_running?
|
85
92
|
|
86
|
-
current_directory = Pathname.new(Dir.pwd).relative_path_from
|
93
|
+
current_directory = Pathname.new(Dir.pwd).relative_path_from(Pathname.new(@full_path))
|
87
94
|
|
88
95
|
take_snapshot("Dry-run started", :dry_run_started, current_directory)
|
89
96
|
true
|
@@ -103,11 +110,11 @@ module Tetra
|
|
103
110
|
@git.revert_whole_directory(".", latest_tag(:dry_run_started))
|
104
111
|
@git.delete_tag(latest_tag(:dry_run_started))
|
105
112
|
else
|
106
|
-
take_snapshot
|
113
|
+
take_snapshot("Changes during dry-run", :dry_run_changed)
|
107
114
|
|
108
115
|
@git.revert_whole_directory("src", latest_tag(:dry_run_started))
|
109
116
|
|
110
|
-
take_snapshot
|
117
|
+
take_snapshot("Dry run finished", :dry_run_finished)
|
111
118
|
end
|
112
119
|
return true
|
113
120
|
end
|
@@ -115,16 +122,8 @@ module Tetra
|
|
115
122
|
end
|
116
123
|
|
117
124
|
# takes a revertable snapshot of this project
|
118
|
-
def take_snapshot(message, tag_prefix
|
119
|
-
|
120
|
-
if tag_prefix
|
121
|
-
"#{tag_prefix}_#{latest_tag_count(tag_prefix) + 1}"
|
122
|
-
else
|
123
|
-
nil
|
124
|
-
end
|
125
|
-
)
|
126
|
-
|
127
|
-
@git.commit_whole_directory(message, tag, tag_message)
|
125
|
+
def take_snapshot(message, tag_prefix, tag_message = nil)
|
126
|
+
@git.commit_whole_directory(message, next_tag(tag_prefix), tag_message)
|
128
127
|
end
|
129
128
|
|
130
129
|
# replaces content in path with new_content, takes a snapshot using
|
@@ -144,7 +143,7 @@ module Tetra
|
|
144
143
|
|
145
144
|
File.open(path, "w") { |io| io.write(new_content) }
|
146
145
|
log.debug "taking snapshot with new content: #{snapshot_message}"
|
147
|
-
|
146
|
+
@git.commit_file(path, snapshot_message, next_tag(tag_prefix))
|
148
147
|
|
149
148
|
if already_existing
|
150
149
|
if previous_tag == ""
|
@@ -172,6 +171,11 @@ module Tetra
|
|
172
171
|
@git.get_tag_maximum_suffix(prefix)
|
173
172
|
end
|
174
173
|
|
174
|
+
# returns the next tag for a given tag prefix
|
175
|
+
def next_tag(prefix)
|
176
|
+
"#{prefix}_#{latest_tag_count(prefix) + 1}"
|
177
|
+
end
|
178
|
+
|
175
179
|
# runs a block from the project directory or a subdirectory
|
176
180
|
def from_directory(subdirectory = "")
|
177
181
|
Dir.chdir(File.join(@full_path, subdirectory)) do
|