tetra 0.40.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +27 -0
- data/.rubocop.yml +14 -0
- data/Gemfile +4 -0
- data/LICENSE +28 -0
- data/MOTIVATION.md +27 -0
- data/README.md +106 -0
- data/Rakefile +9 -0
- data/SPECIAL_CASES.md +130 -0
- data/bin/tetra +29 -0
- data/integration-tests/commons.sh +55 -0
- data/lib/template/gitignore +2 -0
- data/lib/template/kit.spec +64 -0
- data/lib/template/kit/CONTENTS +8 -0
- data/lib/template/kit/jars/CONTENTS +1 -0
- data/lib/template/kit/m2/settings.xml +10 -0
- data/lib/template/output/CONTENTS +3 -0
- data/lib/template/package.spec +65 -0
- data/lib/template/src/CONTENTS +6 -0
- data/lib/tetra.rb +63 -0
- data/lib/tetra/ant_runner.rb +27 -0
- data/lib/tetra/archiver.rb +95 -0
- data/lib/tetra/commands/ant.rb +23 -0
- data/lib/tetra/commands/base.rb +89 -0
- data/lib/tetra/commands/download_maven_source_jars.rb +29 -0
- data/lib/tetra/commands/dry_run.rb +17 -0
- data/lib/tetra/commands/finish.rb +22 -0
- data/lib/tetra/commands/generate_all.rb +38 -0
- data/lib/tetra/commands/generate_kit_archive.rb +18 -0
- data/lib/tetra/commands/generate_kit_spec.rb +16 -0
- data/lib/tetra/commands/generate_package_archive.rb +19 -0
- data/lib/tetra/commands/generate_package_script.rb +21 -0
- data/lib/tetra/commands/generate_package_spec.rb +22 -0
- data/lib/tetra/commands/get_pom.rb +33 -0
- data/lib/tetra/commands/get_source.rb +30 -0
- data/lib/tetra/commands/init.rb +15 -0
- data/lib/tetra/commands/list_kit_missing_sources.rb +21 -0
- data/lib/tetra/commands/move_jars_to_kit.rb +18 -0
- data/lib/tetra/commands/mvn.rb +23 -0
- data/lib/tetra/git.rb +140 -0
- data/lib/tetra/kit_checker.rb +104 -0
- data/lib/tetra/kit_runner.rb +43 -0
- data/lib/tetra/kit_spec_adapter.rb +28 -0
- data/lib/tetra/logger.rb +28 -0
- data/lib/tetra/main.rb +102 -0
- data/lib/tetra/maven_runner.rb +47 -0
- data/lib/tetra/maven_website.rb +59 -0
- data/lib/tetra/package_spec_adapter.rb +59 -0
- data/lib/tetra/pom.rb +55 -0
- data/lib/tetra/pom_getter.rb +104 -0
- data/lib/tetra/project.rb +245 -0
- data/lib/tetra/script_generator.rb +57 -0
- data/lib/tetra/source_getter.rb +41 -0
- data/lib/tetra/spec_generator.rb +60 -0
- data/lib/tetra/template_manager.rb +33 -0
- data/lib/tetra/version.rb +6 -0
- data/lib/tetra/version_matcher.rb +90 -0
- data/spec/data/ant-super-simple-code/build.xml +133 -0
- data/spec/data/ant-super-simple-code/build/HW.class +0 -0
- data/spec/data/ant-super-simple-code/build/mypackage/HW.class +0 -0
- data/spec/data/ant-super-simple-code/dist/antsimple-20130618.jar +0 -0
- data/spec/data/ant-super-simple-code/lib/junit-4.11.jar +0 -0
- data/spec/data/ant-super-simple-code/lib/log4j-1.2.13.jar +0 -0
- data/spec/data/ant-super-simple-code/src/mypackage/HW.java +15 -0
- data/spec/data/antlr/antlr-2.7.2.jar +0 -0
- data/spec/data/antlr/pom.xml +6 -0
- data/spec/data/commons-logging/commons-logging-1.1.1.jar +0 -0
- data/spec/data/commons-logging/parent_pom.xml +420 -0
- data/spec/data/commons-logging/pom.xml +504 -0
- data/spec/data/nailgun/nailgun-0.7.1.jar +0 -0
- data/spec/data/nailgun/pom.xml +153 -0
- data/spec/data/struts-apps/pom.xml +228 -0
- data/spec/data/tomcat/pom.xml +33 -0
- data/spec/lib/ant_runner_spec.rb +45 -0
- data/spec/lib/archiver_spec.rb +106 -0
- data/spec/lib/git_spec.rb +105 -0
- data/spec/lib/kit_checker_spec.rb +119 -0
- data/spec/lib/maven_runner_spec.rb +68 -0
- data/spec/lib/maven_website_spec.rb +56 -0
- data/spec/lib/pom_getter_spec.rb +36 -0
- data/spec/lib/pom_spec.rb +69 -0
- data/spec/lib/project_spec.rb +254 -0
- data/spec/lib/script_generator_spec.rb +67 -0
- data/spec/lib/source_getter_spec.rb +36 -0
- data/spec/lib/spec_generator_spec.rb +130 -0
- data/spec/lib/template_manager_spec.rb +54 -0
- data/spec/lib/version_matcher_spec.rb +64 -0
- data/spec/spec_helper.rb +37 -0
- data/spec/support/kit_runner_examples.rb +15 -0
- data/tetra.gemspec +31 -0
- data/utils/delete_nonet_user.sh +8 -0
- data/utils/setup_nonet_user.sh +8 -0
- metadata +267 -0
data/lib/tetra/pom.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Tetra
|
4
|
+
# encapsulates a pom.xml file
|
5
|
+
class Pom
|
6
|
+
def initialize(filename)
|
7
|
+
@doc = Nokogiri::XML(open(filename).read)
|
8
|
+
@doc.remove_namespaces!
|
9
|
+
end
|
10
|
+
|
11
|
+
def group_id
|
12
|
+
@doc.xpath("project/groupId").text || ""
|
13
|
+
end
|
14
|
+
|
15
|
+
def artifact_id
|
16
|
+
@doc.xpath("project/artifactId").text || ""
|
17
|
+
end
|
18
|
+
|
19
|
+
def name
|
20
|
+
@doc.xpath("project/name").text || ""
|
21
|
+
end
|
22
|
+
|
23
|
+
def version
|
24
|
+
@doc.xpath("project/version").text || ""
|
25
|
+
end
|
26
|
+
|
27
|
+
def description
|
28
|
+
@doc.xpath("project/description").text || ""
|
29
|
+
end
|
30
|
+
|
31
|
+
def url
|
32
|
+
@doc.xpath("project/url").text || ""
|
33
|
+
end
|
34
|
+
|
35
|
+
def license_name
|
36
|
+
@doc.xpath("project/licenses/license/name").text || ""
|
37
|
+
end
|
38
|
+
|
39
|
+
def runtime_dependency_ids
|
40
|
+
@doc.xpath("project/dependencies/dependency[\
|
41
|
+
not(optional='true') and not(scope='provided') and not(scope='test') and not(scope='system')\
|
42
|
+
]").map do |element|
|
43
|
+
[element.xpath("groupId").text, element.xpath("artifactId").text, element.xpath("version").text]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def scm_connection
|
48
|
+
@doc.xpath("project/scm/connection").text || ""
|
49
|
+
end
|
50
|
+
|
51
|
+
def scm_url
|
52
|
+
@doc.xpath("project/scm/url").text || ""
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Tetra
|
4
|
+
# attempts to get java projects' pom file
|
5
|
+
class PomGetter
|
6
|
+
include Logging
|
7
|
+
|
8
|
+
# saves a jar poms in <jar_filename>.pom
|
9
|
+
# returns filename and status if found, else nil
|
10
|
+
def get_pom(filename)
|
11
|
+
content, status = (get_pom_from_jar(filename) || get_pom_from_sha1(filename) || get_pom_from_heuristic(filename))
|
12
|
+
return unless content
|
13
|
+
|
14
|
+
pom_filename = filename.sub(/(\.jar)?$/, ".pom")
|
15
|
+
File.open(pom_filename, "w") { |io| io.write(content) }
|
16
|
+
[pom_filename, status]
|
17
|
+
end
|
18
|
+
|
19
|
+
# returns a pom embedded in a jar file
|
20
|
+
def get_pom_from_jar(file)
|
21
|
+
log.debug("Attempting unpack of #{file} to find a POM")
|
22
|
+
begin
|
23
|
+
Zip::File.foreach(file) do |entry|
|
24
|
+
if entry.name =~ /\/pom.xml$/
|
25
|
+
log.info("pom.xml found in #{file}##{entry.name}")
|
26
|
+
return entry.get_input_stream.read, :found_in_jar
|
27
|
+
end
|
28
|
+
end
|
29
|
+
rescue Zip::Error
|
30
|
+
log.warn("#{file} does not seem to be a valid jar archive, skipping")
|
31
|
+
rescue TypeError
|
32
|
+
log.warn("#{file} seems to be a valid jar archive but is corrupt, skipping")
|
33
|
+
end
|
34
|
+
nil
|
35
|
+
end
|
36
|
+
|
37
|
+
# returns a pom from search.maven.org with a jar sha1 search
|
38
|
+
def get_pom_from_sha1(file)
|
39
|
+
log.debug("Attempting SHA1 POM lookup for #{file}")
|
40
|
+
begin
|
41
|
+
if File.file?(file)
|
42
|
+
site = MavenWebsite.new
|
43
|
+
sha1 = Digest::SHA1.hexdigest File.read(file)
|
44
|
+
results = site.search_by_sha1(sha1).select { |result| result["ec"].include?(".pom") }
|
45
|
+
result = results.first
|
46
|
+
unless result.nil?
|
47
|
+
log.info("pom.xml for #{file} found on search.maven.org for sha1 #{sha1}\
|
48
|
+
(#{result["g"]}:#{result["a"]}:#{result["v"]})"
|
49
|
+
)
|
50
|
+
group_id, artifact_id, version = site.get_maven_id_from result
|
51
|
+
return site.download_pom(group_id, artifact_id, version), :found_via_sha1
|
52
|
+
end
|
53
|
+
end
|
54
|
+
rescue RestClient::ResourceNotFound
|
55
|
+
log.warn("Got a 404 error while looking for #{file}'s SHA1 in search.maven.org")
|
56
|
+
end
|
57
|
+
nil
|
58
|
+
end
|
59
|
+
|
60
|
+
# returns a pom from search.maven.org with a heuristic name search
|
61
|
+
def get_pom_from_heuristic(filename)
|
62
|
+
begin
|
63
|
+
log.debug("Attempting heuristic POM search for #{filename}")
|
64
|
+
site = MavenWebsite.new
|
65
|
+
filename = cleanup_name(filename)
|
66
|
+
version_matcher = VersionMatcher.new
|
67
|
+
my_artifact_id, my_version = version_matcher.split_version(filename)
|
68
|
+
log.debug("Guessed artifact id: #{my_artifact_id}, version: #{my_version}")
|
69
|
+
|
70
|
+
result = site.search_by_name(my_artifact_id).first
|
71
|
+
log.debug("Artifact id search result: #{result}")
|
72
|
+
unless result.nil?
|
73
|
+
group_id, artifact_id, _ = site.get_maven_id_from result
|
74
|
+
results = site.search_by_group_id_and_artifact_id(group_id, artifact_id)
|
75
|
+
log.debug("All versions: #{results}")
|
76
|
+
their_versions = results.map { |doc| doc["v"] }
|
77
|
+
best_matched_version = (
|
78
|
+
if !my_version.nil?
|
79
|
+
version_matcher.best_match(my_version, their_versions)
|
80
|
+
else
|
81
|
+
their_versions.max
|
82
|
+
end
|
83
|
+
)
|
84
|
+
best_matched_result = (results.select { |r| r["v"] == best_matched_version }).first
|
85
|
+
|
86
|
+
group_id, artifact_id, version = site.get_maven_id_from(best_matched_result)
|
87
|
+
log.warn("pom.xml for #{filename} found on search.maven.org with heuristic search\
|
88
|
+
(#{group_id}:#{artifact_id}:#{version})"
|
89
|
+
)
|
90
|
+
|
91
|
+
return site.download_pom(group_id, artifact_id, version), :found_via_heuristic
|
92
|
+
end
|
93
|
+
rescue RestClient::ResourceNotFound
|
94
|
+
log.warn("Got a 404 error while looking for #{filename} heuristically in search.maven.org")
|
95
|
+
end
|
96
|
+
nil
|
97
|
+
end
|
98
|
+
|
99
|
+
# get a heuristic name from a path
|
100
|
+
def cleanup_name(path)
|
101
|
+
Pathname.new(path).basename.to_s.sub(/.jar$/, "")
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,245 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Tetra
|
4
|
+
# encapsulates a Tetra project directory
|
5
|
+
class Project
|
6
|
+
include Logging
|
7
|
+
|
8
|
+
attr_accessor :full_path
|
9
|
+
attr_accessor :git
|
10
|
+
|
11
|
+
def initialize(path)
|
12
|
+
@full_path = Tetra::Project.find_project_dir(File.expand_path(path))
|
13
|
+
@git = Tetra::Git.new(@full_path)
|
14
|
+
end
|
15
|
+
|
16
|
+
def name
|
17
|
+
File.basename(@full_path)
|
18
|
+
end
|
19
|
+
|
20
|
+
def version
|
21
|
+
latest_tag_count(:dry_run_finished)
|
22
|
+
end
|
23
|
+
|
24
|
+
# finds the project directory up in the tree, like git does
|
25
|
+
def self.find_project_dir(starting_dir)
|
26
|
+
result = starting_dir
|
27
|
+
while project?(result) == false && result != "/"
|
28
|
+
result = File.expand_path("..", result)
|
29
|
+
end
|
30
|
+
|
31
|
+
fail NoProjectDirectoryError, starting_dir if result == "/"
|
32
|
+
|
33
|
+
result
|
34
|
+
end
|
35
|
+
|
36
|
+
# returns true if the specified directory is a valid tetra project
|
37
|
+
def self.project?(dir)
|
38
|
+
File.directory?(File.join(dir, "src")) &&
|
39
|
+
File.directory?(File.join(dir, "kit")) &&
|
40
|
+
File.directory?(File.join(dir, ".git"))
|
41
|
+
end
|
42
|
+
|
43
|
+
# returns the package name corresponding to the specified dir, if any
|
44
|
+
# raises NoPackageDirectoryError if dir is not a (sub)directory of a package
|
45
|
+
def get_package_name(dir)
|
46
|
+
dir_path = Pathname.new(File.expand_path(dir)).relative_path_from(Pathname.new(@full_path))
|
47
|
+
components = dir_path.to_s.split(File::SEPARATOR)
|
48
|
+
if components.count >= 2 &&
|
49
|
+
components.first == "src" &&
|
50
|
+
Dir.exist?(File.join(@full_path, components[0], components[1]))
|
51
|
+
components[1]
|
52
|
+
else
|
53
|
+
fail NoPackageDirectoryError
|
54
|
+
end
|
55
|
+
rescue ArgumentError, NoProjectDirectoryError
|
56
|
+
raise NoPackageDirectoryError, dir
|
57
|
+
end
|
58
|
+
|
59
|
+
# inits a new project directory structure
|
60
|
+
def self.init(dir)
|
61
|
+
Dir.chdir(dir) do
|
62
|
+
Tetra::Git.new(".").init
|
63
|
+
|
64
|
+
FileUtils.mkdir_p "src"
|
65
|
+
FileUtils.mkdir_p "kit"
|
66
|
+
|
67
|
+
# populate the project with templates and take a snapshot
|
68
|
+
project = Project.new(".")
|
69
|
+
|
70
|
+
template_manager = Tetra::TemplateManager.new
|
71
|
+
template_manager.copy "output", "."
|
72
|
+
template_manager.copy "kit", "."
|
73
|
+
template_manager.copy "src", "."
|
74
|
+
template_manager.copy "gitignore", ".gitignore"
|
75
|
+
|
76
|
+
project.take_snapshot "Template files added", :init
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# starts a dry running phase: files added to kit/ will be added
|
81
|
+
# to the kit package, src/ will be reset at the current state
|
82
|
+
# when finished
|
83
|
+
def dry_run
|
84
|
+
return false if dry_running?
|
85
|
+
|
86
|
+
current_directory = Pathname.new(Dir.pwd).relative_path_from Pathname.new(@full_path)
|
87
|
+
|
88
|
+
take_snapshot("Dry-run started", :dry_run_started, current_directory)
|
89
|
+
true
|
90
|
+
end
|
91
|
+
|
92
|
+
# returns true iff we are currently dry-running
|
93
|
+
def dry_running?
|
94
|
+
latest_tag_count(:dry_run_started) > latest_tag_count(:dry_run_finished)
|
95
|
+
end
|
96
|
+
|
97
|
+
# ends a dry-run.
|
98
|
+
# if abort is true, reverts the whole directory
|
99
|
+
# if abort is false, reverts sources and updates output file lists
|
100
|
+
def finish(abort)
|
101
|
+
if dry_running?
|
102
|
+
if abort
|
103
|
+
@git.revert_whole_directory(".", latest_tag(:dry_run_started))
|
104
|
+
@git.delete_tag(latest_tag(:dry_run_started))
|
105
|
+
else
|
106
|
+
take_snapshot "Changes during dry-run", :dry_run_changed
|
107
|
+
|
108
|
+
@git.revert_whole_directory("src", latest_tag(:dry_run_started))
|
109
|
+
|
110
|
+
take_snapshot "Dry run finished", :dry_run_finished
|
111
|
+
end
|
112
|
+
return true
|
113
|
+
end
|
114
|
+
false
|
115
|
+
end
|
116
|
+
|
117
|
+
# takes a revertable snapshot of this project
|
118
|
+
def take_snapshot(message, tag_prefix = nil, tag_message = nil)
|
119
|
+
tag = (
|
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)
|
128
|
+
end
|
129
|
+
|
130
|
+
# replaces content in path with new_content, takes a snapshot using
|
131
|
+
# snapshot_message and tag_prefix and 3-way merges new and old content
|
132
|
+
# with a previous snapshotted file same path tag_prefix, if it exists.
|
133
|
+
# returns the number of conflicts
|
134
|
+
def merge_new_content(new_content, path, snapshot_message, tag_prefix)
|
135
|
+
from_directory do
|
136
|
+
log.debug "merging new content to #{path} with prefix #{tag_prefix}"
|
137
|
+
already_existing = File.exist? path
|
138
|
+
previous_tag = latest_tag(tag_prefix)
|
139
|
+
|
140
|
+
if already_existing
|
141
|
+
log.debug "moving #{path} to #{path}.tetra_user_edited"
|
142
|
+
File.rename path, "#{path}.tetra_user_edited"
|
143
|
+
end
|
144
|
+
|
145
|
+
File.open(path, "w") { |io| io.write(new_content) }
|
146
|
+
log.debug "taking snapshot with new content: #{snapshot_message}"
|
147
|
+
take_snapshot(snapshot_message, tag_prefix)
|
148
|
+
|
149
|
+
if already_existing
|
150
|
+
if previous_tag == ""
|
151
|
+
previous_tag = latest_tag(tag_prefix)
|
152
|
+
log.debug "there was no tag with prefix #{tag_prefix} before snapshot"
|
153
|
+
log.debug "defaulting to #{previous_tag} after snapshot"
|
154
|
+
end
|
155
|
+
|
156
|
+
# 3-way merge
|
157
|
+
conflict_count = @git.merge_with_tag("#{path}", "#{path}.tetra_user_edited", previous_tag)
|
158
|
+
File.delete "#{path}.tetra_user_edited"
|
159
|
+
return conflict_count
|
160
|
+
end
|
161
|
+
return 0
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
# returns the tag with maximum count for a given tag prefix
|
166
|
+
def latest_tag(prefix)
|
167
|
+
"#{prefix}_#{latest_tag_count(prefix)}"
|
168
|
+
end
|
169
|
+
|
170
|
+
# returns the maximum tag count for a given tag prefix
|
171
|
+
def latest_tag_count(prefix)
|
172
|
+
@git.get_tag_maximum_suffix(prefix)
|
173
|
+
end
|
174
|
+
|
175
|
+
# runs a block from the project directory or a subdirectory
|
176
|
+
def from_directory(subdirectory = "")
|
177
|
+
Dir.chdir(File.join(@full_path, subdirectory)) do
|
178
|
+
yield
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
# returns the latest dry run start directory
|
183
|
+
def latest_dry_run_directory
|
184
|
+
@git.get_message(latest_tag(:dry_run_started))
|
185
|
+
end
|
186
|
+
|
187
|
+
# returns a list of files produced during dry-runs in a certain package
|
188
|
+
def get_produced_files(package)
|
189
|
+
dry_run_count = latest_tag_count(:dry_run_changed)
|
190
|
+
log.debug "Getting produced files from #{dry_run_count} dry runs"
|
191
|
+
if dry_run_count >= 1
|
192
|
+
package_dir = File.join("src", package)
|
193
|
+
(1..dry_run_count).map do |i|
|
194
|
+
@git.changed_files_between("dry_run_started_#{i}", "dry_run_changed_#{i}", package_dir)
|
195
|
+
end
|
196
|
+
.flatten
|
197
|
+
.uniq
|
198
|
+
.sort
|
199
|
+
.map { |file| Pathname.new(file).relative_path_from(Pathname.new(package_dir)).to_s }
|
200
|
+
else
|
201
|
+
[]
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
# moves any .jar from src/ to kit/ and links it back
|
206
|
+
def purge_jars
|
207
|
+
from_directory do
|
208
|
+
result = []
|
209
|
+
Find.find("src") do |file|
|
210
|
+
next unless file =~ /.jar$/ && !File.symlink?(file)
|
211
|
+
|
212
|
+
new_location = File.join("kit", "jars", Pathname.new(file).split[1])
|
213
|
+
FileUtils.mv(file, new_location)
|
214
|
+
|
215
|
+
link_target = Pathname.new(new_location)
|
216
|
+
.relative_path_from(Pathname.new(file).split.first)
|
217
|
+
.to_s
|
218
|
+
|
219
|
+
File.symlink(link_target, file)
|
220
|
+
result << [file, new_location]
|
221
|
+
end
|
222
|
+
|
223
|
+
result
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
# current directory is not a tetra project
|
229
|
+
class NoProjectDirectoryError < StandardError
|
230
|
+
attr_reader :directory
|
231
|
+
|
232
|
+
def initialize(directory)
|
233
|
+
@directory = directory
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
# current directory is not a tetra package directory
|
238
|
+
class NoPackageDirectoryError < StandardError
|
239
|
+
attr_reader :directory
|
240
|
+
|
241
|
+
def initialize(directory)
|
242
|
+
@directory = directory
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Tetra
|
4
|
+
# generates build scripts from bash_history
|
5
|
+
class ScriptGenerator
|
6
|
+
include Logging
|
7
|
+
|
8
|
+
def initialize(project, history_path)
|
9
|
+
@project = project
|
10
|
+
@ant_runner = Tetra::AntRunner.new(project)
|
11
|
+
@maven_runner = Tetra::MavenRunner.new(project)
|
12
|
+
@history_path = history_path
|
13
|
+
end
|
14
|
+
|
15
|
+
def generate_build_script(name)
|
16
|
+
@project.from_directory do
|
17
|
+
history_lines = File.readlines(@history_path).map { |e| e.strip }
|
18
|
+
relevant_lines =
|
19
|
+
history_lines
|
20
|
+
.reverse
|
21
|
+
.take_while { |e| e.match(/tetra +dry-run/).nil? }
|
22
|
+
.reverse
|
23
|
+
.take_while { |e| e.match(/tetra +finish/).nil? }
|
24
|
+
.select { |e| e.match(/^#/).nil? }
|
25
|
+
|
26
|
+
script_lines = [
|
27
|
+
"#!/bin/bash",
|
28
|
+
"PROJECT_PREFIX=`readlink -e .`",
|
29
|
+
"cd #{@project.latest_dry_run_directory}"
|
30
|
+
] +
|
31
|
+
relevant_lines.map do |line|
|
32
|
+
if line =~ /tetra +mvn/
|
33
|
+
line.gsub(/tetra +mvn/, "#{@maven_runner.get_maven_commandline("$PROJECT_PREFIX", ["-o"])}")
|
34
|
+
elsif line =~ /tetra +ant/
|
35
|
+
line.gsub(/tetra +ant/, "#{@ant_runner.get_ant_commandline("$PROJECT_PREFIX")}")
|
36
|
+
else
|
37
|
+
line
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
new_content = script_lines.join("\n") + "\n"
|
42
|
+
|
43
|
+
script_name = "build.sh"
|
44
|
+
result_path = File.join("src", name, script_name)
|
45
|
+
conflict_count = @project.merge_new_content(new_content, result_path, "Build script generated",
|
46
|
+
"generate_#{name}_build_script")
|
47
|
+
|
48
|
+
destination_dir = File.join("output", name)
|
49
|
+
FileUtils.mkdir_p(destination_dir)
|
50
|
+
destination_script_path = File.join(destination_dir, script_name)
|
51
|
+
FileUtils.symlink(File.expand_path(result_path), destination_script_path, force: true)
|
52
|
+
|
53
|
+
[result_path, conflict_count]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|