jenkins-plugin-runtime 0.1.18 → 0.1.20
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +12 -0
- data/Rakefile +2 -1
- data/jenkins-plugin-runtime.gemspec +2 -1
- data/lib/core_ext/exception.rb +36 -0
- data/lib/jenkins/cli/command.rb +167 -0
- data/lib/jenkins/cli/command_proxy.rb +62 -0
- data/lib/jenkins/filepath.rb +1 -6
- data/lib/jenkins/launcher.rb +4 -14
- data/lib/jenkins/model.rb +8 -41
- data/lib/jenkins/model/action.rb +1 -9
- data/lib/jenkins/model/build.rb +4 -5
- data/lib/jenkins/model/describable.rb +16 -30
- data/lib/jenkins/model/root_action.rb +2 -2
- data/lib/jenkins/plugin.rb +61 -12
- data/lib/jenkins/plugin/behavior.rb +96 -0
- data/lib/jenkins/plugin/proxies.rb +4 -0
- data/lib/jenkins/plugin/proxies/action.rb +10 -6
- data/lib/jenkins/plugin/proxies/build_step.rb +1 -0
- data/lib/jenkins/plugin/proxies/build_wrapper.rb +2 -5
- data/lib/jenkins/plugin/proxies/builder.rb +1 -5
- data/lib/jenkins/plugin/proxies/describable.rb +6 -0
- data/lib/jenkins/plugin/proxies/publisher.rb +1 -5
- data/lib/jenkins/plugin/proxies/root_action.rb +2 -17
- data/lib/jenkins/plugin/proxy.rb +27 -6
- data/lib/jenkins/plugin/runtime.rb +3 -0
- data/lib/jenkins/plugin/runtime/version.rb +1 -1
- data/lib/jenkins/plugin/wrapper.rb +29 -0
- data/spec/jenkins/cli/command_proxy_spec.rb +5 -0
- data/spec/jenkins/cli/command_spec.rb +5 -0
- data/spec/jenkins/launcher_spec.rb +0 -4
- data/spec/jenkins/model/action_spec.rb +2 -1
- data/spec/jenkins/model/build_spec.rb +2 -3
- data/spec/jenkins/model/describable_spec.rb +22 -7
- data/spec/jenkins/model_spec.rb +0 -28
- data/spec/jenkins/plugin/behavior_spec.rb +109 -0
- data/spec/jenkins/plugin/proxy_spec.rb +14 -0
- data/spec/jenkins/plugin_spec.rb +20 -0
- data/spec/spec_helper.rb +11 -5
- metadata +34 -13
- data/spec/mockito-all-1.8.5.jar +0 -0
data/lib/jenkins/plugin/proxy.rb
CHANGED
@@ -10,11 +10,12 @@ module Jenkins
|
|
10
10
|
#
|
11
11
|
# This module provides common functionality for all proxies.
|
12
12
|
module Proxy
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
13
|
+
extend Plugin::Behavior
|
14
|
+
|
15
|
+
implemented do |cls|
|
16
|
+
cls.class_eval do
|
17
|
+
include Java.org.kohsuke.stapler.StaplerProxy
|
18
|
+
end
|
18
19
|
end
|
19
20
|
|
20
21
|
# Every Proxy object has a reference to the plugin to which it belongs, as well as the
|
@@ -30,11 +31,21 @@ module Jenkins
|
|
30
31
|
end
|
31
32
|
|
32
33
|
# tell Stapler to go look for views from the wrapped object
|
33
|
-
include Java.org.kohsuke.stapler.StaplerProxy
|
34
34
|
def getTarget
|
35
35
|
@object
|
36
36
|
end
|
37
37
|
|
38
|
+
# Used to specify which Ruby class this will act as a proxy
|
39
|
+
module ProxyFor
|
40
|
+
# register this class as a proxy for `internal_class`. Jenkins
|
41
|
+
# will auto-create instances of this class when passing to
|
42
|
+
# ruby and vice-versa
|
43
|
+
def proxy_for(internal_class)
|
44
|
+
fail "not a ruby class" unless internal_class.is_a? Class
|
45
|
+
Jenkins::Plugin::Proxies.register internal_class, self
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
38
49
|
# Make sure that proxy classes do not try to persist the plugin parameter.
|
39
50
|
# when serializing this proxy to XStream. It will be reconstructed with
|
40
51
|
# [Unmarshal#read_completed]
|
@@ -78,6 +89,16 @@ module Jenkins
|
|
78
89
|
@plugin.export(object)
|
79
90
|
end
|
80
91
|
end
|
92
|
+
|
93
|
+
module ClassMethods
|
94
|
+
include Marshal
|
95
|
+
include ProxyFor
|
96
|
+
end
|
97
|
+
|
98
|
+
module InstanceMethods
|
99
|
+
include Unmarshal
|
100
|
+
include Customs
|
101
|
+
end
|
81
102
|
end
|
82
103
|
end
|
83
104
|
end
|
@@ -1,9 +1,12 @@
|
|
1
1
|
require 'jenkins/plugin'
|
2
|
+
require 'jenkins/plugin/behavior'
|
3
|
+
require 'jenkins/plugin/wrapper'
|
2
4
|
require 'jenkins/plugin/specification'
|
3
5
|
require 'jenkins/plugin/runtime/version'
|
4
6
|
require 'jenkins/plugin/proxy'
|
5
7
|
require 'jenkins/plugin/proxies/describable'
|
6
8
|
require 'jenkins/plugin/proxies'
|
9
|
+
require 'jenkins/cli/command'
|
7
10
|
require 'jenkins/model'
|
8
11
|
require 'jenkins/model/action'
|
9
12
|
require 'jenkins/model/root_action'
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class Jenkins::Plugin
|
2
|
+
# Proxies provide a lens through which the Java world sees a Ruby
|
3
|
+
# object. On the other hand, Wrappers are a lens through which
|
4
|
+
# the Ruby world sees a Java object.
|
5
|
+
module Wrapper
|
6
|
+
extend Behavior
|
7
|
+
|
8
|
+
# The native [java.lang.Object] which this object wraps
|
9
|
+
attr_reader :native
|
10
|
+
|
11
|
+
def initialize(*args)
|
12
|
+
@native, = *args
|
13
|
+
end
|
14
|
+
|
15
|
+
module ClassMethods
|
16
|
+
|
17
|
+
# Declare a wrapper class to wrap a certain type of
|
18
|
+
# java class. The plugin runtime will maintain this
|
19
|
+
# mapping so that whenever it sees an object coming
|
20
|
+
# in from Java, it knows the appropriate wrapper
|
21
|
+
# class to choose.
|
22
|
+
#
|
23
|
+
# @param [java.lang.Class] the java class equivalent
|
24
|
+
def wrapper_for(java_class)
|
25
|
+
Jenkins::Plugin::Proxies.register self, java_class
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -10,10 +10,6 @@ describe Jenkins::Launcher do
|
|
10
10
|
@launcher = Jenkins::Launcher.new(@native)
|
11
11
|
end
|
12
12
|
|
13
|
-
it "can be instantiated" do
|
14
|
-
Jenkins::Launcher.new
|
15
|
-
end
|
16
|
-
|
17
13
|
describe "execute" do
|
18
14
|
it "passes a simple command to a native launcher" do
|
19
15
|
@starter.should_receive(:envs).with({})
|
@@ -35,7 +35,8 @@ describe Jenkins::Model::Action do
|
|
35
35
|
private
|
36
36
|
|
37
37
|
def new_action(&body)
|
38
|
-
action = Class.new
|
38
|
+
action = Class.new
|
39
|
+
action.send(:include, Jenkins::Model::Action)
|
39
40
|
action.class_eval(&body) if block_given?
|
40
41
|
return action
|
41
42
|
end
|
@@ -5,8 +5,8 @@ describe Jenkins::Model::Build do
|
|
5
5
|
include SpecHelper
|
6
6
|
|
7
7
|
before :each do
|
8
|
-
@native =
|
9
|
-
@native.buildEnvironments
|
8
|
+
@native = mock(Java.hudson.model.AbstractBuild)
|
9
|
+
@native.stub(:buildEnvironments).and_return(java.util.ArrayList.new)
|
10
10
|
@build = Jenkins::Model::Build.new(@native)
|
11
11
|
end
|
12
12
|
|
@@ -50,7 +50,6 @@ describe Jenkins::Model::Build do
|
|
50
50
|
pending "we need to get some full stack testing for this to fully work"
|
51
51
|
@build.env['FOO'] = 'bar'
|
52
52
|
@build.env[:bar] = :baz
|
53
|
-
Java.org.mockito.Mockito.when(@native.getEvironment(nil)).thenCallRealMethod()
|
54
53
|
@vars = @native.getEnvironment(nil)
|
55
54
|
end
|
56
55
|
|
@@ -4,14 +4,14 @@ describe Jenkins::Model::Describable do
|
|
4
4
|
|
5
5
|
before do
|
6
6
|
@plugin = mock(Jenkins::Plugin)
|
7
|
-
Jenkins
|
7
|
+
Jenkins.stub(:plugin).and_return(@plugin)
|
8
8
|
end
|
9
9
|
|
10
10
|
describe "when mixed into a class" do
|
11
11
|
before do
|
12
12
|
@class = Class.new
|
13
|
-
@class.send(:include, Jenkins::Model::Describable)
|
14
13
|
@plugin.stub(:register_describable)
|
14
|
+
@class.send(:include, Jenkins::Model::Describable)
|
15
15
|
end
|
16
16
|
|
17
17
|
|
@@ -30,11 +30,17 @@ describe Jenkins::Model::Describable do
|
|
30
30
|
describe "a subclass of that class" do
|
31
31
|
before do
|
32
32
|
@class.describe_as java.lang.Object
|
33
|
+
def @class.to_s; "SuperClass" end
|
33
34
|
@subclass = Class.new(@class)
|
35
|
+
def @subclass.to_s; "SubClass" end
|
34
36
|
end
|
35
37
|
|
36
|
-
it "is registered as an extension
|
37
|
-
@plugin.should have_received(:register_describable).with(@subclass
|
38
|
+
it "is registered as an extension" do
|
39
|
+
@plugin.should have_received(:register_describable).with(@subclass)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "has the same java type as its superclass" do
|
43
|
+
@subclass.describe_as_type.should eql java.lang.Object.java_class
|
38
44
|
end
|
39
45
|
|
40
46
|
describe ". a sub-subclass" do
|
@@ -43,20 +49,29 @@ describe Jenkins::Model::Describable do
|
|
43
49
|
end
|
44
50
|
|
45
51
|
it "is also registered as an extension of the original java type" do
|
46
|
-
@plugin.should have_received(:register_describable).with(@subsubclass
|
52
|
+
@plugin.should have_received(:register_describable).with(@subsubclass)
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'inherits its describe_as_type' do
|
56
|
+
@subsubclass.describe_as_type.should eql java.lang.Object.java_class
|
47
57
|
end
|
48
58
|
end
|
49
59
|
end
|
50
60
|
|
51
61
|
describe "with a custom descriptor type" do
|
52
|
-
|
62
|
+
before do
|
53
63
|
@class.describe_as java.lang.Object, :with => java.lang.String
|
54
64
|
@subclass = Class.new(@class)
|
55
|
-
|
65
|
+
end
|
66
|
+
it "registers that custom descriptor" do
|
67
|
+
@plugin.should have_received(:register_describable).with(@subclass)
|
56
68
|
end
|
57
69
|
it "must be a real java class" do
|
58
70
|
lambda {@class.describe_as java.lang.Object, :with => Object}.should raise_error(Jenkins::Model::Describable::DescribableError)
|
59
71
|
end
|
72
|
+
it "inherits the descriptor type" do
|
73
|
+
@subclass.descriptor_is.should eql java.lang.String.java_class
|
74
|
+
end
|
60
75
|
end
|
61
76
|
end
|
62
77
|
end
|
data/spec/jenkins/model_spec.rb
CHANGED
@@ -61,34 +61,6 @@ describe Jenkins::Model do
|
|
61
61
|
child.should be_transient(:bar)
|
62
62
|
end
|
63
63
|
|
64
|
-
describe "tracking descendants" do
|
65
|
-
before do
|
66
|
-
Model.clear
|
67
|
-
end
|
68
|
-
|
69
|
-
it "captures including classes" do
|
70
|
-
cls = Class.new
|
71
|
-
cls.send(:include, Model)
|
72
|
-
Model.should be_descendant cls
|
73
|
-
end
|
74
|
-
|
75
|
-
it "captures classes that extend including classes" do
|
76
|
-
cls = Class.new
|
77
|
-
cls.send(:include, Model)
|
78
|
-
Model.should be_descendant(Class.new(cls))
|
79
|
-
end
|
80
|
-
|
81
|
-
it "captures classes that include including modules" do
|
82
|
-
m1 = Module.new
|
83
|
-
m1.send(:include, Model)
|
84
|
-
m2 = Module.new
|
85
|
-
m2.send(:include, m1)
|
86
|
-
cls = Class.new
|
87
|
-
cls.send(:include, m2)
|
88
|
-
Model.should be_descendant(Class.new(cls))
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
64
|
private
|
93
65
|
|
94
66
|
def new_model(&block)
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'jenkins/plugin/behavior'
|
3
|
+
|
4
|
+
describe Jenkins::Plugin::Behavior do
|
5
|
+
before do
|
6
|
+
module OhBehave
|
7
|
+
extend Jenkins::Plugin::Behavior
|
8
|
+
@implementations = []
|
9
|
+
def self.implementations
|
10
|
+
@implementations
|
11
|
+
end
|
12
|
+
implemented do |impl|
|
13
|
+
@implementations << impl
|
14
|
+
end
|
15
|
+
module Foo
|
16
|
+
def foo; 'foo' end
|
17
|
+
end
|
18
|
+
module Bar
|
19
|
+
def bar; 'bar' end
|
20
|
+
end
|
21
|
+
module Baz
|
22
|
+
def baz; 'baz' end
|
23
|
+
end
|
24
|
+
module Qux
|
25
|
+
def qux; 'qux' end
|
26
|
+
end
|
27
|
+
module InstanceMethods
|
28
|
+
include Foo
|
29
|
+
include Bar
|
30
|
+
end
|
31
|
+
module ClassMethods
|
32
|
+
include Baz
|
33
|
+
include Qux
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
describe "when a behavior is included into a class" do
|
38
|
+
before do
|
39
|
+
@class = Class.new
|
40
|
+
def @class.to_s; 'Behaving' end
|
41
|
+
@class.send(:include, OhBehave)
|
42
|
+
end
|
43
|
+
|
44
|
+
its "methods in ClassMethods are available to the implementing class" do
|
45
|
+
@class.baz.should eql 'baz'
|
46
|
+
@class.qux.should eql 'qux'
|
47
|
+
end
|
48
|
+
|
49
|
+
its "methods in the InstanceMethods module are available to instances" do
|
50
|
+
@class.new.tap do |i|
|
51
|
+
i.foo.should eql 'foo'
|
52
|
+
i.bar.should eql 'bar'
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
its "implementation block is invoked" do
|
57
|
+
OhBehave.implementations.should be_member @class
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "and then that class is subclassed" do
|
61
|
+
before do
|
62
|
+
@subclass = Class.new(@class)
|
63
|
+
def @subclass.to_s; 'BehavingSubclass' end
|
64
|
+
end
|
65
|
+
|
66
|
+
its "methods in ClassMethods are available to the subclass" do
|
67
|
+
@subclass.baz.should eql 'baz'
|
68
|
+
@subclass.qux.should eql 'qux'
|
69
|
+
end
|
70
|
+
|
71
|
+
its 'methods in InstanceMethods are available to subclass instances' do
|
72
|
+
@subclass.new.foo.should eql 'foo'
|
73
|
+
@subclass.new.bar.should eql 'bar'
|
74
|
+
end
|
75
|
+
|
76
|
+
its 'implementation block is invoked with the subclass' do
|
77
|
+
OhBehave.implementations.should be_member @subclass
|
78
|
+
end
|
79
|
+
|
80
|
+
describe ". If it is subclassed yet again" do
|
81
|
+
before do
|
82
|
+
@subsubclass = Class.new(@subclass)
|
83
|
+
def @subsubclass.to_s; "BehavingSubSubClass" end
|
84
|
+
end
|
85
|
+
its 'implementatin block is invoked with the sub-sub-class' do
|
86
|
+
OhBehave.implementations.should be_member @subsubclass
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
describe 'when a behavior is included into another module' do
|
92
|
+
before do
|
93
|
+
@module = Module.new
|
94
|
+
@module.send(:include, OhBehave)
|
95
|
+
@class = Class.new(Object)
|
96
|
+
@class.send(:include, @module)
|
97
|
+
end
|
98
|
+
it 'reaches classes the module includes' do
|
99
|
+
@class.baz.should eql 'baz'
|
100
|
+
@class.new.foo.should eql 'foo'
|
101
|
+
end
|
102
|
+
its 'implementation callback is invoked for classes including that module' do
|
103
|
+
OhBehave.implementations.should be_member @class
|
104
|
+
end
|
105
|
+
its 'implementation callback is NOT invoked for any intervening modules' do
|
106
|
+
OhBehave.implementations.should_not be_member @module
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'rspec-spies'
|
2
3
|
|
3
4
|
describe "a class with #{Jenkins::Plugin::Proxy} mixed in" do
|
4
5
|
|
@@ -40,4 +41,17 @@ describe "a class with #{Jenkins::Plugin::Proxy} mixed in" do
|
|
40
41
|
end
|
41
42
|
end
|
42
43
|
|
44
|
+
describe "specifiying which ruby class it proxies" do
|
45
|
+
before do
|
46
|
+
@proxies = Jenkins::Plugin::Proxies
|
47
|
+
@proxies.stub(:register)
|
48
|
+
@class.class_eval do
|
49
|
+
proxy_for String
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'registers it with the global proxy registry' do
|
54
|
+
@proxies.should have_received(:register).with(String, @class)
|
55
|
+
end
|
56
|
+
end
|
43
57
|
end
|
data/spec/jenkins/plugin_spec.rb
CHANGED
@@ -3,6 +3,26 @@ require 'tmpdir'
|
|
3
3
|
|
4
4
|
describe Jenkins::Plugin do
|
5
5
|
|
6
|
+
describe Jenkins::Plugin::Lifecycle do
|
7
|
+
before do |variable|
|
8
|
+
@plugin = Jenkins::Plugin.new mock(:name => 'org.jenkinsci.ruby.RubyPlugin')
|
9
|
+
@plugin.on.start do |plugin|
|
10
|
+
@start = plugin
|
11
|
+
end
|
12
|
+
@plugin.on.stop do |plugin|
|
13
|
+
@stop = plugin
|
14
|
+
end
|
15
|
+
@plugin.start
|
16
|
+
@plugin.stop
|
17
|
+
end
|
18
|
+
it "gets a callback on start" do
|
19
|
+
@start.should be @plugin
|
20
|
+
end
|
21
|
+
it "gets a callback on stop" do
|
22
|
+
@stop.should be @plugin
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
6
26
|
describe "when plugin loads models" do
|
7
27
|
include SpecHelper
|
8
28
|
|
data/spec/spec_helper.rb
CHANGED
@@ -1,6 +1,12 @@
|
|
1
1
|
require 'java'
|
2
2
|
require 'tmpdir'
|
3
3
|
|
4
|
+
module Jenkins
|
5
|
+
def self.rspec_ewwww_gross_hack?
|
6
|
+
true
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
4
10
|
require 'jenkins/war'
|
5
11
|
for path in Dir[File.join(ENV['HOME'], '.jenkins', 'wars', Jenkins::War::VERSION, "**/*.jar")]
|
6
12
|
$CLASSPATH << path
|
@@ -10,7 +16,11 @@ $:.unshift Pathname(__FILE__).dirname.join('../lib')
|
|
10
16
|
|
11
17
|
require 'jenkins/plugin/runtime'
|
12
18
|
require 'jenkins/plugin/proxies/proxy_helper'
|
13
|
-
|
19
|
+
|
20
|
+
def puts(msg = nil)
|
21
|
+
require 'erb'
|
22
|
+
super ERB::Util.h(msg) + "<br/>"
|
23
|
+
end
|
14
24
|
|
15
25
|
module SpecHelper
|
16
26
|
# Java does not support opening directory as a File: File.open(".")
|
@@ -43,8 +53,4 @@ module SpecHelper
|
|
43
53
|
f << content
|
44
54
|
end
|
45
55
|
end
|
46
|
-
|
47
|
-
def mockito(cls)
|
48
|
-
Java.org.mockito.Mockito.mock(cls.java_class)
|
49
|
-
end
|
50
56
|
end
|