gjp 0.8.0 → 0.9.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/lib/gjp.rb CHANGED
@@ -9,3 +9,4 @@ require "gjp/get_pom"
9
9
  require "gjp/get_parent_pom"
10
10
  require "gjp/get_source_address"
11
11
  require "gjp/get_source"
12
+ require "gjp/jar_table"
@@ -74,5 +74,13 @@ module Gjp
74
74
  puts Gjp::SourceGetter.get_source(address, pom, directory)
75
75
  end
76
76
  end
77
+
78
+ subcommand "scaffold-jar-table", "Creates a heuristic version of a project's jar table" do
79
+ parameter "[DIRECTORY]", "project directory", :default => "."
80
+
81
+ def execute
82
+ puts Gjp::JarTable.new(directory).to_s
83
+ end
84
+ end
77
85
  end
78
86
  end
@@ -0,0 +1,119 @@
1
+ # encoding: UTF-8
2
+
3
+ require "text"
4
+
5
+ module Gjp
6
+ # encapsulates information of a project's jar files
7
+ # assumes the project is in a directory with jar files
8
+ # in its (possibly nested) subdirectories
9
+ class JarTable
10
+ def self.log
11
+ Gjp.logger
12
+ end
13
+
14
+ attr_reader :dir, :rows
15
+
16
+ # builds a JarTable from a directory (paths relative to the current directory)
17
+ def initialize(dir)
18
+ @dir = dir
19
+
20
+ @rows = Hash[
21
+ jars.map do |jar|
22
+ [jar, get_type(jar)]
23
+ end
24
+ ]
25
+ end
26
+
27
+ def to_s
28
+ "# Legend: "
29
+ "#b - jar is required for building the project"
30
+ "#r - jar is required runtime by the project"
31
+ "#p - jar is produced by the project"
32
+ @rows.map do |key, value|
33
+ "#{value.to_s[0]} #{key}"
34
+ end.sort
35
+ end
36
+
37
+ # jar files in the project's directory
38
+ def jars
39
+ Dir["#{@dir}/**/*.jar"]
40
+ end
41
+
42
+ # returns packages defined in a jar file
43
+ def jar_defined_packages(jar)
44
+ result = []
45
+ begin
46
+ Zip::ZipFile.foreach(jar) do |entry|
47
+ if entry.name =~ /^(.+)\/.+?\.class$/
48
+ result << $1.gsub("/", ".")
49
+ end
50
+ end
51
+ rescue Zip::ZipError
52
+ log.info "#{file} does not seem to be a valid jar archive, skipping"
53
+ rescue TypeError
54
+ log.info "#{file} seems to be a valid jar archive but is corrupt, skipping"
55
+ end
56
+
57
+ return result.sort.uniq
58
+ end
59
+
60
+ # returns :produced if the jar was produced from the project's sources, and
61
+ # :required or :build_required if it is needed at runtime or build time
62
+ # (heuristically)
63
+ def get_type(jar)
64
+ if source_defined?(jar)
65
+ :produced
66
+ elsif runtime_required?(jar)
67
+ :required
68
+ else
69
+ :build_required
70
+ end
71
+ end
72
+
73
+ # returns true if a jar is produced from source code in the project's directory
74
+ def source_defined?(jar)
75
+ jar_defined_packages(jar).all? { |package| source_defined_packages.include?(package) }
76
+ end
77
+
78
+ # returns true if a jar is required runtime, false if it is only needed
79
+ # at compile time. Current implementation is heuristic (looks for "import" statements
80
+ # in java code)
81
+ def runtime_required?(jar)
82
+ jar_defined_packages(jar).any? { |package| source_required_packages.include?(package) }
83
+ end
84
+
85
+ # java source files in the project's directory
86
+ def sources
87
+ Dir["#{@dir}/**/*.java"]
88
+ end
89
+
90
+ # java statements in java source files
91
+ def statements
92
+ sources.map do |source|
93
+ File.readlines(source)
94
+ .map { |line| line.split(";") }
95
+ .flatten
96
+ .map { |statement| statement.strip }
97
+ end.flatten
98
+ end
99
+
100
+ # heuristically determined package names that the sources require
101
+ def source_required_packages
102
+ statement_fragments_from(/^import[ \t]+(?:static[ \t]+)?(.+)\..+?$/)
103
+ end
104
+
105
+ # heuristically determined package names that the sources define
106
+ def source_defined_packages
107
+ statement_fragments_from(/^package[ \t]+(.+)$/)
108
+ end
109
+
110
+ # matches a regex against all source statements
111
+ def statement_fragments_from(regex)
112
+ statements.map do |statement|
113
+ if statement =~ regex
114
+ $1
115
+ end
116
+ end.select {|package| package != nil}.flatten.sort.uniq
117
+ end
118
+ end
119
+ end
@@ -1,5 +1,5 @@
1
1
  # encoding: UTF-8
2
2
 
3
3
  module Gjp
4
- VERSION = "0.8.0"
4
+ VERSION = "0.9.0"
5
5
  end
@@ -0,0 +1,133 @@
1
+ <!--
2
+ Ant simple sample project.
3
+ Kick start your java builds.
4
+ Find out more at http://www.bodkinconsulting.com
5
+ or http://java.net/projects/ant-simple-sample
6
+
7
+ Instructions:
8
+ Put this file in an empty directory and run the 'ant' command in that directory. The build file will create directories and make a very empty jar file in the same directory as the build.xml.
9
+
10
+ Create src/HW.java and put this code in it.
11
+
12
+ public class HW
13
+ {
14
+ public static void main(String [] args)
15
+ {
16
+ System.out.println("Hello World");
17
+ }
18
+
19
+ }
20
+
21
+ in the build file below change
22
+ <property name="main_class_name" value="changeme"/>
23
+ to
24
+ <property name="main_class_name" value="HW"/>
25
+
26
+ Run the ant command again, and now you can run your main class with the command
27
+ java -jar antsimple.jar
28
+
29
+ It should print:
30
+ Hellow World
31
+ and exit.
32
+
33
+ Add a junit.jar (from junit.org) into your ANT_HOME/lib directory and run 'ant test'
34
+
35
+ Create the file test/HWTest.java and add this code.
36
+ import junit.framework.*;
37
+ public class HWTest extends TestCase {
38
+ public void testTrue()
39
+ {
40
+ assertTrue(true);
41
+ }
42
+ }
43
+
44
+ -->
45
+
46
+ <project name="antsimple" default="dist" basedir=".">
47
+ <description>
48
+ Ant Simple Sample File
49
+ </description>
50
+ <!-- set global properties for this build -->
51
+ <property name="ant.project.name" value="antsimple"/>
52
+ <property name="main_class_name" value="HW"/>
53
+ <property name="jarname" value="${ant.project.name}"/>
54
+ <!-- set directories -->
55
+ <property name="src" location="src"/>
56
+ <property name="test" location="test"/>
57
+ <property name="build" location="build"/>
58
+ <property name="dist" location="dist"/>
59
+ <property name="lib" location="lib"/>
60
+
61
+ <path id="project.classpath">
62
+ <pathelement location="${build}" />
63
+ <pathelement location="${lib}/log4j-1.2.13.jar" />
64
+ </path>
65
+
66
+
67
+ <target name="init">
68
+ <!-- Create the time stamp -->
69
+ <tstamp/>
70
+ <!-- Create directories if needed -->
71
+ <mkdir dir="${src}"/>
72
+ <mkdir dir="${test}"/>
73
+ <mkdir dir="${build}"/>
74
+ <mkdir dir="${dist}"/>
75
+ </target>
76
+
77
+ <target name="compile" depends="init" description="compile the source " >
78
+ <!-- Compile the java code from ${src} into ${build} -->
79
+ <javac debug="true"
80
+ srcdir="${src}"
81
+ destdir="${build}"
82
+ classpathref="project.classpath"/>
83
+ <!-- Copy files from ${src} into ${build} -->
84
+ <copy todir="${build}">
85
+ <fileset dir="${src}">
86
+ <exclude name="**/*.java"/>
87
+ </fileset>
88
+ </copy>
89
+ </target>
90
+
91
+ <!--
92
+ Broken???
93
+ -->
94
+ <target name="test" depends="compiletest" description="run the tests " >
95
+ <junit printsummary="yes" fork="yes" haltonfailure="yes">
96
+ <formatter type="plain"/>
97
+ <batchtest fork="true">
98
+ <fileset dir="${test}">
99
+ <include name="**/*Test*.java"/>
100
+ </fileset>
101
+ </batchtest>
102
+ <classpath refid="${project.classpath}" />
103
+ </junit>
104
+ </target>
105
+
106
+ <target name="compiletest" depends="compile"
107
+ description="compile the tests " >
108
+ <javac debug="true"
109
+ srcdir="${test}"
110
+ destdir="${build}"
111
+ classpathref="project.classpath" />
112
+ </target>
113
+
114
+ <target name="dist" depends="compile" description="generate the distribution" >
115
+ <!-- Create the distribution directory -->
116
+
117
+ <!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->
118
+ <jar jarfile="${dist}/${jarname}-${DSTAMP}.jar" basedir="${build}">
119
+ <manifest>
120
+ <attribute name="Main-Class"
121
+ value="${main_class_name}"/>
122
+ </manifest>
123
+ </jar>
124
+ <copy file="${dist}/${jarname}-${DSTAMP}.jar" tofile="./${jarname}.jar" overwrite="true"/>
125
+ </target>
126
+
127
+ <target name="clean"
128
+ description="clean up" >
129
+ <!-- Delete the ${build} directory-->
130
+ <delete dir="${build}"/>
131
+ </target>
132
+ </project>
133
+
@@ -0,0 +1,15 @@
1
+ package mypackage;
2
+
3
+ import org.apache.log4j.Logger;
4
+ import org.apache.log4j.BasicConfigurator;
5
+
6
+ public class HW
7
+ {
8
+ static Logger logger = Logger.getLogger(HW.class);
9
+ public static void main(String [] args)
10
+ {
11
+ BasicConfigurator.configure();
12
+ logger.info("Hello World");
13
+ }
14
+
15
+ }
@@ -0,0 +1,66 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Gjp::JarTable do
6
+ let(:dir) { File.join("spec", "data", "ant-super-simple-code") }
7
+ let(:jar_table) { Gjp::JarTable.new(dir) }
8
+
9
+ describe "#jars" do
10
+ it "finds jar paths in a directory" do
11
+ jar_table.jars.should include(
12
+ File.join(dir, "dist", "antsimple-20130618.jar"),
13
+ File.join(dir, "lib", "junit-4.11.jar"),
14
+ File.join(dir, "lib", "log4j-1.2.13.jar")
15
+ )
16
+ end
17
+ end
18
+
19
+ describe "#jar_defined_packages" do
20
+ it "finds the package names part of a jar file" do
21
+ jar_table.jar_defined_packages(File.join(dir, "lib", "junit-4.11.jar")).should include(
22
+ "junit.framework",
23
+ "junit.extensions",
24
+ "org.junit.runner",
25
+ "org.junit.runners.model"
26
+ )
27
+ end
28
+ end
29
+
30
+ describe "#runtime_required?" do
31
+ it "heuristically determines if a jar file is needed runtime" do
32
+ jar_table.runtime_required?(File.join(dir, "lib", "junit-4.11.jar")).should be_false
33
+ jar_table.runtime_required?(File.join(dir, "lib", "log4j-1.2.13.jar")).should be_true
34
+ end
35
+ end
36
+
37
+ describe "#sources" do
38
+ it "finds source paths in a directory" do
39
+ jar_table.sources.should include(
40
+ File.join(dir, "src", "mypackage", "HW.java")
41
+ )
42
+ end
43
+ end
44
+
45
+ describe "#source_defined_packages" do
46
+ it "finds the package names built from this project" do
47
+ jar_table.source_defined_packages.should include("mypackage")
48
+ end
49
+ end
50
+
51
+ describe "#source_required_packages" do
52
+ it "finds the package names required by this project's sources" do
53
+ jar_table.source_required_packages.should include("org.apache.log4j")
54
+ end
55
+ end
56
+
57
+ describe "#rows" do
58
+ it "returns jar data" do
59
+ jar_table.rows.should include(
60
+ "spec/data/ant-super-simple-code/lib/log4j-1.2.13.jar" => :required,
61
+ "spec/data/ant-super-simple-code/lib/junit-4.11.jar" => :build_required,
62
+ "spec/data/ant-super-simple-code/dist/antsimple-20130618.jar" => :produced
63
+ )
64
+ end
65
+ end
66
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gjp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.9.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-06-17 00:00:00.000000000 Z
12
+ date: 2013-06-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -161,11 +161,19 @@ files:
161
161
  - lib/gjp/get_pom.rb
162
162
  - lib/gjp/get_source.rb
163
163
  - lib/gjp/get_source_address.rb
164
+ - lib/gjp/jar_table.rb
164
165
  - lib/gjp/logger.rb
165
166
  - lib/gjp/maven_website.rb
166
167
  - lib/gjp/pom.rb
167
168
  - lib/gjp/version.rb
168
169
  - lib/gjp/version_matcher.rb
170
+ - spec/data/ant-super-simple-code/build.xml
171
+ - spec/data/ant-super-simple-code/build/HW.class
172
+ - spec/data/ant-super-simple-code/build/mypackage/HW.class
173
+ - spec/data/ant-super-simple-code/dist/antsimple-20130618.jar
174
+ - spec/data/ant-super-simple-code/lib/junit-4.11.jar
175
+ - spec/data/ant-super-simple-code/lib/log4j-1.2.13.jar
176
+ - spec/data/ant-super-simple-code/src/mypackage/HW.java
169
177
  - spec/data/antlr/antlr-2.7.2.jar
170
178
  - spec/data/antlr/pom.xml
171
179
  - spec/data/commons-logging/commons-logging-1.1.1.jar
@@ -179,6 +187,7 @@ files:
179
187
  - spec/lib/get_pom_spec.rb
180
188
  - spec/lib/get_source_address_spec.rb
181
189
  - spec/lib/get_source_spec.rb
190
+ - spec/lib/jar_table_spec.rb
182
191
  - spec/lib/maven_website_spec.rb
183
192
  - spec/lib/pom_spec.rb
184
193
  - spec/lib/version_matcher_spec.rb
@@ -208,6 +217,13 @@ signing_key:
208
217
  specification_version: 3
209
218
  summary: Green Java Packager's Tools
210
219
  test_files:
220
+ - spec/data/ant-super-simple-code/build.xml
221
+ - spec/data/ant-super-simple-code/build/HW.class
222
+ - spec/data/ant-super-simple-code/build/mypackage/HW.class
223
+ - spec/data/ant-super-simple-code/dist/antsimple-20130618.jar
224
+ - spec/data/ant-super-simple-code/lib/junit-4.11.jar
225
+ - spec/data/ant-super-simple-code/lib/log4j-1.2.13.jar
226
+ - spec/data/ant-super-simple-code/src/mypackage/HW.java
211
227
  - spec/data/antlr/antlr-2.7.2.jar
212
228
  - spec/data/antlr/pom.xml
213
229
  - spec/data/commons-logging/commons-logging-1.1.1.jar
@@ -221,6 +237,7 @@ test_files:
221
237
  - spec/lib/get_pom_spec.rb
222
238
  - spec/lib/get_source_address_spec.rb
223
239
  - spec/lib/get_source_spec.rb
240
+ - spec/lib/jar_table_spec.rb
224
241
  - spec/lib/maven_website_spec.rb
225
242
  - spec/lib/pom_spec.rb
226
243
  - spec/lib/version_matcher_spec.rb