gjp 0.8.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
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