Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
dream21st
jenkins
提交
69ef22f5
J
jenkins
项目概览
dream21st
/
jenkins
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
J
jenkins
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
69ef22f5
编写于
10月 24, 2012
作者:
J
Jesse Glick
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' of github.com:jenkinsci/jenkins
上级
3b91f11c
ee43b8e7
变更
21
隐藏空白更改
内联
并排
Showing
21 changed file
with
471 addition
and
66 deletion
+471
-66
changelog.html
changelog.html
+2
-3
core/src/main/java/hudson/Functions.java
core/src/main/java/hudson/Functions.java
+0
-8
core/src/main/java/hudson/Launcher.java
core/src/main/java/hudson/Launcher.java
+47
-0
core/src/main/java/hudson/model/AbstractBuild.java
core/src/main/java/hudson/model/AbstractBuild.java
+1
-13
core/src/main/java/hudson/model/AbstractProject.java
core/src/main/java/hudson/model/AbstractProject.java
+27
-6
core/src/main/java/hudson/model/AutoCompletionCandidates.java
.../src/main/java/hudson/model/AutoCompletionCandidates.java
+73
-0
core/src/main/java/hudson/model/Computer.java
core/src/main/java/hudson/model/Computer.java
+35
-0
core/src/main/java/hudson/model/Job.java
core/src/main/java/hudson/model/Job.java
+43
-0
core/src/main/java/hudson/model/ParametersDefinitionProperty.java
.../main/java/hudson/model/ParametersDefinitionProperty.java
+10
-5
core/src/main/java/hudson/model/Run.java
core/src/main/java/hudson/model/Run.java
+8
-7
core/src/main/java/hudson/slaves/EnvironmentVariablesNodeProperty.java
.../java/hudson/slaves/EnvironmentVariablesNodeProperty.java
+6
-0
core/src/main/java/hudson/slaves/NodeProperty.java
core/src/main/java/hudson/slaves/NodeProperty.java
+36
-0
core/src/main/java/hudson/tasks/BuildTrigger.java
core/src/main/java/hudson/tasks/BuildTrigger.java
+2
-11
core/src/main/java/hudson/tasks/test/AggregatedTestResultPublisher.java
...java/hudson/tasks/test/AggregatedTestResultPublisher.java
+3
-12
core/src/main/java/jenkins/util/TimeDuration.java
core/src/main/java/jenkins/util/TimeDuration.java
+52
-0
core/src/main/resources/lib/form/select/select.js
core/src/main/resources/lib/form/select/select.js
+2
-0
core/src/main/resources/lib/layout/layout.jelly
core/src/main/resources/lib/layout/layout.jelly
+1
-1
test/src/test/java/hudson/model/AutoCompletionCandidatesTest.java
.../test/java/hudson/model/AutoCompletionCandidatesTest.java
+57
-0
test/src/test/java/lib/layout/RenderOnDemandTest.java
test/src/test/java/lib/layout/RenderOnDemandTest.java
+17
-0
test/src/test/resources/lib/layout/RenderOnDemandTest/testScript.jelly
.../resources/lib/layout/RenderOnDemandTest/testScript.jelly
+49
-0
war/src/main/webapp/images/i486.jpg
war/src/main/webapp/images/i486.jpg
+0
-0
未找到文件。
changelog.html
浏览文件 @
69ef22f5
...
...
@@ -55,7 +55,8 @@ Upcoming changes</a>
<!-- Record your changes in the trunk here. -->
<div
id=
"trunk"
style=
"display:none"
>
<!--=TRUNK-BEGIN=-->
<ul
class=
image
>
<li
class=
>
<li
class=
rfe
>
Improved the auto-completion of job names to support hierarchy better.
</ul>
</div>
<!--=TRUNK-END=-->
...
...
@@ -108,8 +109,6 @@ Upcoming changes</a>
<li
class=
bug
>
Memory exhaustion parsing large test stdio from Surefire.
(
<a
href=
"https://issues.jenkins-ci.org/browse/JENKINS-15382"
>
issue 15382
</a>
)
<li
class=
rfe
>
In celebration of the release number '486', background image will be 80486 for a week.
</ul>
<h3><a
name=
v1.485
>
What's new in 1.485
</a>
(2012/10/07)
</h3>
<ul
class=
image
>
...
...
core/src/main/java/hudson/Functions.java
浏览文件 @
69ef22f5
...
...
@@ -1537,12 +1537,4 @@ public class Functions {
DecimalFormat
format
=
new
DecimalFormat
(
"##.00"
);
return
format
.
format
(
number
)
+
" "
+
measure
;
}
/**
* 1.486 special
*/
public
static
String
getBackgroundImage
()
{
// for one week.
return
System
.
currentTimeMillis
()
<
1350696100409L
?
"i486.jpg"
:
"jenkins.png"
;
}
}
core/src/main/java/hudson/Launcher.java
浏览文件 @
69ef22f5
...
...
@@ -51,6 +51,7 @@ import java.util.Arrays;
import
java.util.Map
;
import
java.util.List
;
import
java.util.ArrayList
;
import
java.util.Map.Entry
;
import
java.util.logging.Level
;
import
java.util.logging.Logger
;
...
...
@@ -690,6 +691,52 @@ public abstract class Launcher {
};
}
/**
* Returns a decorated {@link Launcher} that automatically adds the specified environment
* variables.
*
* Those that are specified in {@link ProcStarter#envs(String...)} will take precedence over
* what's specified here.
*
* @since 1.489
*/
public
final
Launcher
decorateByEnv
(
EnvVars
_env
)
{
final
EnvVars
env
=
new
EnvVars
(
_env
);
final
Launcher
outer
=
this
;
return
new
Launcher
(
outer
)
{
@Override
public
Proc
launch
(
ProcStarter
starter
)
throws
IOException
{
EnvVars
e
=
new
EnvVars
(
env
);
if
(
starter
.
envs
!=
null
)
{
for
(
int
i
=
0
;
i
<
starter
.
envs
.
length
;
i
+=
2
)
e
.
put
(
starter
.
envs
[
i
],
starter
.
envs
[
i
+
1
]);
}
String
[]
r
=
new
String
[
e
.
size
()*
2
];
int
idx
=
0
;
for
(
Entry
<
String
,
String
>
i
:
e
.
entrySet
())
{
r
[
idx
++]
=
i
.
getKey
();
r
[
idx
++]
=
i
.
getValue
();
}
starter
.
envs
=
r
;
return
outer
.
launch
(
starter
);
}
@Override
public
Channel
launchChannel
(
String
[]
cmd
,
OutputStream
out
,
FilePath
workDir
,
Map
<
String
,
String
>
envVars
)
throws
IOException
,
InterruptedException
{
EnvVars
e
=
new
EnvVars
(
env
);
e
.
putAll
(
envVars
);
return
outer
.
launchChannel
(
cmd
,
out
,
workDir
,
e
);
}
@Override
public
void
kill
(
Map
<
String
,
String
>
modelEnvVars
)
throws
IOException
,
InterruptedException
{
outer
.
kill
(
modelEnvVars
);
}
};
}
/**
* {@link Launcher} that launches process locally.
*/
...
...
core/src/main/java/hudson/model/AbstractBuild.java
浏览文件 @
69ef22f5
...
...
@@ -931,19 +931,7 @@ public abstract class AbstractBuild<P extends AbstractProject<P,R>,R extends Abs
FilePath
ws
=
getWorkspace
();
if
(
ws
!=
null
)
// if this is done very early on in the build, workspace may not be decided yet. see HUDSON-3997
env
.
put
(
"WORKSPACE"
,
ws
.
getRemote
());
// servlet container may have set CLASSPATH in its launch script,
// so don't let that inherit to the new child process.
// see http://www.nabble.com/Run-Job-with-JDK-1.4.2-tf4468601.html
env
.
put
(
"CLASSPATH"
,
""
);
JDK
jdk
=
project
.
getJDK
();
if
(
jdk
!=
null
)
{
Computer
computer
=
Computer
.
currentComputer
();
if
(
computer
!=
null
)
{
// just in case were not in a build
jdk
=
jdk
.
forNode
(
computer
.
getNode
(),
log
);
}
jdk
.
buildEnvVars
(
env
);
}
project
.
getScm
().
buildEnvVars
(
this
,
env
);
if
(
buildEnvironments
!=
null
)
...
...
core/src/main/java/hudson/model/AbstractProject.java
浏览文件 @
69ef22f5
...
...
@@ -28,6 +28,7 @@
package
hudson.model
;
import
com.infradna.tool.bridge_method_injector.WithBridgeMethods
;
import
hudson.EnvVars
;
import
hudson.Functions
;
import
antlr.ANTLRException
;
import
hudson.AbortException
;
...
...
@@ -87,6 +88,7 @@ import jenkins.model.lazy.AbstractLazyLoadRunMap.Direction;
import
jenkins.scm.DefaultSCMCheckoutStrategyImpl
;
import
jenkins.scm.SCMCheckoutStrategy
;
import
jenkins.scm.SCMCheckoutStrategyDescriptor
;
import
jenkins.util.TimeDuration
;
import
net.sf.json.JSONObject
;
import
org.kohsuke.accmod.Restricted
;
import
org.kohsuke.accmod.restrictions.NoExternalUse
;
...
...
@@ -299,6 +301,21 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
updateTransientActions
();
}
@Override
public
EnvVars
getEnvironment
(
Node
node
,
TaskListener
listener
)
throws
IOException
,
InterruptedException
{
EnvVars
env
=
super
.
getEnvironment
(
node
,
listener
);
JDK
jdk
=
getJDK
();
if
(
jdk
!=
null
)
{
if
(
node
!=
null
)
{
// just in case were not in a build
jdk
=
jdk
.
forNode
(
node
,
listener
);
}
jdk
.
buildEnvVars
(
env
);
}
return
env
;
}
@Override
protected
void
performDelete
()
throws
IOException
,
InterruptedException
{
// prevent a new build while a delete operation is in progress
...
...
@@ -1446,7 +1463,7 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
// so better throughput is achieved over time (modulo the initial cost of creating that many workspaces)
// by having multiple workspaces
WorkspaceList
.
Lease
lease
=
l
.
acquire
(
ws
,
!
concurrentBuild
);
Launcher
launcher
=
ws
.
createLauncher
(
listener
);
Launcher
launcher
=
ws
.
createLauncher
(
listener
)
.
decorateByEnv
(
getEnvironment
(
lb
.
getBuiltOn
(),
listener
))
;
try
{
LOGGER
.
fine
(
"Polling SCM changes of "
+
getName
());
if
(
pollingBaseline
==
null
)
// see NOTE-NO-BASELINE above
...
...
@@ -1694,20 +1711,21 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
/**
* Schedules a new build command.
*/
public
void
doBuild
(
StaplerRequest
req
,
StaplerResponse
rsp
)
throws
IOException
,
ServletException
{
public
void
doBuild
(
StaplerRequest
req
,
StaplerResponse
rsp
,
@QueryParameter
TimeDuration
delay
)
throws
IOException
,
ServletException
{
if
(
delay
==
null
)
delay
=
new
TimeDuration
(
getQuietPeriod
());
BuildAuthorizationToken
.
checkPermission
(
this
,
authToken
,
req
,
rsp
);
// if a build is parameterized, let that take over
ParametersDefinitionProperty
pp
=
getProperty
(
ParametersDefinitionProperty
.
class
);
if
(
pp
!=
null
)
{
pp
.
_doBuild
(
req
,
rsp
);
pp
.
_doBuild
(
req
,
rsp
,
delay
);
return
;
}
if
(!
isBuildable
())
throw
HttpResponses
.
error
(
SC_INTERNAL_SERVER_ERROR
,
new
IOException
(
getFullName
()+
" is not buildable"
));
Jenkins
.
getInstance
().
getQueue
().
schedule
(
this
,
getDelay
(
req
),
getBuildCause
(
req
));
Jenkins
.
getInstance
().
getQueue
().
schedule
(
this
,
(
int
)
delay
.
getTime
(
),
getBuildCause
(
req
));
rsp
.
forwardToPreviousPage
(
req
);
}
...
...
@@ -1728,6 +1746,9 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
/**
* Computes the delay by taking the default value and the override in the request parameter into the account.
*
* @deprecated as of 1.488
* Inject {@link TimeDuration}.
*/
public
int
getDelay
(
StaplerRequest
req
)
throws
ServletException
{
String
delay
=
req
.
getParameter
(
"delay"
);
...
...
@@ -1747,12 +1768,12 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
* Supports build trigger with parameters via an HTTP GET or POST.
* Currently only String parameters are supported.
*/
public
void
doBuildWithParameters
(
StaplerRequest
req
,
StaplerResponse
rsp
)
throws
IOException
,
ServletException
{
public
void
doBuildWithParameters
(
StaplerRequest
req
,
StaplerResponse
rsp
,
@QueryParameter
TimeDuration
delay
)
throws
IOException
,
ServletException
{
BuildAuthorizationToken
.
checkPermission
(
this
,
authToken
,
req
,
rsp
);
ParametersDefinitionProperty
pp
=
getProperty
(
ParametersDefinitionProperty
.
class
);
if
(
pp
!=
null
)
{
pp
.
buildWithParameters
(
req
,
rsp
);
pp
.
buildWithParameters
(
req
,
rsp
,
delay
);
}
else
{
throw
new
IllegalStateException
(
"This build is not parameterized!"
);
}
...
...
core/src/main/java/hudson/model/AutoCompletionCandidates.java
浏览文件 @
69ef22f5
...
...
@@ -25,6 +25,7 @@
package
hudson.model
;
import
hudson.search.Search
;
import
jenkins.model.Jenkins
;
import
org.kohsuke.stapler.HttpResponse
;
import
org.kohsuke.stapler.StaplerRequest
;
import
org.kohsuke.stapler.StaplerResponse
;
...
...
@@ -71,4 +72,76 @@ public class AutoCompletionCandidates implements HttpResponse {
}
rsp
.
serveExposedBean
(
req
,
r
,
Flavor
.
JSON
);
}
/**
* Auto-completes possible job names.
*
* @param type
* Limit the auto-completion to the subtype of this type.
* @param value
* The value the user has typed in. Matched as a prefix.
* @param self
* The contextual item for which the auto-completion is provided to.
* For example, if you are configuring a job, this is the job being configured.
* @param container
* The nearby contextual {@link ItemGroup} to resolve relative job names from.
*/
public
static
<
T
extends
Item
>
AutoCompletionCandidates
ofJobNames
(
final
Class
<
T
>
type
,
final
String
value
,
Item
self
,
ItemGroup
container
)
{
if
(
self
==
container
)
container
=
self
.
getParent
();
final
AutoCompletionCandidates
candidates
=
new
AutoCompletionCandidates
();
class
Visitor
extends
ItemVisitor
{
String
prefix
;
Visitor
(
String
prefix
)
{
this
.
prefix
=
prefix
;
}
@Override
public
void
onItem
(
Item
i
)
{
String
n
=
contextualNameOf
(
i
);
if
((
n
.
startsWith
(
value
)
||
value
.
startsWith
(
n
))
// 'foobar' is a valid candidate if the current value is 'foo'.
// Also, we need to visit 'foo' if the current value is 'foo/bar'
&&
(
value
.
length
()>
n
.
length
()
||
!
n
.
substring
(
value
.
length
()).
contains
(
"/"
))
// but 'foobar/zot' isn't if the current value is 'foo'
// we'll first show 'foobar' and then wait for the user to type '/' to show the rest
&&
i
.
hasPermission
(
Item
.
READ
)
// and read permission required
)
{
if
(
type
.
isInstance
(
i
)
&&
n
.
startsWith
(
value
))
candidates
.
add
(
n
);
// recurse
String
oldPrefix
=
prefix
;
prefix
=
n
;
super
.
onItem
(
i
);
prefix
=
oldPrefix
;
}
}
private
String
contextualNameOf
(
Item
i
)
{
if
(
prefix
.
endsWith
(
"/"
)
||
prefix
.
length
()==
0
)
return
prefix
+
i
.
getName
();
else
return
prefix
+
'/'
+
i
.
getName
();
}
}
if
(
container
==
null
||
container
==
Jenkins
.
getInstance
())
{
new
Visitor
(
""
).
onItemGroup
(
Jenkins
.
getInstance
());
}
else
{
new
Visitor
(
""
).
onItemGroup
(
container
);
if
(
value
.
startsWith
(
"/"
))
new
Visitor
(
"/"
).
onItemGroup
(
Jenkins
.
getInstance
());
for
(
String
p
=
"../"
;
value
.
startsWith
(
p
);
p
+=
"../"
)
{
container
=
((
Item
)
container
).
getParent
();
new
Visitor
(
p
).
onItemGroup
(
container
);
}
}
return
candidates
;
}
}
core/src/main/java/hudson/model/Computer.java
浏览文件 @
69ef22f5
...
...
@@ -25,6 +25,9 @@
package
hudson.model
;
import
hudson.EnvVars
;
import
hudson.FilePath
;
import
hudson.Launcher
;
import
hudson.Launcher.ProcStarter
;
import
hudson.Util
;
import
hudson.cli.declarative.CLIMethod
;
import
hudson.cli.declarative.CLIResolver
;
...
...
@@ -45,6 +48,7 @@ import hudson.security.PermissionGroup;
import
hudson.security.PermissionScope
;
import
hudson.slaves.ComputerLauncher
;
import
hudson.slaves.ComputerListener
;
import
hudson.slaves.NodeProperty
;
import
hudson.slaves.RetentionStrategy
;
import
hudson.slaves.WorkspaceList
;
import
hudson.slaves.OfflineCause
;
...
...
@@ -77,6 +81,7 @@ import javax.servlet.ServletException;
import
java.io.File
;
import
java.io.FilenameFilter
;
import
java.io.IOException
;
import
java.io.OutputStream
;
import
java.io.PrintWriter
;
import
java.io.StringWriter
;
import
java.util.*
;
...
...
@@ -877,6 +882,36 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces
return
EnvVars
.
getRemote
(
getChannel
());
}
/**
* Creates an environment variable override to be used for launching processes on this node.
*
* @see ProcStarter#envs(Map)
* @since 1.489
*/
public
EnvVars
buildEnvironment
(
TaskListener
listener
)
throws
IOException
,
InterruptedException
{
EnvVars
env
=
new
EnvVars
();
Node
node
=
getNode
();
if
(
node
==
null
)
return
env
;
// bail out
for
(
NodeProperty
nodeProperty:
Jenkins
.
getInstance
().
getGlobalNodeProperties
())
{
nodeProperty
.
buildEnvVars
(
env
,
listener
);
}
for
(
NodeProperty
nodeProperty:
node
.
getNodeProperties
())
{
nodeProperty
.
buildEnvVars
(
env
,
listener
);
}
// TODO: hmm, they don't really belong
String
rootUrl
=
Hudson
.
getInstance
().
getRootUrl
();
if
(
rootUrl
!=
null
)
{
env
.
put
(
"HUDSON_URL"
,
rootUrl
);
// Legacy.
env
.
put
(
"JENKINS_URL"
,
rootUrl
);
}
return
env
;
}
/**
* Gets the thread dump of the slave JVM.
* @return
...
...
core/src/main/java/hudson/model/Job.java
浏览文件 @
69ef22f5
...
...
@@ -26,6 +26,7 @@ package hudson.model;
import
com.google.common.base.Function
;
import
com.google.common.collect.Collections2
;
import
com.infradna.tool.bridge_method_injector.WithBridgeMethods
;
import
hudson.EnvVars
;
import
hudson.Extension
;
import
hudson.ExtensionPoint
;
import
hudson.PermalinkList
;
...
...
@@ -51,6 +52,7 @@ import hudson.util.DataSetBuilder;
import
hudson.util.DescribableList
;
import
hudson.util.FormApply
;
import
hudson.util.Graph
;
import
hudson.util.ProcessTree
;
import
hudson.util.RunList
;
import
hudson.util.ShiftedCategoryAxis
;
import
hudson.util.StackedAreaRenderer2
;
...
...
@@ -300,6 +302,47 @@ public abstract class Job<JobT extends Job<JobT, RunT>, RunT extends Run<JobT, R
return
nextBuildNumber
;
}
/**
* Builds up the environment variable map that's sufficient to identify a process
* as ours. This is used to kill run-away processes via {@link ProcessTree#killAll(Map)}.
*/
public
EnvVars
getCharacteristicEnvVars
()
{
EnvVars
env
=
new
EnvVars
();
env
.
put
(
"JENKINS_SERVER_COOKIE"
,
Util
.
getDigestOf
(
"ServerID:"
+
Jenkins
.
getInstance
().
getSecretKey
()));
env
.
put
(
"HUDSON_SERVER_COOKIE"
,
Util
.
getDigestOf
(
"ServerID:"
+
Jenkins
.
getInstance
().
getSecretKey
()));
// Legacy compatibility
env
.
put
(
"JOB_NAME"
,
getParent
().
getFullName
());
return
env
;
}
/**
* Creates an environment variable override for launching processes for this project.
*
* <p>
* This is for process launching outside the build execution (such as polling, tagging, deployment, etc.)
* that happens in a context of a specific job.
*
* @param node
* Node to eventually run a process on. The implementation must cope with this parameter being null
* (in which case none of the node specific properties would be reflected in the resulting override.)
*/
public
EnvVars
getEnvironment
(
Node
node
,
TaskListener
listener
)
throws
IOException
,
InterruptedException
{
EnvVars
env
;
if
(
node
!=
null
)
env
=
node
.
toComputer
().
buildEnvironment
(
listener
);
else
env
=
new
EnvVars
();
env
.
putAll
(
getCharacteristicEnvVars
());
// servlet container may have set CLASSPATH in its launch script,
// so don't let that inherit to the new child process.
// see http://www.nabble.com/Run-Job-with-JDK-1.4.2-tf4468601.html
env
.
put
(
"CLASSPATH"
,
""
);
return
env
;
}
/**
* Programatically updates the next build number.
*
...
...
core/src/main/java/hudson/model/ParametersDefinitionProperty.java
浏览文件 @
69ef22f5
...
...
@@ -35,9 +35,11 @@ import java.util.AbstractList;
import
javax.servlet.ServletException
;
import
jenkins.model.Jenkins
;
import
jenkins.util.TimeDuration
;
import
net.sf.json.JSONArray
;
import
net.sf.json.JSONObject
;
import
org.kohsuke.stapler.QueryParameter
;
import
org.kohsuke.stapler.StaplerRequest
;
import
org.kohsuke.stapler.StaplerResponse
;
import
org.kohsuke.stapler.export.Exported
;
...
...
@@ -104,14 +106,16 @@ public class ParametersDefinitionProperty extends JobProperty<AbstractProject<?,
* Interprets the form submission and schedules a build for a parameterized job.
*
* <p>
* This method is supposed to be invoked from {@link AbstractProject#doBuild(StaplerRequest, StaplerResponse)}.
* This method is supposed to be invoked from {@link AbstractProject#doBuild(StaplerRequest, StaplerResponse
, TimeDuration
)}.
*/
public
void
_doBuild
(
StaplerRequest
req
,
StaplerResponse
rsp
)
throws
IOException
,
ServletException
{
public
void
_doBuild
(
StaplerRequest
req
,
StaplerResponse
rsp
,
@QueryParameter
TimeDuration
delay
)
throws
IOException
,
ServletException
{
if
(!
req
.
getMethod
().
equals
(
"POST"
))
{
// show the parameter entry form.
req
.
getView
(
this
,
"index.jelly"
).
forward
(
req
,
rsp
);
return
;
}
if
(
delay
==
null
)
delay
=
new
TimeDuration
(
owner
.
getQuietPeriod
());
List
<
ParameterValue
>
values
=
new
ArrayList
<
ParameterValue
>();
...
...
@@ -130,13 +134,13 @@ public class ParametersDefinitionProperty extends JobProperty<AbstractProject<?,
}
Jenkins
.
getInstance
().
getQueue
().
schedule
(
owner
,
owner
.
getDelay
(
req
),
new
ParametersAction
(
values
),
new
CauseAction
(
new
Cause
.
UserIdCause
()));
owner
,
delay
.
getTime
(
),
new
ParametersAction
(
values
),
new
CauseAction
(
new
Cause
.
UserIdCause
()));
// send the user back to the job top page.
rsp
.
sendRedirect
(
"."
);
}
public
void
buildWithParameters
(
StaplerRequest
req
,
StaplerResponse
rsp
)
throws
IOException
,
ServletException
{
public
void
buildWithParameters
(
StaplerRequest
req
,
StaplerResponse
rsp
,
TimeDuration
delay
)
throws
IOException
,
ServletException
{
List
<
ParameterValue
>
values
=
new
ArrayList
<
ParameterValue
>();
for
(
ParameterDefinition
d:
parameterDefinitions
)
{
ParameterValue
value
=
d
.
createValue
(
req
);
...
...
@@ -144,9 +148,10 @@ public class ParametersDefinitionProperty extends JobProperty<AbstractProject<?,
values
.
add
(
value
);
}
}
if
(
delay
==
null
)
delay
=
new
TimeDuration
(
owner
.
getQuietPeriod
());
Jenkins
.
getInstance
().
getQueue
().
schedule
(
owner
,
owner
.
getDelay
(
req
),
new
ParametersAction
(
values
),
owner
.
getBuildCause
(
req
));
owner
,
delay
.
getTime
(
),
new
ParametersAction
(
values
),
owner
.
getBuildCause
(
req
));
if
(
requestWantsJson
(
req
))
{
rsp
.
setContentType
(
"application/json"
);
...
...
core/src/main/java/hudson/model/Run.java
浏览文件 @
69ef22f5
...
...
@@ -1958,12 +1958,16 @@ public abstract class Run <JobT extends Job<JobT,RunT>,RunT extends Run<JobT,Run
* @return the map with the environmental variables. Never <code>null</code>.
* @since 1.305
*/
public
EnvVars
getEnvironment
(
TaskListener
log
)
throws
IOException
,
InterruptedException
{
EnvVars
env
=
getCharacteristicEnvVars
();
public
EnvVars
getEnvironment
(
TaskListener
listener
)
throws
IOException
,
InterruptedException
{
Computer
c
=
Computer
.
currentComputer
();
Node
n
=
c
==
null
?
null
:
c
.
getNode
();
EnvVars
env
=
getParent
().
getEnvironment
(
n
,
listener
);
env
.
putAll
(
getCharacteristicEnvVars
());
// apply them in a reverse order so that higher ordinal ones can modify values added by lower ordinal ones
for
(
EnvironmentContributor
ec
:
EnvironmentContributor
.
all
().
reverseView
())
ec
.
buildEnvironmentFor
(
this
,
env
,
l
og
);
ec
.
buildEnvironmentFor
(
this
,
env
,
l
istener
);
return
env
;
}
...
...
@@ -1973,13 +1977,10 @@ public abstract class Run <JobT extends Job<JobT,RunT>,RunT extends Run<JobT,Run
* as ours. This is used to kill run-away processes via {@link ProcessTree#killAll(Map)}.
*/
public
final
EnvVars
getCharacteristicEnvVars
()
{
EnvVars
env
=
new
EnvVars
();
env
.
put
(
"JENKINS_SERVER_COOKIE"
,
Util
.
getDigestOf
(
"ServerID:"
+
Jenkins
.
getInstance
().
getSecretKey
()));
env
.
put
(
"HUDSON_SERVER_COOKIE"
,
Util
.
getDigestOf
(
"ServerID:"
+
Jenkins
.
getInstance
().
getSecretKey
()));
// Legacy compatibility
EnvVars
env
=
getParent
().
getCharacteristicEnvVars
();
env
.
put
(
"BUILD_NUMBER"
,
String
.
valueOf
(
number
));
env
.
put
(
"BUILD_ID"
,
getId
());
env
.
put
(
"BUILD_TAG"
,
"jenkins-"
+
getParent
().
getFullName
().
replace
(
'/'
,
'-'
)+
"-"
+
number
);
env
.
put
(
"JOB_NAME"
,
getParent
().
getFullName
());
return
env
;
}
...
...
core/src/main/java/hudson/slaves/EnvironmentVariablesNodeProperty.java
浏览文件 @
69ef22f5
...
...
@@ -31,6 +31,7 @@ import hudson.model.BuildListener;
import
hudson.model.ComputerSet
;
import
hudson.model.Environment
;
import
hudson.model.Node
;
import
hudson.model.TaskListener
;
import
org.kohsuke.stapler.DataBoundConstructor
;
import
org.kohsuke.stapler.Stapler
;
...
...
@@ -69,6 +70,11 @@ public class EnvironmentVariablesNodeProperty extends NodeProperty<Node> {
return
Environment
.
create
(
envVars
);
}
@Override
public
void
buildEnvVars
(
EnvVars
env
,
TaskListener
listener
)
throws
IOException
,
InterruptedException
{
env
.
putAll
(
envVars
);
}
@Extension
public
static
class
DescriptorImpl
extends
NodePropertyDescriptor
{
...
...
core/src/main/java/hudson/slaves/NodeProperty.java
浏览文件 @
69ef22f5
...
...
@@ -23,6 +23,7 @@
*/
package
hudson.slaves
;
import
hudson.EnvVars
;
import
hudson.ExtensionPoint
;
import
hudson.FilePath
;
import
hudson.Launcher
;
...
...
@@ -30,6 +31,7 @@ import hudson.DescriptorExtensionList;
import
hudson.model.Descriptor.FormException
;
import
hudson.model.Queue.BuildableItem
;
import
hudson.model.ReconfigurableDescribable
;
import
hudson.model.TaskListener
;
import
hudson.model.queue.CauseOfBlockage
;
import
hudson.scm.SCM
;
import
hudson.model.AbstractBuild
;
...
...
@@ -44,6 +46,7 @@ import org.kohsuke.stapler.StaplerRequest;
import
java.io.File
;
import
java.io.IOException
;
import
java.util.List
;
import
java.util.Map
;
/**
* Extensible property of {@link Node}.
...
...
@@ -129,6 +132,39 @@ public abstract class NodeProperty<N extends Node> implements ReconfigurableDesc
return
new
Environment
()
{};
}
/**
* Creates environment variable override for launching child processes in this node.
*
* <p>
* Whereas {@link #setUp(AbstractBuild, Launcher, BuildListener)} is used specifically for
* executing builds, this method is used for other process launch activities that happens
* outside the context of a build, such as polling, one time action (tagging, deployment, etc.)
*
* <p>
* Starting 1.488, this method and {@link #setUp(AbstractBuild, Launcher, BuildListener)} are
* layered properly. That is, for launching processes for a build, this method
* is called first and then {@link Environment#buildEnvVars(Map)} will be added on top.
* This allows implementations to put node-scoped environment variables here, then
* build scoped variables to {@link #setUp(AbstractBuild, Launcher, BuildListener)}.
*
* <p>
* Unfortunately, Jenkins core earlier than 1.488 only calls {@link #setUp(AbstractBuild, Launcher, BuildListener)},
* so if the backward compatibility with these earlier versions is important, implementations
* should invoke this method from {@link Environment#buildEnvVars(Map)}.
*
* @param env
* Manipulate this variable (normally by adding more entries.)
* Note that this is an override, so it doesn't contain environment variables that are
* currently set for the slave process itself.
* @param listener
* Can be used to send messages.
*
* @since 1.488
*/
public
void
buildEnvVars
(
EnvVars
env
,
TaskListener
listener
)
throws
IOException
,
InterruptedException
{
// default is no-op
}
public
NodeProperty
<?>
reconfigure
(
StaplerRequest
req
,
JSONObject
form
)
throws
FormException
{
return
form
==
null
?
null
:
getDescriptor
().
newInstance
(
req
,
form
);
}
...
...
core/src/main/java/hudson/tasks/BuildTrigger.java
浏览文件 @
69ef22f5
...
...
@@ -343,17 +343,8 @@ public class BuildTrigger extends Recorder implements DependecyDeclarer {
return
FormValidation
.
ok
();
}
public
AutoCompletionCandidates
doAutoCompleteChildProjects
(
@QueryParameter
String
value
)
{
AutoCompletionCandidates
candidates
=
new
AutoCompletionCandidates
();
List
<
Job
>
jobs
=
Jenkins
.
getInstance
().
getItems
(
Job
.
class
);
for
(
Job
job:
jobs
)
{
if
(
job
.
getFullName
().
startsWith
(
value
))
{
if
(
job
.
hasPermission
(
Item
.
READ
))
{
candidates
.
add
(
job
.
getFullName
());
}
}
}
return
candidates
;
public
AutoCompletionCandidates
doAutoCompleteChildProjects
(
@QueryParameter
String
value
,
@AncestorInPath
Item
self
,
@AncestorInPath
ItemGroup
container
)
{
return
AutoCompletionCandidates
.
ofJobNames
(
Job
.
class
,
value
,
self
,
container
);
}
@Extension
...
...
core/src/main/java/hudson/tasks/test/AggregatedTestResultPublisher.java
浏览文件 @
69ef22f5
...
...
@@ -32,6 +32,7 @@ import hudson.Util;
import
static
hudson
.
Util
.
fixNull
;
import
hudson.model.BuildListener
;
import
hudson.model.Fingerprint.RangeSet
;
import
hudson.model.ItemGroup
;
import
jenkins.model.Jenkins
;
import
hudson.model.Item
;
import
hudson.model.Job
;
...
...
@@ -351,19 +352,9 @@ public class AggregatedTestResultPublisher extends Recorder {
return
new
AggregatedTestResultPublisher
(
s
.
getString
(
"jobs"
),
req
.
getParameter
(
"includeFailedBuilds"
)
!=
null
);
}
public
AutoCompletionCandidates
doAutoCompleteJobs
(
@QueryParameter
String
value
)
{
AutoCompletionCandidates
candidates
=
new
AutoCompletionCandidates
();
List
<
Job
>
jobs
=
Jenkins
.
getInstance
().
getItems
(
Job
.
class
);
for
(
Job
job:
jobs
)
{
if
(
job
.
getFullName
().
startsWith
(
value
))
{
if
(
job
.
hasPermission
(
Item
.
READ
))
{
candidates
.
add
(
job
.
getFullName
());
}
}
}
return
candidates
;
public
AutoCompletionCandidates
doAutoCompleteJobs
(
@QueryParameter
String
value
,
@AncestorInPath
Item
self
,
@AncestorInPath
ItemGroup
container
)
{
return
AutoCompletionCandidates
.
ofJobNames
(
Job
.
class
,
value
,
self
,
container
);
}
}
}
core/src/main/java/jenkins/util/TimeDuration.java
0 → 100644
浏览文件 @
69ef22f5
package
jenkins.util
;
import
org.apache.commons.beanutils.Converter
;
import
java.util.concurrent.TimeUnit
;
/**
* Represents a length of something, like "3 seconds"
*
* This supports parameter injection, such as via {@link QueryParameter}.
*
* @author Kohsuke Kawaguchi
* @since 1.489
*/
public
class
TimeDuration
{
private
final
long
millis
;
public
TimeDuration
(
long
millis
)
{
this
.
millis
=
millis
;
}
public
int
getTime
()
{
return
(
int
)
millis
;
}
public
long
getTimeInMillis
()
{
return
millis
;
}
public
long
as
(
TimeUnit
t
)
{
return
t
.
convert
(
millis
,
TimeUnit
.
MILLISECONDS
);
}
public
static
class
StaplerConverterImpl
implements
Converter
{
public
Object
convert
(
Class
type
,
Object
value
)
{
if
(
value
==
null
)
return
null
;
if
(
value
instanceof
String
)
{
String
delay
=
(
String
)
value
;
try
{
// TODO: more unit handling
if
(
delay
.
endsWith
(
"sec"
))
delay
=
delay
.
substring
(
0
,
delay
.
length
()-
3
);
if
(
delay
.
endsWith
(
"secs"
))
delay
=
delay
.
substring
(
0
,
delay
.
length
()-
4
);
return
new
TimeDuration
(
Long
.
parseLong
(
delay
));
}
catch
(
NumberFormatException
e
)
{
throw
new
IllegalArgumentException
(
"Invalid time duration value: "
+
delay
);
}
}
throw
new
UnsupportedOperationException
();
}
}
}
core/src/main/resources/lib/form/select/select.js
浏览文件 @
69ef22f5
...
...
@@ -57,6 +57,8 @@ Behaviour.specify("SELECT.select", 'select', 0, function(e) {
}
}
fireEvent
(
e
,
"
filled
"
);
// let other interested parties know that the items have changed
// if the update changed the current selection, others listening to this control needs to be notified.
if
(
e
.
value
!=
value
)
fireEvent
(
e
,
"
change
"
);
}
...
...
core/src/main/resources/lib/layout/layout.jelly
浏览文件 @
69ef22f5
...
...
@@ -206,7 +206,7 @@ ${h.initPageVariables(context)}
</l:breadcrumbBar>
</table>
<table
id=
"main-table"
width=
"100%"
height=
"70%"
border=
"0"
style=
"background-image: url(${imagesURL}/
${h.backgroundImage}
);
style=
"background-image: url(${imagesURL}/
jenkins.png
);
background-repeat: no-repeat; background-position: bottom left;"
>
<tr>
<td
id=
"side-panel"
width=
"20%"
>
...
...
test/src/test/java/hudson/model/AutoCompletionCandidatesTest.java
0 → 100644
浏览文件 @
69ef22f5
package
hudson.model
;
import
hudson.matrix.AxisList
;
import
hudson.matrix.MatrixConfiguration
;
import
hudson.matrix.MatrixProject
;
import
hudson.matrix.TextAxis
;
import
org.jvnet.hudson.test.HudsonTestCase
;
import
java.util.Arrays
;
import
java.util.TreeSet
;
/**
* @author Kohsuke Kawaguchi
*/
public
class
AutoCompletionCandidatesTest
extends
HudsonTestCase
{
public
void
testCompletion
()
throws
Exception
{
FreeStyleProject
foo
=
jenkins
.
createProject
(
FreeStyleProject
.
class
,
"foo"
);
MatrixProject
bar
=
jenkins
.
createProject
(
MatrixProject
.
class
,
"bar"
);
bar
.
setAxes
(
new
AxisList
(
new
TextAxis
(
"x"
,
"1"
,
"2"
,
"3"
)));
MatrixConfiguration
x3
=
bar
.
getItem
(
"x=3"
);
AutoCompletionCandidates
c
;
c
=
AutoCompletionCandidates
.
ofJobNames
(
Item
.
class
,
""
,
foo
,
jenkins
);
assertContains
(
c
,
"foo"
,
"bar"
);
c
=
AutoCompletionCandidates
.
ofJobNames
(
Item
.
class
,
"ba"
,
foo
,
jenkins
);
assertContains
(
c
,
"bar"
);
c
=
AutoCompletionCandidates
.
ofJobNames
(
Item
.
class
,
"bar/"
,
foo
,
jenkins
);
assertContains
(
c
,
"bar/x=1"
,
"bar/x=2"
,
"bar/x=3"
);
c
=
AutoCompletionCandidates
.
ofJobNames
(
FreeStyleProject
.
class
,
""
,
foo
,
jenkins
);
assertContains
(
c
,
"foo"
);
c
=
AutoCompletionCandidates
.
ofJobNames
(
MatrixConfiguration
.
class
,
"bar/"
,
foo
,
jenkins
);
assertContains
(
c
,
"bar/x=1"
,
"bar/x=2"
,
"bar/x=3"
);
c
=
AutoCompletionCandidates
.
ofJobNames
(
Item
.
class
,
""
,
x3
,
x3
.
getParent
());
assertContains
(
c
,
"x=1"
,
"x=2"
,
"x=3"
);
c
=
AutoCompletionCandidates
.
ofJobNames
(
Item
.
class
,
"/"
,
x3
,
x3
.
getParent
());
assertContains
(
c
,
"/foo"
,
"/bar"
);
c
=
AutoCompletionCandidates
.
ofJobNames
(
Item
.
class
,
"/bar/"
,
x3
,
x3
.
getParent
());
assertContains
(
c
,
"/bar/x=1"
,
"/bar/x=2"
,
"/bar/x=3"
);
// relative path
c
=
AutoCompletionCandidates
.
ofJobNames
(
Item
.
class
,
"../"
,
x3
,
x3
.
getParent
());
assertContains
(
c
,
"../bar"
,
"../foo"
);
}
private
void
assertContains
(
AutoCompletionCandidates
c
,
String
...
values
)
{
assertEquals
(
new
TreeSet
<
String
>(
Arrays
.
asList
(
values
)),
new
TreeSet
<
String
>(
c
.
getValues
()));
}
}
test/src/test/java/lib/layout/RenderOnDemandTest.java
浏览文件 @
69ef22f5
...
...
@@ -46,4 +46,21 @@ public class RenderOnDemandTest extends HudsonTestCase {
ScriptResult
r
=
p
.
executeJavaScript
(
"var r=document.getElementsBySelector('DIV.a'); r[0].innerHTML+r[1].innerHTML+r[2].innerHTML"
);
assertEquals
(
"AlphaBravoCharlie"
,
r
.
getJavaScriptResult
().
toString
());
}
/**
* Makes sure that scripts get evaluated.
*/
public
void
testScript
()
throws
Exception
{
HtmlPage
p
=
createWebClient
().
goTo
(
"self/testScript"
);
p
.
getElementById
(
"button"
).
click
();
// all AJAX calls complete before the above method returns
ScriptResult
r
=
p
.
executeJavaScript
(
"x"
);
assertEquals
(
"foo"
,
r
.
getJavaScriptResult
().
toString
());
// if you want to test this in the browser
System
.
out
.
println
(
"Try http://localhost:"
+
localPort
+
"\"self/testScript"
);
interactiveBreak
();
}
}
test/src/test/resources/lib/layout/RenderOnDemandTest/testScript.jelly
0 → 100644
浏览文件 @
69ef22f5
<!--
The MIT License
Copyright (c) 2011, CloudBees, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-->
<!--
Config page
-->
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">
<l:layout title="">
<l:main-panel>
<input type="button" value="Test" id="button"/>
<script>
var x = null;
$("button").onclick = function() {
renderOnDemand(document.getElementsBySelector('.lazy')[0]);
}
</script>
<l:renderOnDemand clazz="lazy">
<div id="eye">hello</div>
<script>
x = "foo";
</script>
</l:renderOnDemand>
</l:main-panel>
</l:layout>
</j:jelly>
war/src/main/webapp/images/i486.jpg
已删除
100644 → 0
浏览文件 @
3b91f11c
此差异由.gitattributes 抑制。
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录