eclipse-plugin 0.0.1

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.
@@ -0,0 +1,42 @@
1
+ h1. Eclipse::Plugin
2
+
3
+ A Ruby Gem to extract information about views, properties and perspectives from an eclipse plugin or a workspace
4
+
5
+ Use it at your own risk, as it is just a small utility gem to help for some release engineering for the Elexis-RCP. See http://elexis.info.
6
+
7
+ But I have an open ear for suggestions for improvements, especially if they come with a patch including specs.
8
+
9
+ License: GPLv3 or later
10
+
11
+ Copyright: 2014 (c) by Niklaus Giger <niklaus.giger@member.fsf.org>
12
+
13
+ h2. Installation
14
+
15
+ Add this line to your application's Gemfile:
16
+
17
+ bc. $ gem 'eclipse-plugin'
18
+
19
+ And then execute:
20
+
21
+ bc. $ bundle
22
+
23
+ Or install it yourself as:
24
+
25
+ bc. $ gem install eclipse-plugin
26
+
27
+ h2. Usage
28
+
29
+ bc. require 'eclipse/plugin'
30
+ workspace = Eclipse::Workspace.new('/path/to/eclipse/app')
31
+ workspace.parsePluginDir
32
+ workspace.views.first {|view| puts view.id }
33
+
34
+ Or you can inspire you from the spec/*_spec.rb files to see tested examples.
35
+
36
+ h2. Contributing
37
+
38
+ # Fork it ( http://github.com/<my-github-username>/eclipse-plugin/fork )
39
+ # Create your feature branch (`git checkout -b my-new-feature`)
40
+ # Commit your changes (`git commit -am 'Add some feature'`)
41
+ # Push to the branch (`git push origin my-new-feature`)
42
+ # Create new Pull Request
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'eclipse/plugin/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "eclipse-plugin"
8
+ spec.version = Eclipse::Plugin::VERSION
9
+ spec.authors = ["Niklaus Giger"]
10
+ spec.email = ["niklaus.giger@member.fsf.org"]
11
+ spec.summary = "Extract information about views, properties and perspectives from an eclipse plugin"
12
+ spec.description = "Extracts localized info out of an Eclipse plugin jar"
13
+ spec.homepage = ""
14
+ spec.license = "GPLv3"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+ spec.add_dependency 'rubyzip', '>= 1.0.0'
21
+ spec.add_development_dependency "bundler", "~> 1.5"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec"
24
+ spec.add_development_dependency "simplecov"
25
+ spec.add_development_dependency "pry-debugger"
26
+ end
@@ -0,0 +1,21 @@
1
+ #encoding : utf-8
2
+ require 'iconv' unless String.method_defined?(:encode)
3
+
4
+ module Eclipse
5
+
6
+ module Helpers
7
+
8
+ module_function
9
+
10
+ # properties files are saved (at least in the cases, that interest me)
11
+ # as ISO-8859-15 files
12
+ def unescape(inhalt)
13
+ if String.method_defined?(:encode)
14
+ inhalt.encode!('UTF-8', 'ISO-8859-15', :invalid => :replace)
15
+ else
16
+ ic = Iconv.new('UTF-8//IGNORE', 'ISO-8859-15')
17
+ inhalt = ic.iconv(inhalt)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,201 @@
1
+ require "eclipse/plugin/version"
2
+
3
+ require 'zip'
4
+ require "rexml/document"
5
+ include REXML # so that we don't have to prefix everything with REXML::...
6
+
7
+ module Eclipse
8
+ class Workspace
9
+ attr_reader :workspace_dir, :views, :view_categories, :preferencePages, :perspectives, :preferencePage_categories
10
+ def initialize(workspace_dir)
11
+ @workspace_dir = workspace_dir
12
+ @views = Hash.new
13
+ @view_categories = Hash.new
14
+ @preferencePages = Hash.new
15
+ @perspectives = Hash.new
16
+ @preferencePage_categories = Hash.new
17
+ end
18
+
19
+ def parsePluginDir(plugins_dir = File.join(@workspace_dir, "plugins"))
20
+ name = "#{plugins_dir}/*.jar"
21
+ Dir.glob(name).each{
22
+ |jarname|
23
+ info = Plugin::Info.new(jarname)
24
+ fields = [:views, :view_categories, :preferencePages, :perspectives, :preferencePage_categories]
25
+ info.views.each{ |k, v| @views[k] = v }
26
+ info.view_categories.each{ |k, v| @views[k] = v }
27
+ info.perspectives.each{ |k, v| @views[k] = v }
28
+ info.preferencePages.each{ |k, v| @views[k] = v }
29
+ info.preferencePage_categories.each{ |k, v| @views[k] = v }
30
+ }
31
+ end
32
+ end
33
+
34
+ module Plugin
35
+ class Info
36
+ # Some helper classes for the extension points we are interested in
37
+ UI_PreferencePage = Struct.new('UI_PreferencePage', :id, :category, :translation)
38
+ UI_View = Struct.new('UI_View', :id, :category, :translation)
39
+ UI_Perspective = Struct.new('UI_Perspective', :id, :category, :translation)
40
+ Category = Struct.new('Category', :id, :name, :translation)
41
+ attr_reader :iso, :views, :view_categories, :preferencePages, :perspectives, :workspace, :preferencePage_categories
42
+
43
+ def initialize(jarname, iso='de')
44
+ @workspace = File.dirname(jarname).sub(/\/plugins$/, '')
45
+ @iso = iso
46
+ @jarname = jarname
47
+ @jarfile = Zip::File.open(jarname)
48
+ @views = Hash.new
49
+ @view_categories = Hash.new
50
+ @preferencePages = Hash.new
51
+ @perspectives = Hash.new
52
+ @preferencePage_categories = Hash.new
53
+ # we use hashes to be able to find the categories fast
54
+ readPluginXML(File.basename(jarname))
55
+ rescue => e # HACK: we need this to handle org.apache.commons.lang under Windows-7
56
+ puts "Skipped plugin #{File.expand_path(jarname)}"
57
+ puts "error was #{e.inspect}"
58
+ puts caller
59
+ end
60
+
61
+ def addCategory(hash, id, name = nil)
62
+ return if hash[id] and hash[id].translation
63
+ hash[id] = Category.new(id, name) unless hash[id]
64
+ translation = getTranslationForPlugin(name, @iso) if name
65
+ hash[id].translation = translation if name and translation
66
+ puts "#{File.basename(@jarname)}: Added category #{id} name #{name} tr '#{translation}'" if $VERBOSE
67
+ end
68
+
69
+ def getTranslatedPreferencePages
70
+ all = []
71
+ @preferencePages.each{
72
+ |id, content|
73
+ unless content.category
74
+ next if @preferencePages.find { |sub_id, x| x.category.eql?(content.id) }
75
+ end
76
+ category = content.category
77
+ cat_trans = content.translation
78
+ text = nil
79
+ if @preferencePage_categories[category]
80
+ text = "#{@preferencePage_categories[category].translation}/#{content.translation}"
81
+ puts "preferencePages #{id} category #{category.inspect} text #{cat_trans}" if $VERBOSE
82
+ else
83
+ text = content.translation
84
+ puts "preferencePages #{id} text #{text}" if $VERBOSE
85
+ end
86
+ all << text
87
+ }
88
+ all.sort.reverse.uniq if all and all.size > 0
89
+ end
90
+
91
+ def getTranslatedViews
92
+ all = []
93
+ @views.each{
94
+ |id, content|
95
+ category = content.category
96
+ cat_trans = content.translation
97
+ text = nil
98
+ if category
99
+ text = "#{@view_categories[category].translation}/#{content.translation}"
100
+ else
101
+ text = "Other/#{content.translation}"
102
+ end
103
+ all << text if text
104
+ }
105
+ all.sort.reverse.uniq if all and all.size > 0
106
+ end
107
+ def getTranslatedPerspectives
108
+ all = []
109
+ @perspectives.each{
110
+ |id, content|
111
+ category = content.category
112
+ cat_trans = content.translation
113
+ text = nil
114
+ if category
115
+ text = "#{@perspectives[category].translation}/#{content.translation}"
116
+ puts "perspectives #{id} category #{category.inspect} text #{cat_trans}" if $VERBOSE
117
+ else
118
+ text = content.translation
119
+ puts "perspectives #{id} categories #{category} text #{text}" if $VERBOSE
120
+ end
121
+ all << text
122
+ }
123
+ all.sort.reverse.uniq if all and all.size > 0
124
+ end
125
+
126
+ def getTranslationForPlugin(look_for, iso)
127
+ properties = "plugin_#{iso}.properties"
128
+ properties = "plugin.properties" unless @jarfile.find_entry(properties)
129
+ puts "Looking for translation of #{look_for} in #{properties}" if $VERBOSE
130
+ line_nr = 0
131
+ @jarfile.read(properties).split("\n").each {
132
+ |line|
133
+ line_nr += 1
134
+ id,value = line.split(' = ')
135
+ if id and id.index(look_for) and value
136
+ return Helpers::unescape(value.sub("\r","").sub("\n",""))
137
+ else id,value = line.split('=')
138
+ return Helpers::unescape(value.sub("\r","").sub("\n","")) if id and id.index(look_for)
139
+ end
140
+ } if @jarfile.find_entry(properties)
141
+ return look_for # default
142
+ end
143
+
144
+ def readPluginXML(plugin_xml)
145
+ return unless @jarfile.find_entry('plugin.xml')
146
+ doc = Document.new @jarfile.read('plugin.xml')
147
+ # Get all perspectives
148
+ root = doc.root
149
+ res = []
150
+ root.elements.collect { |x| res << x if /org.eclipse.ui.perspectives/.match(x.attributes['point']) }
151
+ res[0].elements.each{
152
+ |x|
153
+ id = x.attributes['name'].sub(/^%/,'')
154
+ @perspectives[id] = UI_Perspective.new(id, nil, getTranslationForPlugin(id, @iso))
155
+ } if res and res[0] and res[0].elements
156
+ puts "found #{@perspectives.size} perspectives in #{plugin_xml}" if $VERBOSE
157
+
158
+ # Get all views
159
+ res = []
160
+ root.elements.collect { |x| res << x if /org.eclipse.ui.views/.match(x.attributes['point']) }
161
+ res[0].elements.each{
162
+ |x|
163
+ name = x.attributes['name'].sub(/^%/,'') if x.attributes['name']
164
+ id = x.attributes['id'].sub(/^%/,'')
165
+ if x.name.eql?('category')
166
+ addCategory(@view_categories, id, name)
167
+ elsif x.attributes['name']
168
+ category = x.attributes['category']
169
+ translation = getTranslationForPlugin(name, @iso)
170
+ puts "#{File.basename(@jarname, '.jar')}: Adding view: id #{id} category #{category.inspect} translation #{translation}" if $VERBOSE
171
+ unless category
172
+ @views[id] = UI_View.new(id, nil, translation)
173
+ else
174
+ @views[id] = UI_View.new(id, category, translation)
175
+ end
176
+ end
177
+ } if res and res[0] and res[0].elements
178
+ puts "found #{@views.size} views and #{@view_categories.size} categories" if $VERBOSE
179
+
180
+ # Get all preferencePages
181
+ res = []
182
+ root.elements.collect { |x| res << x if /org.eclipse.ui.preferencePages/.match(x.attributes['point']) }
183
+ res[0].elements.each{
184
+ |x|
185
+ name = x.attributes['name'].sub(/^%/,'')
186
+ id = x.attributes['id'].sub(/^%/,'')
187
+ category = x.attributes['category']
188
+ addCategory(@preferencePage_categories, id, name) unless category
189
+ translation = getTranslationForPlugin(name, @iso)
190
+ puts "Adding preferences: id #{id} category #{category.inspect} translation #{translation}" if $VERBOSE
191
+ unless category
192
+ @preferencePages[id] = UI_PreferencePage.new(id, nil, translation)
193
+ else
194
+ @preferencePages[id] = UI_PreferencePage.new(id, category, translation)
195
+ end
196
+ } if res and res[0] and res[0].elements
197
+ puts "#{sprintf("%-40s", File.basename(File.dirname(plugin_xml)))}: now #{@preferencePages.size} preferencePages" if $VERBOSE
198
+ end
199
+ end
200
+ end
201
+ end
@@ -0,0 +1,5 @@
1
+ module Eclipse
2
+ module Plugin
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ #Created by JInto - www.guh-software.de
2
+ Ansicht=Agenda-Ansicht
3
+ Add_Recurring_Appointment=Terminserie hinzuf�gen
@@ -0,0 +1,21 @@
1
+ #encoding : utf-8
2
+ require 'spec_helper'
3
+
4
+ require 'eclipse/plugin'
5
+ require 'eclipse/helpers'
6
+
7
+ describe 'Helpers' do
8
+
9
+ before :each do
10
+ @dataDir = File.expand_path(File.join(File.dirname(__FILE__), 'data'))
11
+ end
12
+
13
+ it "should escape a property_string into an UTF-8 string" do
14
+ IO.readlines(File.join(@dataDir, 'plugin_de.properties')).each{
15
+ |line|
16
+ next unless line.index('Add_Recurring_Appointment')
17
+ unescaped = Eclipse::Helpers.unescape(line)
18
+ unescaped.should match /hinzufügen/
19
+ }
20
+ end
21
+ end
@@ -0,0 +1,84 @@
1
+ #encoding : utf-8
2
+ require 'spec_helper'
3
+
4
+ require 'eclipse/plugin'
5
+
6
+ describe 'Plugin' do
7
+
8
+ CHECK_4_VIEW = 'ch.elexis.views.TemplatePrintView'
9
+ CHECK_4_PERSPECTIVE = 'elexis.articlePerspective'
10
+ CHECK_4_PREFERENCE_PAGE = 'org.iatrix.preferences.IatrixPreferences'
11
+ APP_JAR = 'ch.elexis.core.application_3.0.0.v20140314-1352.jar'
12
+ IATRIX_JAR = 'org.iatrix_3.0.0.v20140313-1017.jar'
13
+ JAR_WITHOUT_LOCALIZE = 'ch.elexis.laborimport.hl7.allg-3.0.0-SNAPSHOT.jar'
14
+ before :all do
15
+ @dataDir = File.expand_path(File.join(File.dirname(__FILE__), 'data'))
16
+ end
17
+
18
+ it "should run the readme example" do
19
+ require 'eclipse/plugin'
20
+ workspace = Eclipse::Workspace.new(@dataDir)
21
+ workspace.parsePluginDir
22
+ workspace.views.first {|view| puts view.id }
23
+ workspace.views.size.should == 66
24
+ end
25
+
26
+ it "must be able to analyse a plugin.xml without localization" do
27
+ plugin = File.join(@dataDir, 'plugins', JAR_WITHOUT_LOCALIZE)
28
+ info = Eclipse::Plugin::Info.new(plugin)
29
+ info.preferencePages['ch.elexis.laborimport.hl7.preferences'].should_not be nil
30
+ info.workspace.should == @dataDir
31
+ end
32
+
33
+ it "must be able to analyse a plugin.xml with localization" do
34
+ plugin = File.join(@dataDir, 'plugins', IATRIX_JAR)
35
+ info = Eclipse::Plugin::Info.new(plugin)
36
+ info.views['org.iatrix.views.JournalView'].should_not be nil
37
+ info.view_categories['org.iatrix'].should_not be nil
38
+ info.workspace.should == @dataDir
39
+ end
40
+
41
+ it "must return the perspectives" do
42
+ plugin = File.join(@dataDir, 'plugins', APP_JAR)
43
+ info = Eclipse::Plugin::Info.new(plugin)
44
+ info.perspectives[CHECK_4_PERSPECTIVE].should_not be nil
45
+ end
46
+
47
+ it "must return the preferencePages" do
48
+ plugin = File.join(@dataDir, 'plugins', IATRIX_JAR)
49
+ info = Eclipse::Plugin::Info.new(plugin)
50
+ info.preferencePages[CHECK_4_PREFERENCE_PAGE].should_not be nil
51
+ end
52
+
53
+ it "must return the correct translation for a view" do
54
+ plugin = File.join(@dataDir, 'plugins', APP_JAR)
55
+ info = Eclipse::Plugin::Info.new(plugin)
56
+ info.views[CHECK_4_VIEW].should_not be nil
57
+ german = 'Vorlage Drucken'
58
+ info.views[CHECK_4_VIEW].translation.should == german
59
+ pp info.getTranslatedViews.find_all{ |item| item.match(german) }
60
+ info.workspace.should == @dataDir
61
+ info.getTranslatedViews.find_all{ |item| item.match(german) }.should_not be nil
62
+ end
63
+
64
+ it "must return the correct translation for a preferencePage" do
65
+ plugin = File.join(@dataDir, 'plugins', IATRIX_JAR)
66
+ info = Eclipse::Plugin::Info.new(plugin)
67
+ info.preferencePages[CHECK_4_PREFERENCE_PAGE].should_not be nil
68
+ german = 'Iatrix'
69
+ info.preferencePages[CHECK_4_PREFERENCE_PAGE].translation.should == german
70
+ info.workspace.should == @dataDir
71
+ info.getTranslatedPreferencePages.find_all{ |item| item.match(german) }.should_not be nil
72
+ end
73
+
74
+ it "must return the correct translation for a perspective" do
75
+ plugin = File.join(@dataDir, 'plugins', APP_JAR)
76
+ info = Eclipse::Plugin::Info.new(plugin)
77
+ info.perspectives[CHECK_4_PERSPECTIVE].should_not be nil
78
+ german = 'Artikel'
79
+ info.perspectives[CHECK_4_PERSPECTIVE].translation.should == german
80
+ info.workspace.should == @dataDir
81
+ info.getTranslatedPerspectives.find_all{ |item| item.match(german) }.should_not be nil
82
+ end
83
+
84
+ end
@@ -0,0 +1,13 @@
1
+ require "bundler"
2
+ Bundler.setup(:default, :development)
3
+
4
+ unless RUBY_PLATFORM =~ /java/
5
+ require "simplecov"
6
+ SimpleCov.formatter = SimpleCov::Formatter::HTMLFormatter
7
+ SimpleCov.start do
8
+ add_filter "spec"
9
+ end
10
+ end
11
+
12
+ require "rspec"
13
+
metadata ADDED
@@ -0,0 +1,154 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: eclipse-plugin
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Niklaus Giger
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-03-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rubyzip
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ! '>='
18
+ - !ruby/object:Gem::Version
19
+ version: 1.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ! '>='
25
+ - !ruby/object:Gem::Version
26
+ version: 1.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '1.5'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '1.5'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ! '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: simplecov
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ! '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ! '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: pry-debugger
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ! '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ! '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: Extracts localized info out of an Eclipse plugin jar
98
+ email:
99
+ - niklaus.giger@member.fsf.org
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - .gitignore
105
+ - .travis.yml
106
+ - Gemfile
107
+ - Gemfile.lock
108
+ - LICENSE
109
+ - README.textile
110
+ - Rakefile
111
+ - eclipse-plugin.gemspec
112
+ - lib/eclipse/helpers.rb
113
+ - lib/eclipse/plugin.rb
114
+ - lib/eclipse/plugin/version.rb
115
+ - spec/data/plugin_de.properties
116
+ - spec/data/plugins/ch.elexis.core.application_3.0.0.v20140314-1352.jar
117
+ - spec/data/plugins/ch.elexis.laborimport.hl7.allg-3.0.0-SNAPSHOT.jar
118
+ - spec/data/plugins/org.iatrix_3.0.0.v20140313-1017.jar
119
+ - spec/helpers_spec.rb
120
+ - spec/plugin_spec.rb
121
+ - spec/spec_helper.rb
122
+ homepage: ''
123
+ licenses:
124
+ - GPLv3
125
+ metadata: {}
126
+ post_install_message:
127
+ rdoc_options: []
128
+ require_paths:
129
+ - lib
130
+ required_ruby_version: !ruby/object:Gem::Requirement
131
+ requirements:
132
+ - - ! '>='
133
+ - !ruby/object:Gem::Version
134
+ version: '0'
135
+ required_rubygems_version: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ! '>='
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
140
+ requirements: []
141
+ rubyforge_project:
142
+ rubygems_version: 2.2.1
143
+ signing_key:
144
+ specification_version: 4
145
+ summary: Extract information about views, properties and perspectives from an eclipse
146
+ plugin
147
+ test_files:
148
+ - spec/data/plugin_de.properties
149
+ - spec/data/plugins/ch.elexis.core.application_3.0.0.v20140314-1352.jar
150
+ - spec/data/plugins/ch.elexis.laborimport.hl7.allg-3.0.0-SNAPSHOT.jar
151
+ - spec/data/plugins/org.iatrix_3.0.0.v20140313-1017.jar
152
+ - spec/helpers_spec.rb
153
+ - spec/plugin_spec.rb
154
+ - spec/spec_helper.rb