tetra 0.40.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.
Files changed (92) hide show
  1. data/.gitignore +27 -0
  2. data/.rubocop.yml +14 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE +28 -0
  5. data/MOTIVATION.md +27 -0
  6. data/README.md +106 -0
  7. data/Rakefile +9 -0
  8. data/SPECIAL_CASES.md +130 -0
  9. data/bin/tetra +29 -0
  10. data/integration-tests/commons.sh +55 -0
  11. data/lib/template/gitignore +2 -0
  12. data/lib/template/kit.spec +64 -0
  13. data/lib/template/kit/CONTENTS +8 -0
  14. data/lib/template/kit/jars/CONTENTS +1 -0
  15. data/lib/template/kit/m2/settings.xml +10 -0
  16. data/lib/template/output/CONTENTS +3 -0
  17. data/lib/template/package.spec +65 -0
  18. data/lib/template/src/CONTENTS +6 -0
  19. data/lib/tetra.rb +63 -0
  20. data/lib/tetra/ant_runner.rb +27 -0
  21. data/lib/tetra/archiver.rb +95 -0
  22. data/lib/tetra/commands/ant.rb +23 -0
  23. data/lib/tetra/commands/base.rb +89 -0
  24. data/lib/tetra/commands/download_maven_source_jars.rb +29 -0
  25. data/lib/tetra/commands/dry_run.rb +17 -0
  26. data/lib/tetra/commands/finish.rb +22 -0
  27. data/lib/tetra/commands/generate_all.rb +38 -0
  28. data/lib/tetra/commands/generate_kit_archive.rb +18 -0
  29. data/lib/tetra/commands/generate_kit_spec.rb +16 -0
  30. data/lib/tetra/commands/generate_package_archive.rb +19 -0
  31. data/lib/tetra/commands/generate_package_script.rb +21 -0
  32. data/lib/tetra/commands/generate_package_spec.rb +22 -0
  33. data/lib/tetra/commands/get_pom.rb +33 -0
  34. data/lib/tetra/commands/get_source.rb +30 -0
  35. data/lib/tetra/commands/init.rb +15 -0
  36. data/lib/tetra/commands/list_kit_missing_sources.rb +21 -0
  37. data/lib/tetra/commands/move_jars_to_kit.rb +18 -0
  38. data/lib/tetra/commands/mvn.rb +23 -0
  39. data/lib/tetra/git.rb +140 -0
  40. data/lib/tetra/kit_checker.rb +104 -0
  41. data/lib/tetra/kit_runner.rb +43 -0
  42. data/lib/tetra/kit_spec_adapter.rb +28 -0
  43. data/lib/tetra/logger.rb +28 -0
  44. data/lib/tetra/main.rb +102 -0
  45. data/lib/tetra/maven_runner.rb +47 -0
  46. data/lib/tetra/maven_website.rb +59 -0
  47. data/lib/tetra/package_spec_adapter.rb +59 -0
  48. data/lib/tetra/pom.rb +55 -0
  49. data/lib/tetra/pom_getter.rb +104 -0
  50. data/lib/tetra/project.rb +245 -0
  51. data/lib/tetra/script_generator.rb +57 -0
  52. data/lib/tetra/source_getter.rb +41 -0
  53. data/lib/tetra/spec_generator.rb +60 -0
  54. data/lib/tetra/template_manager.rb +33 -0
  55. data/lib/tetra/version.rb +6 -0
  56. data/lib/tetra/version_matcher.rb +90 -0
  57. data/spec/data/ant-super-simple-code/build.xml +133 -0
  58. data/spec/data/ant-super-simple-code/build/HW.class +0 -0
  59. data/spec/data/ant-super-simple-code/build/mypackage/HW.class +0 -0
  60. data/spec/data/ant-super-simple-code/dist/antsimple-20130618.jar +0 -0
  61. data/spec/data/ant-super-simple-code/lib/junit-4.11.jar +0 -0
  62. data/spec/data/ant-super-simple-code/lib/log4j-1.2.13.jar +0 -0
  63. data/spec/data/ant-super-simple-code/src/mypackage/HW.java +15 -0
  64. data/spec/data/antlr/antlr-2.7.2.jar +0 -0
  65. data/spec/data/antlr/pom.xml +6 -0
  66. data/spec/data/commons-logging/commons-logging-1.1.1.jar +0 -0
  67. data/spec/data/commons-logging/parent_pom.xml +420 -0
  68. data/spec/data/commons-logging/pom.xml +504 -0
  69. data/spec/data/nailgun/nailgun-0.7.1.jar +0 -0
  70. data/spec/data/nailgun/pom.xml +153 -0
  71. data/spec/data/struts-apps/pom.xml +228 -0
  72. data/spec/data/tomcat/pom.xml +33 -0
  73. data/spec/lib/ant_runner_spec.rb +45 -0
  74. data/spec/lib/archiver_spec.rb +106 -0
  75. data/spec/lib/git_spec.rb +105 -0
  76. data/spec/lib/kit_checker_spec.rb +119 -0
  77. data/spec/lib/maven_runner_spec.rb +68 -0
  78. data/spec/lib/maven_website_spec.rb +56 -0
  79. data/spec/lib/pom_getter_spec.rb +36 -0
  80. data/spec/lib/pom_spec.rb +69 -0
  81. data/spec/lib/project_spec.rb +254 -0
  82. data/spec/lib/script_generator_spec.rb +67 -0
  83. data/spec/lib/source_getter_spec.rb +36 -0
  84. data/spec/lib/spec_generator_spec.rb +130 -0
  85. data/spec/lib/template_manager_spec.rb +54 -0
  86. data/spec/lib/version_matcher_spec.rb +64 -0
  87. data/spec/spec_helper.rb +37 -0
  88. data/spec/support/kit_runner_examples.rb +15 -0
  89. data/tetra.gemspec +31 -0
  90. data/utils/delete_nonet_user.sh +8 -0
  91. data/utils/setup_nonet_user.sh +8 -0
  92. metadata +267 -0
@@ -0,0 +1,36 @@
1
+ # encoding: UTF-8
2
+
3
+ require "spec_helper"
4
+
5
+ describe Tetra::PomGetter do
6
+ let(:pom_getter) { Tetra::PomGetter.new }
7
+
8
+ describe "#get_pom" do
9
+ it "gets the pom from a jar" do
10
+ dir_path = File.join("spec", "data", "commons-logging")
11
+ jar_path = File.join(dir_path, "commons-logging-1.1.1.jar")
12
+ path, status = pom_getter.get_pom(jar_path)
13
+ expect(status).to eq :found_in_jar
14
+ expect(File.exist?(path)).to be_truthy
15
+ FileUtils.rm(path)
16
+ end
17
+
18
+ it "gets the pom from sha1" do
19
+ dir_path = File.join("spec", "data", "antlr")
20
+ jar_path = File.join(dir_path, "antlr-2.7.2.jar")
21
+ path, status = pom_getter.get_pom(jar_path)
22
+ expect(status).to eq :found_via_sha1
23
+ expect(File.exist?(path)).to be_truthy
24
+ FileUtils.rm(path)
25
+ end
26
+
27
+ it "gets the pom from a heuristic" do
28
+ dir_path = File.join("spec", "data", "nailgun")
29
+ jar_path = File.join(dir_path, "nailgun-0.7.1.jar")
30
+ path, status = pom_getter.get_pom(jar_path)
31
+ expect(status).to eq :found_via_heuristic
32
+ expect(File.exist?(path)).to be_truthy
33
+ FileUtils.rm(path)
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,69 @@
1
+ # encoding: UTF-8
2
+
3
+ require "spec_helper"
4
+
5
+ describe Tetra::Pom do
6
+ let(:pom) { Tetra::Pom.new(File.join("spec", "data", "commons-logging", "pom.xml")) }
7
+
8
+ describe "#group_id" do
9
+ it "reads the group id" do
10
+ expect(pom.group_id).to eq "commons-logging"
11
+ end
12
+ end
13
+
14
+ describe "#artifact_id" do
15
+ it "reads the artifact id" do
16
+ expect(pom.artifact_id).to eq "commons-logging"
17
+ end
18
+ end
19
+
20
+ describe "#name" do
21
+ it "reads artifact name" do
22
+ expect(pom.name).to eq "Commons Logging"
23
+ end
24
+ end
25
+
26
+ describe "#version" do
27
+ it "reads the version" do
28
+ expect(pom.version).to eq "1.1.1"
29
+ end
30
+ end
31
+
32
+ describe "#description" do
33
+ it "reads the description" do
34
+ expect(pom.description).to eq "Commons Logging is a thin adapter allowing configurable bridging to other,\n " \
35
+ "well known logging systems."
36
+ end
37
+ end
38
+
39
+ describe "#url" do
40
+ it "reads the url" do
41
+ expect(pom.url).to eq "http://commons.apache.org/logging"
42
+ end
43
+ end
44
+
45
+ describe "#license_name" do
46
+ it "reads the license name" do
47
+ expect(pom.license_name).to eq ""
48
+ end
49
+ end
50
+
51
+ describe "#runtime_dependency_ids" do
52
+ it "reads the dependency maven ids" do
53
+ expect(pom.runtime_dependency_ids).to eq []
54
+ end
55
+ end
56
+
57
+ describe "#scm_connection" do
58
+ it "reads the SCM connection address" do
59
+ expect(pom.scm_connection).to eq "scm:svn:http://svn.apache.org/repos/asf/commons/proper/" \
60
+ "logging/tags/commons-logging-1.1.1"
61
+ end
62
+ end
63
+
64
+ describe "#scm_url" do
65
+ it "reads the SCM connection url" do
66
+ expect(pom.scm_url).to eq "http://svn.apache.org/repos/asf/commons/proper/logging/tags/commons-logging-1.1.1"
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,254 @@
1
+ # encoding: UTF-8
2
+
3
+ require "spec_helper"
4
+
5
+ describe Tetra::Project do
6
+ before(:each) do
7
+ @project_path = File.join("spec", "data", "test-project")
8
+ Dir.mkdir(@project_path)
9
+
10
+ Tetra::Project.init(@project_path)
11
+ @project = Tetra::Project.new(@project_path)
12
+ end
13
+
14
+ after(:each) do
15
+ FileUtils.rm_rf(@project_path)
16
+ end
17
+
18
+ describe "#project?" do
19
+ it "checks if a directory is a tetra project or not" do
20
+ expect(Tetra::Project.project?(@project_path)).to be_truthy
21
+ expect(Tetra::Project.project?(File.join(@project_path, ".."))).to be_falsey
22
+ end
23
+ end
24
+
25
+ describe "#find_project_dir" do
26
+ it "recursively the parent project directory" do
27
+ expanded_path = File.expand_path(@project_path)
28
+ expect(Tetra::Project.find_project_dir(expanded_path)).to eq expanded_path
29
+ expect(Tetra::Project.find_project_dir(File.expand_path("src", @project_path))).to eq expanded_path
30
+ expect(Tetra::Project.find_project_dir(File.expand_path("kit", @project_path))).to eq expanded_path
31
+
32
+ expect do
33
+ expect(Tetra::Project.find_project_dir(File.expand_path("..", @project_path))).to raise_error
34
+ end.to raise_error(Tetra::NoProjectDirectoryError)
35
+ end
36
+ end
37
+
38
+ describe ".get_package_name" do
39
+ it "raises an error with a directory outside a tetra project" do
40
+ expect do
41
+ @project.get_package_name("/")
42
+ end.to raise_error(Tetra::NoPackageDirectoryError)
43
+ end
44
+
45
+ it "raises an error with a tetra project directory" do
46
+ expect do
47
+ @project.get_package_name(@project_path)
48
+ end.to raise_error(Tetra::NoPackageDirectoryError)
49
+ end
50
+
51
+ it "raises an error with a tetra kit directory" do
52
+ expect do
53
+ @project.get_package_name(File.join(@project_path, "kit"))
54
+ end.to raise_error(Tetra::NoPackageDirectoryError)
55
+ end
56
+
57
+ it "raises an error with a tetra src directory" do
58
+ expect do
59
+ @project.get_package_name(File.join(@project_path, "src"))
60
+ end.to raise_error(Tetra::NoPackageDirectoryError)
61
+ end
62
+
63
+ it "raises an error with a nonexisting package directory" do
64
+ expect do
65
+ @project.get_package_name(File.join(@project_path, "src", "test_package"))
66
+ end.to raise_error(Tetra::NoPackageDirectoryError)
67
+ end
68
+
69
+ it "returns the package on an existing package directory" do
70
+ FileUtils.mkdir_p(File.join(@project_path, "src", "test_package"))
71
+ expect(@project.get_package_name(File.join(@project_path, "src", "test_package"))).to eq "test_package"
72
+ end
73
+
74
+ it "returns the package on an existing package subdirectory" do
75
+ FileUtils.mkdir_p(File.join(@project_path, "src", "test_package", "subdir1"))
76
+ expect(@project.get_package_name(File.join(@project_path, "src", "test_package", "subdir1"))).to eq "test_package"
77
+ end
78
+
79
+ it "returns the package on an existing package subsubdirectory" do
80
+ FileUtils.mkdir_p(File.join(@project_path, "src", "test_package", "subdir1", "subdir2"))
81
+ expect(@project.get_package_name(File.join(@project_path, "src", "test_package", "subdir1", "subdir2")))
82
+ .to eq "test_package"
83
+ end
84
+ end
85
+
86
+ describe "full_path" do
87
+ it "returns the project's full path" do
88
+ expect(@project.full_path).to eq File.expand_path(@project_path)
89
+ end
90
+ end
91
+
92
+ describe "#init" do
93
+ it "inits a new project" do
94
+ kit_path = File.join(@project_path, "kit")
95
+ expect(Dir.exist?(kit_path)).to be_truthy
96
+
97
+ src_path = File.join(@project_path, "src")
98
+ expect(Dir.exist?(src_path)).to be_truthy
99
+ end
100
+ end
101
+
102
+ describe "#dry_running?" do
103
+ it "checks if a project is dry running" do
104
+ @project.from_directory do
105
+ expect(@project.dry_running?).to be_falsey
106
+ @project.dry_run
107
+ expect(@project.dry_running?).to be_truthy
108
+ @project.finish(false)
109
+ expect(@project.dry_running?).to be_falsey
110
+ end
111
+ end
112
+ end
113
+
114
+ describe "#take_snapshot" do
115
+ it "commits the project contents to git for later use" do
116
+ @project.from_directory do
117
+ `touch kit/test`
118
+
119
+ @project.take_snapshot "test", :revertable
120
+
121
+ expect(`git rev-list --all`.split("\n").length).to eq 2
122
+ expect(@project.latest_tag(:revertable)).to eq "revertable_1"
123
+ end
124
+ end
125
+ end
126
+
127
+ describe "#finish" do
128
+ it "ends the current dry-run phase after a successful build" do
129
+ @project.from_directory do
130
+ Dir.mkdir("src/abc")
131
+ `echo A > src/abc/test`
132
+ end
133
+
134
+ expect(@project.finish(true)).to be_falsey
135
+ expect(@project.finish(false)).to be_falsey
136
+
137
+ expect(@project.dry_run).to be_truthy
138
+
139
+ @project.from_directory do
140
+ `echo B > src/abc/test`
141
+ `touch src/abc/test2`
142
+ end
143
+
144
+ expect(@project.finish(false)).to be_truthy
145
+ expect(@project.dry_running?).to be_falsey
146
+
147
+ @project.from_directory do
148
+ expect(`git rev-list --all`.split("\n").length).to eq 4
149
+ expect(File.read("src/abc/test")).to eq "A\n"
150
+
151
+ expect(`git diff-tree --no-commit-id --name-only -r HEAD~`.split("\n")).to include("src/abc/test2")
152
+ expect(File.exist?("src/abc/test2")).to be_falsey
153
+ end
154
+ end
155
+ it "ends the current dry-run phase after a failed build" do
156
+ @project.from_directory do
157
+ Dir.mkdir("src/abc")
158
+ `echo A > src/abc/test`
159
+ `echo A > kit/test`
160
+ end
161
+
162
+ expect(@project.finish(true)).to be_falsey
163
+ expect(@project.finish(false)).to be_falsey
164
+
165
+ expect(@project.dry_run).to be_truthy
166
+
167
+ @project.from_directory do
168
+ `echo B > src/abc/test`
169
+ `touch src/abc/test2`
170
+ `echo B > kit/test`
171
+ `touch kit/test2`
172
+ end
173
+
174
+ expect(@project.finish(true)).to be_truthy
175
+ expect(@project.dry_running?).to be_falsey
176
+
177
+ @project.from_directory do
178
+ expect(`git rev-list --all`.split("\n").length).to eq 2
179
+ expect(File.read("src/abc/test")).to eq "A\n"
180
+ expect(File.exist?("src/abc/test2")).to be_falsey
181
+
182
+ expect(File.read("kit/test")).to eq "A\n"
183
+ expect(File.exist?("kit/test2")).to be_falsey
184
+ end
185
+ end
186
+ end
187
+
188
+ describe "#dry_run" do
189
+ it "starts a dry running phase" do
190
+ expect(@project.finish(false)).to be_falsey
191
+
192
+ @project.from_directory do
193
+ `touch src/test`
194
+ end
195
+
196
+ @project.from_directory("src") do
197
+ expect(@project.dry_run).to be_truthy
198
+ end
199
+
200
+ @project.from_directory do
201
+ expect(@project.dry_running?).to be_truthy
202
+ expect(`git rev-list --all`.split("\n").length).to eq 2
203
+ expect(`git diff-tree --no-commit-id --name-only -r HEAD`.split("\n")).to include("src/test")
204
+ expect(`git cat-file tag tetra_dry_run_started_1 | tail -1`).to include("src")
205
+ end
206
+ end
207
+ end
208
+
209
+ describe "#get_produced_files" do
210
+ it "gets a list of produced files" do
211
+ @project.from_directory do
212
+ Dir.mkdir("src/abc")
213
+ `echo A > src/abc/added_outside_dry_run`
214
+ end
215
+
216
+ expect(@project.dry_run).to be_truthy
217
+ @project.from_directory do
218
+ `echo A > src/abc/added_in_first_dry_run`
219
+ `echo A > src/added_outside_directory`
220
+ end
221
+ expect(@project.finish(false)).to be_truthy
222
+
223
+ expect(@project.dry_run).to be_truthy
224
+ @project.from_directory do
225
+ `echo A > src/abc/added_in_second_dry_run`
226
+ end
227
+ expect(@project.finish(false)).to be_truthy
228
+
229
+ list = @project.get_produced_files("abc")
230
+ expect(list).to include("added_in_first_dry_run")
231
+ expect(list).to include("added_in_second_dry_run")
232
+
233
+ expect(list).not_to include("added_outside_dry_run")
234
+ expect(list).not_to include("added_outside_directory")
235
+ end
236
+ end
237
+
238
+ describe "#purge_jars" do
239
+ it "moves jars in kit/jars" do
240
+ @project.from_directory do
241
+ `echo "jarring" > src/test.jar`
242
+ end
243
+ expect(@project.finish(false)).to be_falsey
244
+
245
+ @project.purge_jars
246
+
247
+ @project.from_directory do
248
+ expect(File.symlink?(File.join("src", "test.jar"))).to be_truthy
249
+ expect(File.readlink(File.join("src", "test.jar"))).to eq "../kit/jars/test.jar"
250
+ expect(File.readlines(File.join("kit", "jars", "test.jar"))).to include("jarring\n")
251
+ end
252
+ end
253
+ end
254
+ end
@@ -0,0 +1,67 @@
1
+ # encoding: UTF-8
2
+
3
+ require "spec_helper"
4
+
5
+ describe Tetra::ScriptGenerator do
6
+ before(:each) do
7
+ @project_path = File.join("spec", "data", "test-project")
8
+ Dir.mkdir(@project_path)
9
+
10
+ Tetra::Project.init(@project_path)
11
+ @project = Tetra::Project.new(@project_path)
12
+
13
+ @project.from_directory do
14
+ File.open("history", "w") do |io|
15
+ io.puts "some earlier command"
16
+ io.puts "tetra dry-run --unwanted-options"
17
+ io.puts "cd somewhere significant"
18
+ io.puts "tetra mvn --options"
19
+ io.puts "tetra finish -a"
20
+ io.puts "some later command"
21
+ end
22
+
23
+ FileUtils.mkdir_p(File.join("src", "test-package"))
24
+ @project.dry_run
25
+
26
+ @generator = Tetra::ScriptGenerator.new(@project, "history")
27
+ end
28
+
29
+ mock_maven_executable
30
+ end
31
+
32
+ after(:each) do
33
+ FileUtils.rm_rf(@project_path)
34
+ end
35
+
36
+ describe "#generate_build_script" do
37
+ it "generates a build script from the history" do
38
+ @project.from_directory do
39
+ @generator.generate_build_script("test-package")
40
+
41
+ lines = File.readlines(File.join("src", "test-package", "build.sh"))
42
+
43
+ expect(lines).to include("#!/bin/bash\n")
44
+ expect(lines).to include("cd somewhere significant\n")
45
+ expect(lines).to include("$PROJECT_PREFIX/kit/mvn/bin/mvn -Dmaven.repo.local=$PROJECT_PREFIX/kit/m2 " \
46
+ "-s$PROJECT_PREFIX/kit/m2/settings.xml -o --options\n"
47
+ )
48
+
49
+ expect(lines).not_to include("some earlier command\n")
50
+ expect(lines).not_to include("tetra dry-run --unwanted-options\n")
51
+ expect(lines).not_to include("tetra dry-run --unwanted-options\n")
52
+ expect(lines).not_to include("tetra finish -a\n")
53
+ expect(lines).not_to include("some later command\n")
54
+ end
55
+ end
56
+ end
57
+
58
+ def mock_maven_executable
59
+ Dir.chdir(@project_path) do
60
+ @bin_dir = File.join("kit", "mvn", "bin")
61
+ FileUtils.mkdir_p(@bin_dir)
62
+ @maven_executable = File.join(@bin_dir, "mvn")
63
+ File.open(@maven_executable, "w") { |io| io.puts "echo $0 $*>test_out" }
64
+ File.chmod(0777, @maven_executable)
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,36 @@
1
+ # encoding: UTF-8
2
+
3
+ require "spec_helper"
4
+ require "fileutils"
5
+
6
+ describe Tetra::SourceGetter do
7
+ include Tetra::Mockers
8
+ let(:source_getter) { Tetra::SourceGetter.new }
9
+
10
+ before(:each) do
11
+ create_mock_project
12
+ end
13
+
14
+ after(:each) do
15
+ delete_mock_project
16
+ end
17
+
18
+ describe "#get_maven_source_jars" do
19
+ it "gets sources for jars in the Maven repo through Maven itself" do
20
+ create_mock_executable("mvn")
21
+
22
+ @project.from_directory(File.join("kit", "m2")) do
23
+ jar_dir_path = File.join("net", "test", "artifact", "1.0")
24
+ jar_path = File.join(jar_dir_path, "artifact-1.0-blabla.jar")
25
+ FileUtils.mkdir_p(jar_dir_path)
26
+ FileUtils.touch(jar_path)
27
+
28
+ successes, failures = source_getter.get_maven_source_jars(@project)
29
+ commandline = File.read(File.join("..", "..", "test_out")).strip
30
+ expect(commandline).to match(/-Dartifact=net.test:artifact:1.0:jar:sources -Dtransitive=false$/)
31
+ expect(successes).to include File.join(".", "kit", "m2", jar_path)
32
+ expect(failures).to eq []
33
+ end
34
+ end
35
+ end
36
+ end