gjp 0.11.1 → 0.11.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- gjp (0.10.2)
4
+ gjp (0.11.2)
5
5
  clamp
6
6
  json
7
7
  nokogiri
@@ -2,16 +2,9 @@
2
2
  require "gjp/logger"
3
3
  require "clamp"
4
4
 
5
- # Initialize global logger for CLI
6
- Gjp.logger = ::Logger.new(STDERR)
7
- Gjp.logger.datetime_format = "%Y-%m-%d %H:%M "
8
- Gjp.logger.level = ::Logger::ERROR
9
- Gjp.logger.formatter = proc do |severity, datetime, progname, msg|
10
- "#{severity.chars.first}: #{msg}\n"
11
- end
12
-
13
5
  module Gjp
14
6
  class MainCommand < Clamp::Command
7
+ include Logger
15
8
 
16
9
  # Common logging options
17
10
  option ["-v", "--verbose"], :flag, "verbose output"
@@ -32,13 +25,13 @@ module Gjp
32
25
 
33
26
  def configure_log_level(v, vv, vvv)
34
27
  if vvv
35
- Gjp.logger.level = Logger::DEBUG
28
+ log.level = ::Logger::DEBUG
36
29
  elsif vv
37
- Gjp.logger.level = Logger::INFO
30
+ log.level = ::Logger::INFO
38
31
  elsif v
39
- Gjp.logger.level = Logger::WARN
32
+ log.level = ::Logger::WARN
40
33
  else
41
- Gjp.logger.level = Logger::ERROR
34
+ log.level = ::Logger::ERROR
42
35
  end
43
36
  end
44
37
 
@@ -46,38 +39,36 @@ module Gjp
46
39
  subcommand "init", "Inits a gjp project in the current directory" do
47
40
  def execute
48
41
  Gjp::Project.init(".")
49
- puts "Project inited."
50
- puts "Use \"gjp gather\" before adding files to have gjp track them."
42
+ puts "Project inited, now gathering."
43
+ puts "Any file added to kit/ will be added to the kit package."
44
+ puts "Any file added to src/<orgId_artifactId_version> will be added to the corresponding package."
45
+ puts "Note that .gitignore files are honored!"
46
+ puts "When you are ready to test a dry-run build, use \"gjp dry-run\"."
51
47
  end
52
48
  end
53
49
 
54
50
  subcommand "gather", "Starts a gathering phase, add source and kit files to project" do
55
51
  def execute
56
- result = Gjp::Project.new(".").gather
57
- if result == :done
52
+ if Gjp::Project.new(".").gather
58
53
  puts "Now gathering."
59
54
  puts "Any file added to kit/ will be added to the kit package."
60
55
  puts "Any file added to src/<orgId_artifactId_version> will be added to the corresponding package."
61
56
  puts "Note that .gitignore files are honored!"
62
- puts "To finalize this gathering, use \"gjp finish\"."
63
- else
64
- puts "Cannot begin gathering while #{result}, use \"gjp finish\" first."
57
+ puts "When you are ready to test a dry-run build, use \"gjp dry-run\"."
65
58
  end
66
59
  end
67
60
  end
68
61
 
69
62
  subcommand "dry-run", "Starts a dry-run phase, attempt build to add dependencies to kit." do
70
63
  def execute
71
- result = Gjp::Project.new(".").dry_run
72
- if result == :done
64
+ if Gjp::Project.new(".").dry_run
73
65
  puts "Now dry-running, please start your build."
74
66
  puts "Any file added to kit/, presumably downloaded dependencies, will be added to the kit package."
75
67
  puts "The src/ directory and all files in it will be brought back to the current state when finished."
76
68
  puts "Note that .gitignore files are honored!"
77
69
  puts "To run a Maven from the kit, use \"gjp mvn\"."
70
+ puts "To add or remove files, use \"gjp gather\"."
78
71
  puts "To finalize this dry run, use \"gjp finish\"."
79
- else
80
- puts "Cannot begin a dry run while #{result}, use \"gjp finish\" first."
81
72
  end
82
73
  end
83
74
  end
@@ -96,6 +87,11 @@ module Gjp
96
87
  end
97
88
  end
98
89
 
90
+ subcommand "status", "Prints the current phase" do
91
+ def execute
92
+ puts "Now #{Gjp::Project.new(".").get_status.to_s}"
93
+ end
94
+ end
99
95
 
100
96
  subcommand "finish", "Finishes the current phase" do
101
97
  def execute
@@ -136,14 +132,14 @@ module Gjp
136
132
  subcommand "get-pom", "Retrieves a pom corresponding to a filename" do
137
133
  parameter "NAME", "a jar file path, a project directory path or a non-existing filename in the `project-version` form"
138
134
  def execute
139
- puts Gjp::PomGetter.get_pom(name)
135
+ puts Gjp::PomGetter.new.get_pom(name)
140
136
  end
141
137
  end
142
138
 
143
139
  subcommand "get-parent-pom", "Retrieves a pom that is the parent of an existing pom" do
144
140
  parameter "POM", "a pom file path or URI"
145
141
  def execute
146
- puts Gjp::ParentPomGetter.get_parent_pom(pom)
142
+ puts Gjp::ParentPomGetter.new.get_parent_pom(pom)
147
143
  end
148
144
  end
149
145
 
@@ -151,7 +147,7 @@ module Gjp
151
147
  parameter "POM", "a pom file path or URI"
152
148
 
153
149
  def execute
154
- puts Gjp::SourceAddressGetter.get_source_address(pom)
150
+ puts Gjp::SourceAddressGetter.new.get_source_address(pom)
155
151
  end
156
152
  end
157
153
 
@@ -161,7 +157,7 @@ module Gjp
161
157
  parameter "[DIRECTORY]", "directory in which to save the source code", :default => "."
162
158
 
163
159
  def execute
164
- puts Gjp::SourceGetter.get_source(address, pom, directory)
160
+ puts Gjp::SourceGetter.new.get_source(address, pom, directory)
165
161
  end
166
162
  end
167
163
 
@@ -7,9 +7,7 @@ module Gjp
7
7
  # assumes the project is in a directory with jar files
8
8
  # in its (possibly nested) subdirectories
9
9
  class JarTable
10
- def log
11
- Gjp.logger
12
- end
10
+ include Logger
13
11
 
14
12
  attr_reader :rows, :runtime_required_packages, :source_defined_packages
15
13
 
@@ -6,9 +6,7 @@ module Gjp
6
6
  # encapsulates a Linux user that cannot access the Internet
7
7
  # assumes root access (sudo) and iptables are available
8
8
  class LimitedNetworkUser
9
- def log
10
- Gjp.logger
11
- end
9
+ include Logger
12
10
 
13
11
  def initialize(name)
14
12
  @name = name
@@ -3,15 +3,25 @@
3
3
  require "logger"
4
4
 
5
5
  module Gjp
6
- def self.logger=(logger)
7
- @logger = logger
8
- end
6
+ module Logger
7
+ @@logger = nil
9
8
 
10
- def self.logger
11
- @logger ||= Logger.new('/dev/null')
12
- end
9
+ # returns a logger instance
10
+ def self.log
11
+ if @@logger == nil
12
+ @@logger = ::Logger.new(STDERR)
13
+ @@logger.datetime_format = "%Y-%m-%d %H:%M "
14
+ @@logger.level = ::Logger::ERROR
15
+ @@logger.formatter = proc do |severity, datetime, progname, msg|
16
+ "#{severity.chars.first}: #{msg}\n"
17
+ end
18
+ end
19
+ @@logger
20
+ end
13
21
 
14
- def logger
15
- Gjp.logger
22
+ # convenience instance method
23
+ def log
24
+ Gjp::Logger.log
25
+ end
16
26
  end
17
27
  end
@@ -6,9 +6,7 @@ require 'pathname'
6
6
  module Gjp
7
7
  # runs Maven from a gjp kit with gjp-specific options
8
8
  class MavenRunner
9
- def log
10
- Gjp.logger
11
- end
9
+ include Logger
12
10
 
13
11
  def initialize(project)
14
12
  @project = project
@@ -5,9 +5,7 @@ require "text"
5
5
  module Gjp
6
6
  # Facade to search.maven.org
7
7
  class MavenWebsite
8
- def log
9
- Gjp.logger
10
- end
8
+ include Logger
11
9
 
12
10
  # returns a search result object from search.maven.com
13
11
  # searching by a jar sha1 hash
@@ -5,13 +5,10 @@ require "pathname"
5
5
  module Gjp
6
6
  # attempts to get a pom's parent pom
7
7
  class ParentPomGetter
8
-
9
- def self.log
10
- Gjp.logger
11
- end
8
+ include Logger
12
9
 
13
10
  # returns the pom's parent, if any
14
- def self.get_parent_pom(filename)
11
+ def get_parent_pom(filename)
15
12
  begin
16
13
  pom = Pom.new(filename)
17
14
  site = MavenWebsite.new
@@ -11,18 +11,15 @@ require "gjp/version_matcher"
11
11
  module Gjp
12
12
  # attempts to get java projects' pom file
13
13
  class PomGetter
14
-
15
- def self.log
16
- Gjp.logger
17
- end
14
+ include Logger
18
15
 
19
16
  # returns the pom corresponding to a filename
20
- def self.get_pom(filename)
17
+ def get_pom(filename)
21
18
  (get_pom_from_dir(filename) or get_pom_from_jar(filename) or get_pom_from_sha1(filename) or get_pom_from_heuristic(filename))
22
19
  end
23
20
 
24
21
  # returns the pom in a project directory
25
- def self.get_pom_from_dir(dir)
22
+ def get_pom_from_dir(dir)
26
23
  if File.directory?(dir)
27
24
  pom_path = File.join(dir, "pom.xml")
28
25
  if File.file?(pom_path)
@@ -33,7 +30,7 @@ module Gjp
33
30
  end
34
31
 
35
32
  # returns a pom embedded in a jar file
36
- def self.get_pom_from_jar(file)
33
+ def get_pom_from_jar(file)
37
34
  begin
38
35
  Zip::ZipFile.foreach(file) do |entry|
39
36
  if entry.name =~ /\/pom.xml$/
@@ -50,7 +47,7 @@ module Gjp
50
47
  end
51
48
 
52
49
  # returns a pom from search.maven.org with a jar sha1 search
53
- def self.get_pom_from_sha1(file)
50
+ def get_pom_from_sha1(file)
54
51
  begin
55
52
  if File.file?(file)
56
53
  site = MavenWebsite.new
@@ -70,18 +67,19 @@ module Gjp
70
67
  end
71
68
 
72
69
  # returns a pom from search.maven.org with a heuristic name search
73
- def self.get_pom_from_heuristic(filename)
70
+ def get_pom_from_heuristic(filename)
74
71
  begin
75
72
  site = MavenWebsite.new
76
73
  filename = Pathname.new(filename).basename.to_s.sub(/.jar$/, "")
77
- my_artifact_id, my_version = VersionMatcher.split_version(filename)
74
+ version_matcher = VersionMatcher.new
75
+ my_artifact_id, my_version = version_matcher.split_version(filename)
78
76
 
79
77
  result = site.search_by_name(my_artifact_id).first
80
78
  if result != nil
81
79
  group_id, artifact_id, version = site.get_maven_id_from result
82
80
  results = site.search_by_group_id_and_artifact_id(group_id, artifact_id)
83
81
  their_versions = results.map {|doc| doc["v"]}
84
- best_matched_version = if my_version != nil then VersionMatcher.best_match(my_version, their_versions) else their_versions.max end
82
+ best_matched_version = if my_version != nil then version_matcher.best_match(my_version, their_versions) else their_versions.max end
85
83
  best_matched_result = (results.select{|result| result["v"] == best_matched_version}).first
86
84
 
87
85
  group_id, artifact_id, version = site.get_maven_id_from(best_matched_result)
@@ -5,9 +5,10 @@ require 'find'
5
5
  module Gjp
6
6
  # encapsulates a Gjp project directory
7
7
  class Project
8
- def log
9
- Gjp.logger
10
- end
8
+ include Logger
9
+
10
+ # list of possible statuses
11
+ @@statuses = [:gathering, :dry_running]
11
12
 
12
13
  attr_accessor :full_path
13
14
 
@@ -37,38 +38,43 @@ module Gjp
37
38
  # inits a new project directory structure
38
39
  def self.init(dir)
39
40
  Dir.chdir(dir) do
40
- `git init`
41
-
42
- Dir.mkdir("src")
43
- File.open(File.join("src", "README"), "w") do |file|
44
- file.puts "Sources are to be placed in subdirectories named after Maven names: orgId_artifactId_version"
45
- end
46
- Dir.mkdir("kit")
47
- File.open(File.join("kit", "README"), "w") do |file|
48
- file.puts "Build tool binaries are to be placed here"
41
+ if Dir.exists?(".git") == false
42
+ `git init`
49
43
  end
50
44
 
45
+ copy_from_template "file_lists", "."
46
+ copy_from_template "src", "."
47
+ copy_from_template "kit", "."
48
+
51
49
  `git add .`
52
50
  `git commit -m "Project initialized"`
53
- `git tag init`
51
+
52
+ # automatically begin a gathering phase
53
+ Project.new(".").gather
54
54
  end
55
55
  end
56
56
 
57
+ # copies a file/dir from the template directory to the destination directory
58
+ def self.copy_from_template(template_file, destination_dir)
59
+ FileUtils.cp_r(File.join(File.dirname(__FILE__), "..", "template", template_file), destination_dir)
60
+ end
61
+
57
62
  # starts a gathering phase, all files added to the project
58
63
  # will be added to packages (including kit)
59
64
  def gather
60
65
  from_directory do
61
- if get_status(:gathering)
62
- return :gathering
63
- elsif get_status(:dry_running)
64
- return :dry_running
66
+ status = get_status
67
+ if status == :gathering
68
+ return false
69
+ elsif status == :dry_running
70
+ finish
65
71
  end
66
72
 
67
- set_status(:gathering)
68
- commit_all("Gathering started")
73
+ set_status :gathering
74
+ take_snapshot "Gathering started", :revertable
69
75
  end
70
76
 
71
- :done
77
+ true
72
78
  end
73
79
 
74
80
  # starts a dry running phase: files added to the kit will
@@ -76,46 +82,48 @@ module Gjp
76
82
  # end
77
83
  def dry_run
78
84
  from_directory do
79
- if get_status(:gathering)
80
- return :gathering
81
- elsif get_status(:dry_running)
82
- return :dry_running
85
+ status = get_status
86
+ if status == :dry_running
87
+ return false
88
+ elsif status == :gathering
89
+ finish
83
90
  end
84
91
 
85
- set_status(:dry_running)
86
- commit_all("Dry-run started")
92
+ set_status :dry_running
93
+ take_snapshot "Dry-run started", :revertable
87
94
  end
88
95
 
89
- :done
96
+ true
90
97
  end
91
98
 
92
99
  # ends any phase that was previously started,
93
100
  # generating file lists
94
101
  def finish
95
102
  from_directory do
96
- if get_status(:gathering)
97
- commit_all("Changes during gathering")
103
+ status = get_status
104
+ if status == :gathering
105
+ take_snapshot "Changes during gathering"
98
106
 
99
- update_changed_file_list("kit", "gjp_kit_file_list")
100
- update_changed_src_file_list(:file_list)
101
- commit_all("File list updates")
107
+ update_changed_file_list("kit", "kit")
108
+ update_changed_src_file_list(:input)
109
+ take_snapshot "File list updates"
102
110
 
103
- clear_status(:gathering)
104
- commit_all("Gathering finished")
111
+ set_status nil
112
+ take_snapshot "Gathering finished", :revertable
105
113
 
106
114
  :gathering
107
- elsif get_status(:dry_running)
108
- commit_all("Changes during dry-run")
115
+ elsif status == :dry_running
116
+ take_snapshot "Changes during dry-run"
109
117
 
110
- update_changed_file_list("kit", "gjp_kit_file_list")
111
- update_changed_src_file_list(:produced_file_list)
112
- commit_all("File list updates")
118
+ update_changed_file_list("kit", "kit")
119
+ update_changed_src_file_list(:output)
120
+ take_snapshot "File list updates"
113
121
 
114
- revert("src", 2)
115
- commit_all("Sources reverted as before dry-run")
122
+ revert("src")
123
+ take_snapshot "Sources reverted as before dry-run"
116
124
 
117
- clear_status(:dry_running)
118
- commit_all("Dry run finished")
125
+ set_status nil
126
+ take_snapshot "Dry run finished", :revertable
119
127
 
120
128
  :dry_running
121
129
  end
@@ -124,84 +132,103 @@ module Gjp
124
132
 
125
133
  def update_changed_src_file_list(list_name)
126
134
  Dir.foreach("src") do |entry|
127
- if File.directory?(File.join(Dir.getwd, "src", entry)) and entry =~ /([^_\/]+_[^_]+_[^_]+)$/
128
- update_changed_file_list(File.join("src", entry), "gjp_#{$1}_#{list_name.to_s}")
135
+ if File.directory?(File.join(Dir.getwd, "src", entry)) and entry =~ /([^:\/]+:[^:]+:[^:]+)$/
136
+ update_changed_file_list(File.join("src", entry), "#{$1}_#{list_name.to_s}")
129
137
  end
130
138
  end
131
139
  end
132
140
 
133
- def update_changed_file_list(directory, list_file)
134
- existing_files = if File.exists?(list_file)
141
+ def update_changed_file_list(directory, file_name)
142
+ list_file = File.join("file_lists", file_name)
143
+ tracked_files = if File.exists?(list_file)
135
144
  File.readlines(list_file)
136
145
  else
137
146
  []
138
147
  end
139
148
 
140
- files = (
149
+ new_tracked_files = (
141
150
  `git diff-tree --no-commit-id --name-only -r HEAD`.split("\n")
142
151
  .select { |file| file.start_with?(directory) }
143
152
  .map { |file|file[directory.length + 1, file.length] }
144
- .concat(existing_files)
153
+ .concat(tracked_files)
145
154
  .sort
146
155
  .uniq
147
156
  )
148
157
 
149
- log.debug("writing file list for #{directory}: #{files.to_s}")
158
+ log.debug("writing file list for #{directory}: #{new_tracked_files.to_s}")
150
159
 
151
160
 
152
161
  File.open(list_file, "w+") do |file_list|
153
- files.each do |file|
162
+ new_tracked_files.each do |file|
154
163
  file_list.puts file
155
164
  end
156
165
  end
157
166
  end
158
167
 
159
168
  # adds the project's whole contents to git
160
- def commit_all(message)
161
- Find.find(".") do |path|
162
- if path =~ /.gitignore$/
163
- puts "Deleting #{path} to preserve all files..."
164
- File.delete(path)
165
- end
166
- end
167
-
169
+ # if tag is given, commit is tagged
170
+ def take_snapshot(message, revertability = :not_revertable)
168
171
  log.debug "committing with message: #{message}"
169
172
 
170
173
  `git rm -r --cached .`
171
174
  `git add .`
172
175
  `git commit -m "#{message}"`
176
+
177
+ if revertability == :revertable
178
+ latest_count = if latest_snapshot_name =~ /^gjp_revertable_snapshot_([0-9]+)$/
179
+ $1
180
+ else
181
+ 0
182
+ end
183
+ `git tag gjp_revertable_snapshot_#{$1.to_i + 1}`
184
+ end
185
+ end
186
+
187
+ # returns the last snapshot git tag name
188
+ def latest_snapshot_name
189
+ `git describe --abbrev=0 --tags --match=gjp_revertable_snapshot_*`.strip
173
190
  end
174
191
 
175
192
  # reverts dir contents as commit_count commits ago
176
- def revert(dir, commit_count)
193
+ def revert(dir)
177
194
  `git rm -rf --ignore-unmatch #{dir}`
178
- `git checkout -f HEAD~#{commit_count} -- #{dir}`
195
+ `git checkout -f #{latest_snapshot_name} -- #{dir}`
179
196
 
180
197
  `git clean -f -d #{dir}`
181
198
  end
182
199
 
183
- # gets a project status flag
184
- def get_status(status)
185
- file_name = status_file_name(status)
186
- File.exists?(file_name)
187
- end
188
-
189
- # sets a project status flag
190
- def set_status(status)
191
- file_name = status_file_name(status)
192
- if File.exists?(file_name) == false
193
- FileUtils.touch(file_name)
200
+ # returns a symbol with the current status
201
+ # flag
202
+ def get_status
203
+ from_directory do
204
+ @@statuses.each do |status|
205
+ if File.exists?(status_file_name(status))
206
+ return status
207
+ end
208
+ end
194
209
  end
210
+
211
+ nil
195
212
  end
196
213
 
197
- # sets a project status flag
198
- def clear_status(status)
199
- file_name = status_file_name(status)
200
- if File.exists?(file_name)
201
- File.delete(file_name)
214
+ # sets a project status flag. if status = nil,
215
+ # clears all status flags
216
+ def set_status(status)
217
+ from_directory do
218
+ @@statuses.each do |a_status|
219
+ file_name = status_file_name(a_status)
220
+ if File.exists?(file_name)
221
+ File.delete(file_name)
222
+ end
223
+
224
+ if a_status == status
225
+ FileUtils.touch(file_name)
226
+ end
227
+ end
202
228
  end
203
229
  end
204
230
 
231
+ # returns a file name that represents a status
205
232
  def status_file_name(status)
206
233
  ".#{status.to_s}"
207
234
  end