jenkins-plugin-runtime 0.1.6 → 0.1.7
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/jenkins/filepath.rb +133 -0
- data/lib/jenkins/launcher.rb +103 -6
- data/lib/jenkins/model/action.rb +11 -17
- data/lib/jenkins/model/build.rb +7 -6
- data/lib/jenkins/model/describable.rb +1 -1
- data/lib/jenkins/model/descriptor.rb +25 -1
- data/lib/jenkins/model/listener.rb +48 -23
- data/lib/jenkins/model/root_action.rb +4 -4
- data/lib/jenkins/plugin.rb +27 -8
- data/lib/jenkins/plugin/proxies.rb +5 -2
- data/lib/jenkins/plugin/proxies/action.rb +31 -0
- data/lib/jenkins/plugin/proxies/build_step.rb +32 -0
- data/lib/jenkins/plugin/proxies/builder.rb +2 -9
- data/lib/jenkins/plugin/proxies/publisher.rb +25 -0
- data/lib/jenkins/plugin/proxies/root_action.rb +35 -0
- data/lib/jenkins/plugin/runtime/version.rb +1 -1
- data/lib/jenkins/tasks/build_step.rb +23 -0
- data/lib/jenkins/tasks/builder.rb +6 -25
- data/lib/jenkins/tasks/publisher.rb +18 -0
- data/spec/jenkins/filepath_spec.rb +123 -0
- data/spec/jenkins/launcher_spec.rb +210 -0
- data/spec/jenkins/model/action_spec.rb +2 -3
- data/spec/jenkins/model/build_spec.rb +22 -3
- data/spec/jenkins/model/listener_spec.rb +9 -7
- data/spec/jenkins/plugin/proxies/builder_spec.rb +11 -0
- data/spec/jenkins/plugin/proxies/publisher_spec.rb +35 -0
- data/spec/jenkins/plugin/proxies/root_action_spec.rb +31 -0
- data/spec/jenkins/plugin/proxies_spec.rb +17 -1
- data/spec/jenkins/plugin_spec.rb +65 -0
- data/spec/spec_helper.rb +34 -0
- metadata +15 -2
@@ -0,0 +1,133 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
|
3
|
+
module Jenkins
|
4
|
+
class FilePath
|
5
|
+
Stat = Struct.new(:size, :mode, :mtime)
|
6
|
+
|
7
|
+
attr_reader :natvie
|
8
|
+
|
9
|
+
def initialize(native)
|
10
|
+
@native = native
|
11
|
+
end
|
12
|
+
|
13
|
+
# Ruby's Pathname internace
|
14
|
+
|
15
|
+
def +(name)
|
16
|
+
FilePath.new(@native.child(name))
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_s
|
20
|
+
@native.getRemote()
|
21
|
+
end
|
22
|
+
|
23
|
+
def realpath
|
24
|
+
@native.absolutize().getRemote()
|
25
|
+
end
|
26
|
+
|
27
|
+
def read(*args)
|
28
|
+
@native.read.to_io.read(*args)
|
29
|
+
end
|
30
|
+
|
31
|
+
# TODO: atime jnr-posix?
|
32
|
+
# TODO: ctime jnr-posix?
|
33
|
+
|
34
|
+
def mtime
|
35
|
+
Time.at(@native.lastModified().to_f / 1000)
|
36
|
+
end
|
37
|
+
|
38
|
+
def chmod(mask)
|
39
|
+
@native.chmod(mask)
|
40
|
+
end
|
41
|
+
|
42
|
+
# TODO: chown
|
43
|
+
# TODO: open
|
44
|
+
|
45
|
+
def rename(to)
|
46
|
+
@native.renameTo(create_filepath(to))
|
47
|
+
end
|
48
|
+
|
49
|
+
def stat
|
50
|
+
Stat.new(size, @native.mode(), mtime)
|
51
|
+
end
|
52
|
+
|
53
|
+
# TODO: utime
|
54
|
+
|
55
|
+
def basename
|
56
|
+
FilePath.new(create_filepath(@native.getName()))
|
57
|
+
end
|
58
|
+
|
59
|
+
# TODO: dirname
|
60
|
+
# TODO: extname
|
61
|
+
|
62
|
+
def exist?
|
63
|
+
@native.exists()
|
64
|
+
end
|
65
|
+
|
66
|
+
def directory?
|
67
|
+
@native.isDirectory()
|
68
|
+
end
|
69
|
+
|
70
|
+
def file?
|
71
|
+
!directory?
|
72
|
+
end
|
73
|
+
|
74
|
+
def size
|
75
|
+
@native.length()
|
76
|
+
end
|
77
|
+
|
78
|
+
def entries
|
79
|
+
@native.list().map { |native|
|
80
|
+
FilePath.new(native)
|
81
|
+
}
|
82
|
+
end
|
83
|
+
|
84
|
+
def mkdir
|
85
|
+
@native.mkdirs
|
86
|
+
end
|
87
|
+
|
88
|
+
# TODO: rmdir
|
89
|
+
# TODO: opendir
|
90
|
+
|
91
|
+
def each_entry(&block)
|
92
|
+
entries.each do |child|
|
93
|
+
yield child
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def delete
|
98
|
+
@native.delete()
|
99
|
+
end
|
100
|
+
alias unlink delete
|
101
|
+
|
102
|
+
def rmtree
|
103
|
+
@native.deleteRecursive()
|
104
|
+
end
|
105
|
+
|
106
|
+
# TODO: hudson.FilePath does not handle FilePath(".").parent since it scans
|
107
|
+
# the last "/" for file, the 2nd last "/" for directory. Can Jenkins handle
|
108
|
+
# new FilePatn(ch, "../..") correctly?
|
109
|
+
def parent
|
110
|
+
parent = Pathname.new(to_s).parent.to_s
|
111
|
+
FilePath.new(Java.hudson.FilePath.new(@native.getChannel(), parent))
|
112
|
+
end
|
113
|
+
|
114
|
+
# Original interface
|
115
|
+
|
116
|
+
def touch(time)
|
117
|
+
@native.touch(time.to_i * 1000)
|
118
|
+
end
|
119
|
+
|
120
|
+
def remote?
|
121
|
+
@native.isRemote()
|
122
|
+
end
|
123
|
+
|
124
|
+
# TODO: createTempDir
|
125
|
+
# TODO: createTempFile
|
126
|
+
|
127
|
+
private
|
128
|
+
|
129
|
+
def create_filepath(path)
|
130
|
+
Java.hudson.FilePath.new(@native.getChannel(), path)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
data/lib/jenkins/launcher.rb
CHANGED
@@ -1,8 +1,40 @@
|
|
1
|
-
|
2
1
|
module Jenkins
|
3
2
|
|
4
3
|
# Launch processes on build slaves. No functionality is currently exposed
|
5
4
|
class Launcher
|
5
|
+
class Proc
|
6
|
+
attr_reader :natvie
|
7
|
+
|
8
|
+
def initialize(native)
|
9
|
+
@native = native
|
10
|
+
end
|
11
|
+
|
12
|
+
def alive?
|
13
|
+
@native.isAlive()
|
14
|
+
end
|
15
|
+
|
16
|
+
def join
|
17
|
+
@native.join()
|
18
|
+
end
|
19
|
+
|
20
|
+
def kill
|
21
|
+
@native.kill()
|
22
|
+
nil
|
23
|
+
end
|
24
|
+
|
25
|
+
def stdin
|
26
|
+
@native.getStdin().to_io
|
27
|
+
end
|
28
|
+
|
29
|
+
def stdout
|
30
|
+
@native.getStdout().to_io
|
31
|
+
end
|
32
|
+
|
33
|
+
def stderr
|
34
|
+
@native.getStderr().to_io
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
6
38
|
# the native hudson.Launcher object
|
7
39
|
attr_reader :native
|
8
40
|
|
@@ -10,11 +42,76 @@ module Jenkins
|
|
10
42
|
@native = native
|
11
43
|
end
|
12
44
|
|
13
|
-
#
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
45
|
+
# execute([env,] command... [,options]) -> fixnum
|
46
|
+
def execute(*args)
|
47
|
+
spawn(*args).join
|
48
|
+
end
|
49
|
+
|
50
|
+
# spawn([env,] command... [,options]) -> proc
|
51
|
+
def spawn(*args)
|
52
|
+
env, cmd, options = scan_args(args)
|
53
|
+
|
54
|
+
starter = @native.launch()
|
55
|
+
starter.envs(env)
|
56
|
+
if opt_chdir = options[:chdir]
|
57
|
+
starter.pwd(opt_chdir.to_s)
|
58
|
+
end
|
59
|
+
if opt_in = options[:in]
|
60
|
+
starter.stdin(opt_in.to_inputstream)
|
61
|
+
end
|
62
|
+
if opt_out = options[:out]
|
63
|
+
if opt_out.is_a?(Jenkins::Model::Listener)
|
64
|
+
starter.stdout(Jenkins::Plugin.instance.export(opt_out))
|
65
|
+
else
|
66
|
+
starter.stdout(opt_out.to_outputstream)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
if opt_err = options[:err]
|
70
|
+
starter.stderr(opt_err.to_outputstream)
|
71
|
+
end
|
72
|
+
case cmd
|
73
|
+
when Array
|
74
|
+
starter.cmds(cmd)
|
75
|
+
else
|
76
|
+
begin
|
77
|
+
# when we are on 1.432, we can use cmdAsSingleString
|
78
|
+
starter.cmdAsSingleString(cmd.to_s)
|
79
|
+
rescue NoMethodError
|
80
|
+
# http://d.hatena.ne.jp/sikakura/20110324/1300977208 is doing
|
81
|
+
# Arrays.asList(str.split(" ")) which should be wrong.
|
82
|
+
require 'shellwords'
|
83
|
+
starter.cmds(*Shellwords.split(cmd.to_s))
|
84
|
+
end
|
85
|
+
end
|
86
|
+
Proc.new(starter.start())
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
|
91
|
+
def scan_args(args)
|
92
|
+
if args.last
|
93
|
+
if Hash === args.last
|
94
|
+
opt = args.pop
|
95
|
+
elsif args.last.respond_to?(:to_hash)
|
96
|
+
opt = args.pop.to_hash
|
97
|
+
end
|
98
|
+
end
|
99
|
+
if args.first
|
100
|
+
if Hash === args.first
|
101
|
+
env = args.shift
|
102
|
+
elsif args.first.respond_to?(:to_hash)
|
103
|
+
env = args.shift.to_hash
|
104
|
+
end
|
105
|
+
if env
|
106
|
+
env = env.inject({}) { |r, (key, value)| r[key.to_s] = value.to_s; r }
|
107
|
+
end
|
108
|
+
end
|
109
|
+
if args.length == 1
|
110
|
+
cmd = args.first
|
111
|
+
else
|
112
|
+
cmd = args
|
113
|
+
end
|
114
|
+
[env || {}, cmd, opt || {}]
|
18
115
|
end
|
19
116
|
|
20
117
|
Plugin::Proxies.register self, Java.hudson.Launcher
|
data/lib/jenkins/model/action.rb
CHANGED
@@ -1,23 +1,14 @@
|
|
1
1
|
|
2
|
-
|
2
|
+
require 'jenkins/model'
|
3
3
|
|
4
4
|
module Jenkins
|
5
5
|
module Model
|
6
|
-
module Action
|
7
|
-
include Model
|
8
6
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
else
|
15
|
-
cls.extend(ClassMethods)
|
16
|
-
cls.send(:include, InstanceMethods)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
extend Included
|
7
|
+
# TODO: I turned Action into Class from Module but it should be a bad idea.
|
8
|
+
# The change may be reverted. I used class Action for implementing a model
|
9
|
+
# as a describable but I really should do is implementing describable.
|
10
|
+
class Action
|
11
|
+
include Model
|
21
12
|
|
22
13
|
module InstanceMethods
|
23
14
|
def icon
|
@@ -28,7 +19,7 @@ module Jenkins
|
|
28
19
|
self.class.url_path
|
29
20
|
end
|
30
21
|
end
|
31
|
-
|
22
|
+
|
32
23
|
module ClassMethods
|
33
24
|
def icon(filename = nil)
|
34
25
|
filename.nil? ? @icon : @icon = filename.to_s
|
@@ -38,6 +29,9 @@ module Jenkins
|
|
38
29
|
path.nil? ? @url_path : @url_path = path.to_s
|
39
30
|
end
|
40
31
|
end
|
32
|
+
|
33
|
+
include InstanceMethods
|
34
|
+
extend ClassMethods
|
41
35
|
end
|
42
36
|
end
|
43
|
-
end
|
37
|
+
end
|
data/lib/jenkins/model/build.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'jenkins/filepath'
|
1
2
|
|
2
3
|
module Jenkins
|
3
4
|
module Model
|
@@ -13,16 +14,16 @@ module Jenkins
|
|
13
14
|
@native = native
|
14
15
|
end
|
15
16
|
|
17
|
+
def workspace
|
18
|
+
FilePath.new(@native.getWorkspace())
|
19
|
+
end
|
20
|
+
|
16
21
|
def build_var
|
17
22
|
@native.getBuildVariables()
|
18
23
|
end
|
19
24
|
|
20
|
-
def env
|
21
|
-
|
22
|
-
# TODO: not tested. dump to listener?
|
23
|
-
listener = Plugin.instance.export(listener)
|
24
|
-
end
|
25
|
-
@native.getEnvironment(listener)
|
25
|
+
def env
|
26
|
+
@native.getEnvironment(nil)
|
26
27
|
end
|
27
28
|
|
28
29
|
Jenkins::Plugin::Proxies.register self, Java.hudson.model.AbstractBuild
|
@@ -6,7 +6,7 @@ module Jenkins
|
|
6
6
|
class Descriptor < Java.hudson.model.Descriptor
|
7
7
|
|
8
8
|
def initialize(impl, plugin, java_type)
|
9
|
-
super(
|
9
|
+
super(java_type)
|
10
10
|
@impl, @plugin, @java_type = impl, plugin, java_type
|
11
11
|
end
|
12
12
|
|
@@ -14,10 +14,30 @@ module Jenkins
|
|
14
14
|
@impl.display_name
|
15
15
|
end
|
16
16
|
|
17
|
+
def getId()
|
18
|
+
"#{@plugin.name}-#{@impl.name}"
|
19
|
+
end
|
20
|
+
|
17
21
|
def getT()
|
18
22
|
@java_type
|
19
23
|
end
|
20
24
|
|
25
|
+
# TODO: We removed @name from Descriptor (see playground) so we need to use another name.
|
26
|
+
# Just use class name which is in CamelCase.
|
27
|
+
def getConfigPage
|
28
|
+
"/#{name_to_path}/config".tap { |path|
|
29
|
+
puts "getConfigPage -> #{path}"
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
# TODO: We removed @name from Descriptor (see playground) so we need to use another name.
|
34
|
+
# Just use class name which is in CamelCase.
|
35
|
+
def getGlobalConfigPage
|
36
|
+
"/#{name_to_path}/global".tap { |path|
|
37
|
+
puts "getGlobalConfigPage -> #{path}"
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
21
41
|
def newInstance(request, form)
|
22
42
|
properties = JSON.parse(form.toString(2))
|
23
43
|
properties.delete("kind")
|
@@ -34,6 +54,10 @@ module Jenkins
|
|
34
54
|
rescue ArgumentError
|
35
55
|
@impl.new
|
36
56
|
end
|
57
|
+
|
58
|
+
def name_to_path
|
59
|
+
@impl.name.split('::').join('/')
|
60
|
+
end
|
37
61
|
end
|
38
62
|
|
39
63
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'logger'
|
1
2
|
|
2
3
|
module Jenkins
|
3
4
|
module Model
|
@@ -6,42 +7,66 @@ module Jenkins
|
|
6
7
|
class Listener
|
7
8
|
|
8
9
|
# the underlying hudson.model.TaskListener object
|
9
|
-
attr_reader :
|
10
|
+
attr_reader :natvie
|
11
|
+
attr_accessor :level
|
10
12
|
|
11
13
|
def initialize(native = nil)
|
12
14
|
@native = native
|
15
|
+
@level = Logger::DEBUG
|
13
16
|
end
|
14
17
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
def
|
20
|
-
|
18
|
+
def debug?; @level <= DEBUG; end
|
19
|
+
def info?; @level <= INFO; end
|
20
|
+
def warn?; @level <= WARN; end
|
21
|
+
def error?; @level <= ERROR; end
|
22
|
+
def fatal?; @level <= FATAL; end
|
23
|
+
|
24
|
+
def debug(msg = nil, &block); add(Logger::DEBUG, msg, &block); end
|
25
|
+
def info(msg = nil, &block); add(Logger::INFO, msg, &block); end
|
26
|
+
def warn(msg = nil, &block); add(Logger::WARN, msg, &block); end
|
27
|
+
def error(msg = nil, &block); add(Logger::ERROR, msg, &block); end
|
28
|
+
def fatal(msg = nil, &block); add(Logger::FATAL, msg, &block); end
|
29
|
+
def unknown(msg = nil, &block); add(Logger::UNKNOWN, msg, &block); end
|
30
|
+
|
31
|
+
def <<(msg)
|
32
|
+
logger.write(msg.to_s)
|
21
33
|
end
|
22
34
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
35
|
+
private
|
36
|
+
|
37
|
+
def add(severity, msg = nil, &block)
|
38
|
+
severity ||= Logger::UNKNOWN
|
39
|
+
if msg.nil? && block_given?
|
40
|
+
msg = yield
|
41
|
+
end
|
42
|
+
str = msg2str(msg) + "\n"
|
43
|
+
return true if severity < @level
|
44
|
+
case severity
|
45
|
+
when Logger::DEBUG, Logger::INFO
|
46
|
+
logger.write(str)
|
47
|
+
when Logger::WARN, Logger::ERROR
|
48
|
+
@native.error(str)
|
49
|
+
else
|
50
|
+
@native.fatalError(str)
|
51
|
+
end
|
28
52
|
end
|
29
53
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
54
|
+
def msg2str(msg)
|
55
|
+
case msg
|
56
|
+
when ::String
|
57
|
+
msg
|
58
|
+
when ::Exception
|
59
|
+
"#{msg.message} (#{msg.class})\n" << (msg.backtrace || []).join("\n")
|
60
|
+
else
|
61
|
+
msg.inspect
|
62
|
+
end
|
35
63
|
end
|
36
64
|
|
37
|
-
|
38
|
-
|
39
|
-
# @param [String] msg the fatal error message
|
40
|
-
def fatal(msg)
|
41
|
-
@native.fatalError(msg.to_s)
|
65
|
+
def logger
|
66
|
+
@native.getLogger()
|
42
67
|
end
|
43
68
|
|
44
69
|
Jenkins::Plugin::Proxies.register self, Java.hudson.util.AbstractTaskListener
|
45
70
|
end
|
46
71
|
end
|
47
|
-
end
|
72
|
+
end
|