Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
jenkins
提交
386618dc
J
jenkins
项目概览
xxadev
/
jenkins
与 Fork 源项目一致
从无法访问的项目Fork
通知
3
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,发现更多精彩内容 >>
提交
386618dc
编写于
12月 18, 2011
作者:
I
imod
提交者:
Kohsuke Kawaguchi
1月 03, 2012
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
support new JenkinsPlugin type (jpi)
上级
6e02aa91
变更
18
显示空白变更内容
内联
并排
Showing
18 changed file
with
200 addition
and
88 deletion
+200
-88
core/src/main/java/hudson/ClassicPluginStrategy.java
core/src/main/java/hudson/ClassicPluginStrategy.java
+1
-1
core/src/main/java/hudson/LocalPluginManager.java
core/src/main/java/hudson/LocalPluginManager.java
+3
-3
core/src/main/java/hudson/Plugin.java
core/src/main/java/hudson/Plugin.java
+1
-1
core/src/main/java/hudson/PluginManager.java
core/src/main/java/hudson/PluginManager.java
+14
-9
core/src/main/java/hudson/PluginStrategy.java
core/src/main/java/hudson/PluginStrategy.java
+1
-1
core/src/main/java/hudson/PluginWrapper.java
core/src/main/java/hudson/PluginWrapper.java
+3
-3
core/src/main/java/hudson/cli/InstallPluginCommand.java
core/src/main/java/hudson/cli/InstallPluginCommand.java
+1
-1
core/src/main/java/hudson/init/InitStrategy.java
core/src/main/java/hudson/init/InitStrategy.java
+16
-11
core/src/main/java/hudson/model/UpdateCenter.java
core/src/main/java/hudson/model/UpdateCenter.java
+33
-2
core/src/main/java/jenkins/model/Jenkins.java
core/src/main/java/jenkins/model/Jenkins.java
+1
-1
test/src/main/java/org/jvnet/hudson/test/HudsonTestCase.java
test/src/main/java/org/jvnet/hudson/test/HudsonTestCase.java
+38
-18
test/src/main/java/org/jvnet/hudson/test/JenkinsRule.java
test/src/main/java/org/jvnet/hudson/test/JenkinsRule.java
+38
-20
test/src/main/java/org/jvnet/hudson/test/TestPluginManager.java
...rc/main/java/org/jvnet/hudson/test/TestPluginManager.java
+15
-6
test/src/main/resources/plugins/htmlpublisher.jpi
test/src/main/resources/plugins/htmlpublisher.jpi
+0
-0
test/src/main/resources/plugins/legacy.hpi
test/src/main/resources/plugins/legacy.hpi
+0
-0
test/src/main/resources/plugins/tasks.jpi
test/src/main/resources/plugins/tasks.jpi
+0
-0
test/src/test/java/hudson/PluginManagerTest.java
test/src/test/java/hudson/PluginManagerTest.java
+34
-10
test/src/test/java/hudson/util/FormFieldValidatorTest.java
test/src/test/java/hudson/util/FormFieldValidatorTest.java
+1
-1
未找到文件。
core/src/main/java/hudson/ClassicPluginStrategy.java
浏览文件 @
386618dc
...
...
@@ -86,7 +86,7 @@ public class ClassicPluginStrategy implements PluginStrategy {
File
expandDir
=
null
;
// if .hpi, this is the directory where war is expanded
boolean
isLinked
=
archive
.
getName
().
endsWith
(
".hpl"
);
boolean
isLinked
=
archive
.
getName
().
endsWith
(
".hpl"
)
||
archive
.
getName
().
endsWith
(
".jpl"
)
;
if
(
isLinked
)
{
// resolve the .hpl file to the location of the manifest file
final
String
firstLine
=
IOUtils
.
readFirstLine
(
new
FileInputStream
(
archive
),
"UTF-8"
);
...
...
core/src/main/java/hudson/LocalPluginManager.java
浏览文件 @
386618dc
...
...
@@ -52,14 +52,14 @@ public class LocalPluginManager extends PluginManager {
}
/**
* If the war file has any "/WEB-INF/plugins/*.
h
pi", extract them into the plugin directory.
* If the war file has any "/WEB-INF/plugins/*.
j
pi", extract them into the plugin directory.
*
* @return
* File names of the bundled plugins. Like {"ssh-slaves.
hpi","subvesrion.h
pi"}
* File names of the bundled plugins. Like {"ssh-slaves.
jpi","subvesrion.j
pi"}
*/
@Override
protected
Collection
<
String
>
loadBundledPlugins
()
{
// this is used in tests, when we want to override the default bundled plugins with .
hpl
versions
// this is used in tests, when we want to override the default bundled plugins with .
jpl (or .hpl)
versions
if
(
System
.
getProperty
(
"hudson.bundled.plugins"
)
!=
null
)
{
return
Collections
.
emptySet
();
}
...
...
core/src/main/java/hudson/Plugin.java
浏览文件 @
386618dc
...
...
@@ -54,7 +54,7 @@ import com.thoughtworks.xstream.XStream;
*
* <p>
* A plugin is bound to URL space of Hudson as <tt>${rootURL}/plugin/foo/</tt>,
* where "foo" is taken from your plugin name "foo.
h
pi". All your web resources
* where "foo" is taken from your plugin name "foo.
j
pi". All your web resources
* in src/main/webapp are visible from this URL, and you can also define Jelly
* views against your Plugin class, and those are visible in this URL, too.
*
...
...
core/src/main/java/hudson/PluginManager.java
浏览文件 @
386618dc
...
...
@@ -206,7 +206,7 @@ public abstract class PluginManager extends AbstractModelObject {
/**
* Inspects duplication. this happens when you run hpi:run on a bundled plugin,
* as well as putting numbered
hpi files, like "cobertura-1.0.hpi" and "cobertura-1.1.h
pi"
* as well as putting numbered
jpi files, like "cobertura-1.0.jpi" and "cobertura-1.1.j
pi"
*/
private
boolean
isDuplicate
(
PluginWrapper
p
)
{
String
shortName
=
p
.
getShortName
();
...
...
@@ -382,17 +382,17 @@ public abstract class PluginManager extends AbstractModelObject {
}
/**
* If the war file has any "/WEB-INF/plugins/
*.hpi
", extract them into the plugin directory.
* If the war file has any "/WEB-INF/plugins/
[*.jpi | *.hpi]
", extract them into the plugin directory.
*
* @return
* File names of the bundled plugins. Like {"ssh-slaves.hpi","subvesrion.
h
pi"}
* File names of the bundled plugins. Like {"ssh-slaves.hpi","subvesrion.
j
pi"}
* @throws Exception
* Any exception will be reported and halt the startup.
*/
protected
abstract
Collection
<
String
>
loadBundledPlugins
()
throws
Exception
;
/**
* Copies the bundled plugin from the given URL to the destination of the given file name (like 'abc.
h
pi'),
* Copies the bundled plugin from the given URL to the destination of the given file name (like 'abc.
j
pi'),
* with a reasonable up-to-date check. A convenience method to be used by the {@link #loadBundledPlugins()}.
*/
protected
void
copyBundledPlugin
(
URL
src
,
String
fileName
)
throws
IOException
{
...
...
@@ -639,16 +639,21 @@ public abstract class PluginManager extends AbstractModelObject {
// Parse the request
FileItem
fileItem
=
(
FileItem
)
upload
.
parseRequest
(
req
).
get
(
0
);
String
fileName
=
Util
.
getFileName
(
fileItem
.
getName
());
if
(
""
.
equals
(
fileName
))
if
(
""
.
equals
(
fileName
))
{
return
new
HttpRedirect
(
"advanced"
);
if
(!
fileName
.
endsWith
(
".hpi"
))
}
// we allow the upload of the new jpi's and the legacy hpi's
if
(!
fileName
.
endsWith
(
".jpi"
)
&&
!
fileName
.
endsWith
(
".hpi"
)){
throw
new
Failure
(
hudson
.
model
.
Messages
.
Hudson_NotAPlugin
(
fileName
));
fileItem
.
write
(
new
File
(
rootDir
,
fileName
));
}
final
String
baseName
=
FilenameUtils
.
getBaseName
(
fileName
);
fileItem
.
write
(
new
File
(
rootDir
,
baseName
+
".jpi"
));
// rename all new plugins to *.jpi
fileItem
.
delete
();
PluginWrapper
existing
=
getPlugin
(
FilenameUtils
.
getBaseName
(
fileName
)
);
if
(
existing
!=
null
&&
existing
.
isBundled
)
PluginWrapper
existing
=
getPlugin
(
baseName
);
if
(
existing
!=
null
&&
existing
.
isBundled
)
{
existing
.
doPin
();
}
pluginUploaded
=
true
;
...
...
core/src/main/java/hudson/PluginStrategy.java
浏览文件 @
386618dc
...
...
@@ -45,7 +45,7 @@ public interface PluginStrategy extends ExtensionPoint {
/**
* Creates a plugin wrapper, which provides a management interface for the plugin
* @param archive
* Either a directory that points to a pre-exploded plugin, or an
hpi file, or an h
pl file.
* Either a directory that points to a pre-exploded plugin, or an
jpi file, or an j
pl file.
*/
PluginWrapper
createPluginWrapper
(
File
archive
)
throws
IOException
;
...
...
core/src/main/java/hudson/PluginWrapper.java
浏览文件 @
386618dc
...
...
@@ -55,7 +55,7 @@ import java.util.jar.JarFile;
* for Jenkins to control {@link Plugin}.
*
* <p>
* A plug-in is packaged into a jar file whose extension is <tt>".
hpi"</tt>
,
* A plug-in is packaged into a jar file whose extension is <tt>".
jpi"</tt> (or <tt>".hpi"</tt> for backward compatability)
,
* A plugin needs to have a special manifest entry to identify what it is.
*
* <p>
...
...
@@ -115,7 +115,7 @@ public class PluginWrapper implements Comparable<PluginWrapper> {
/**
* Short name of the plugin. The artifact Id of the plugin.
* This is also used in the URL within Jenkins, so it needs
* to remain stable even when the *.
h
pi file name is changed
* to remain stable even when the *.
j
pi file name is changed
* (like Maven does.)
*/
private
final
String
shortName
;
...
...
@@ -165,7 +165,7 @@ public class PluginWrapper implements Comparable<PluginWrapper> {
/**
* @param archive
* A .
hpi archive file jar file, or a .h
pl linked plugin.
* A .
jpi archive file jar file, or a .j
pl linked plugin.
* @param manifest
* The manifest for the plugin
* @param baseResourceURL
...
...
core/src/main/java/hudson/cli/InstallPluginCommand.java
浏览文件 @
386618dc
...
...
@@ -150,6 +150,6 @@ public class InstallPluginCommand extends CLICommand {
}
private
File
getTargetFile
()
{
return
new
File
(
Jenkins
.
getInstance
().
getPluginManager
().
rootDir
,
name
+
".
h
pi"
);
return
new
File
(
Jenkins
.
getInstance
().
getPluginManager
().
rootDir
,
name
+
".
j
pi"
);
}
}
core/src/main/java/hudson/init/InitStrategy.java
浏览文件 @
386618dc
...
...
@@ -15,10 +15,10 @@ import hudson.PluginManager;
import
hudson.util.Service
;
/**
* Strategy pattern of the various key decision making during the
Hudson
initialization.
* Strategy pattern of the various key decision making during the
Jenkins
initialization.
*
* <p>
* Because the act of initializing plugins is a part of the
Hudson
initialization,
* Because the act of initializing plugins is a part of the
Jenkins
initialization,
* this extension point cannot be implemented in a plugin. You need to place your jar
* inside {@code WEB-INF/lib} instead.
*
...
...
@@ -29,27 +29,31 @@ import hudson.util.Service;
*/
public
class
InitStrategy
{
/**
* Returns the list of *.hpi and *.hpl to expand and load.
* Returns the list of *.
jpi, *.
hpi and *.hpl to expand and load.
*
* <p>
* Normally we look at {@code $JENKINS_HOME/plugins/*.
hpi}
and *.hpl.
* Normally we look at {@code $JENKINS_HOME/plugins/*.
jpi} and *.hpi
and *.hpl.
*
* @return
* never null but can be empty. The list can contain different versions of the same plugin,
* and when that happens,
Hudson
will ignore all but the first one in the list.
* and when that happens,
Jenkins
will ignore all but the first one in the list.
*/
public
List
<
File
>
listPluginArchives
(
PluginManager
pm
)
throws
IOException
{
File
[]
hpi
=
pm
.
rootDir
.
listFiles
(
new
FilterByExtension
(
".hpi"
));
// plugin jar file
File
[]
hpl
=
pm
.
rootDir
.
listFiles
(
new
FilterByExtension
(
".hpl"
));
// linked plugin. for debugging.
File
[]
jpi
=
pm
.
rootDir
.
listFiles
(
new
FilterByExtension
(
".jpi"
));
// plugin jar file
File
[]
hpi
=
pm
.
rootDir
.
listFiles
(
new
FilterByExtension
(
".hpi"
));
// plugin jar file (for backward compatibility)
File
[]
jpl
=
pm
.
rootDir
.
listFiles
(
new
FilterByExtension
(
".jpl"
));
// linked plugin. for debugging.
File
[]
hpl
=
pm
.
rootDir
.
listFiles
(
new
FilterByExtension
(
".hpl"
));
// linked plugin. for debugging. (for backward compatibility)
if
(
hpi
==
null
||
hpl
==
null
)
throw
new
IOException
(
"
Hudson
is unable to create "
+
pm
.
rootDir
+
"\nPerhaps its security privilege is insufficient"
);
throw
new
IOException
(
"
Jenkins
is unable to create "
+
pm
.
rootDir
+
"\nPerhaps its security privilege is insufficient"
);
List
<
File
>
r
=
new
ArrayList
<
File
>();
// the ordering makes sure that during the debugging we get proper precedence among duplicates.
// for example, while doing "mvn
hpi:run" on a plugin that's bundled with Hudson
, we want to the
// *.
hpl file to override the bundled
hpi file.
// for example, while doing "mvn
jpi:run" or "mvn hpi:run" on a plugin that's bundled with Jenkins
, we want to the
// *.
jpl file to override the bundled jpi/
hpi file.
getBundledPluginsFromProperty
(
r
);
r
.
addAll
(
Arrays
.
asList
(
jpl
));
r
.
addAll
(
Arrays
.
asList
(
jpi
));
r
.
addAll
(
Arrays
.
asList
(
hpl
));
r
.
addAll
(
Arrays
.
asList
(
hpi
));
...
...
@@ -109,7 +113,8 @@ public class InitStrategy {
public
boolean
accept
(
File
dir
,
String
name
)
{
return
name
.
endsWith
(
extension
)
// plugin jar file
||
name
.
endsWith
(
".hpl"
);
// linked plugin. for debugging.
||
name
.
endsWith
(
".hpl"
)
// linked plugin. for debugging. (for backward compatibility)
||
name
.
endsWith
(
".jpl"
);
// linked plugin. for debugging.
}
}
}
core/src/main/java/hudson/model/UpdateCenter.java
浏览文件 @
386618dc
...
...
@@ -36,7 +36,6 @@ import static hudson.init.InitMilestone.PLUGINS_STARTED;
import
hudson.init.Initializer
;
import
hudson.lifecycle.Lifecycle
;
import
hudson.lifecycle.RestartNotSupportedException
;
import
hudson.model.UpdateCenter.DownloadJob
;
import
hudson.model.UpdateSite.Data
;
import
hudson.model.UpdateSite.Plugin
;
import
hudson.model.listeners.SaveableListener
;
...
...
@@ -1102,6 +1101,11 @@ public class UpdateCenter extends AbstractModelObject implements Saveable {
}
protected
File
getDestination
()
{
File
baseDir
=
pm
.
rootDir
;
return
new
File
(
baseDir
,
plugin
.
name
+
".jpi"
);
}
private
File
getLegacyDestination
()
{
File
baseDir
=
pm
.
rootDir
;
return
new
File
(
baseDir
,
plugin
.
name
+
".hpi"
);
}
...
...
@@ -1145,6 +1149,29 @@ public class UpdateCenter extends AbstractModelObject implements Saveable {
public
String
toString
()
{
return
super
.
toString
()+
"[plugin="
+
plugin
.
title
+
"]"
;
}
/**
* Called when the download is completed to overwrite
* the old file with the new file.
*/
@Override
protected
void
replace
(
File
dst
,
File
src
)
throws
IOException
{
File
bak
=
Util
.
changeExtension
(
dst
,
".bak"
);
bak
.
delete
();
final
File
legacy
=
getLegacyDestination
();
if
(
legacy
.
exists
()){
legacy
.
renameTo
(
bak
);
}
else
{
dst
.
renameTo
(
bak
);
}
legacy
.
delete
();
dst
.
delete
();
// any failure up to here is no big deal
if
(!
src
.
renameTo
(
dst
))
{
throw
new
IOException
(
"Failed to rename "
+
src
+
" to "
+
dst
);
}
}
}
/**
...
...
@@ -1169,7 +1196,11 @@ public class UpdateCenter extends AbstractModelObject implements Saveable {
protected
File
getDestination
()
{
File
baseDir
=
pm
.
rootDir
;
return
new
File
(
baseDir
,
plugin
.
name
+
".hpi"
);
final
File
legacy
=
new
File
(
baseDir
,
plugin
.
name
+
".hpi"
);
if
(
legacy
.
exists
()){
return
legacy
;
}
return
new
File
(
baseDir
,
plugin
.
name
+
".jpi"
);
}
protected
File
getBackup
()
{
...
...
core/src/main/java/jenkins/model/Jenkins.java
浏览文件 @
386618dc
...
...
@@ -1101,7 +1101,7 @@ public class Jenkins extends AbstractCIBase implements ModifiableItemGroup<TopLe
* every plugin reimplementing the singleton pattern.
*
* @param clazz The plugin class (beware class-loader fun, this will probably only work
* from within the
h
pi that defines the plugin class, it may or may not work in other cases)
* from within the
j
pi that defines the plugin class, it may or may not work in other cases)
*
* @return The plugin instance.
*/
...
...
test/src/main/java/org/jvnet/hudson/test/HudsonTestCase.java
浏览文件 @
386618dc
...
...
@@ -46,6 +46,7 @@ import hudson.matrix.MatrixProject;
import
hudson.matrix.MatrixRun
;
import
hudson.maven.MavenBuild
;
import
hudson.maven.MavenEmbedder
;
import
hudson.maven.MavenEmbedderException
;
import
hudson.maven.MavenModule
;
import
hudson.maven.MavenModuleSet
;
import
hudson.maven.MavenModuleSetBuild
;
...
...
@@ -137,6 +138,7 @@ import org.apache.commons.httpclient.NameValuePair;
import
org.apache.commons.io.FileUtils
;
import
org.apache.maven.artifact.Artifact
;
import
org.apache.maven.artifact.resolver.AbstractArtifactResolutionException
;
import
org.codehaus.plexus.component.repository.exception.ComponentLookupException
;
import
org.jvnet.hudson.test.HudsonHomeLoader.CopyExisting
;
import
org.jvnet.hudson.test.recipes.Recipe
;
import
org.jvnet.hudson.test.recipes.Recipe.Runner
;
...
...
@@ -1371,7 +1373,7 @@ public abstract class HudsonTestCase extends TestCase implements RootAction {
}
/**
* If this test harness is launched for a Jenkins plugin, locate the <tt>target/test-classes/the.
h
pl</tt>
* If this test harness is launched for a Jenkins plugin, locate the <tt>target/test-classes/the.
j
pl</tt>
* and add a recipe to install that to the new Jenkins.
*
* <p>
...
...
@@ -1379,21 +1381,26 @@ public abstract class HudsonTestCase extends TestCase implements RootAction {
* packaging is <tt>hpi</tt>.
*/
protected
void
recipeLoadCurrentPlugin
()
throws
Exception
{
final
Enumeration
<
URL
>
e
=
getClass
().
getClassLoader
().
getResources
(
"the.hpl"
);
if
(!
e
.
hasMoreElements
())
return
;
// nope
final
Enumeration
<
URL
>
jpls
=
getClass
().
getClassLoader
().
getResources
(
"the.jpl"
);
final
Enumeration
<
URL
>
hpls
=
getClass
().
getClassLoader
().
getResources
(
"the.hpl"
);
final
List
<
URL
>
all
=
Collections
.
list
(
jpls
);
all
.
addAll
(
Collections
.
list
(
hpls
));
if
(
all
.
isEmpty
())
return
;
// nope
recipes
.
add
(
new
Runner
()
{
@Override
public
void
decorateHome
(
HudsonTestCase
testCase
,
File
home
)
throws
Exception
{
while
(
e
.
hasMoreElements
())
{
final
URL
hpl
=
e
.
nextElement
();
for
(
URL
hpl
:
all
)
{
// make the plugin itself available
Manifest
m
=
new
Manifest
(
hpl
.
openStream
());
String
shortName
=
m
.
getMainAttributes
().
getValue
(
"Short-Name"
);
if
(
shortName
==
null
)
throw
new
Error
(
hpl
+
" doesn't have the Short-Name attribute"
);
FileUtils
.
copyURLToFile
(
hpl
,
new
File
(
home
,
"plugins/"
+
shortName
+
".
h
pl"
));
FileUtils
.
copyURLToFile
(
hpl
,
new
File
(
home
,
"plugins/"
+
shortName
+
".
j
pl"
));
// make dependency plugins available
// TODO: probably better to read POM, but where to read from?
...
...
@@ -1412,7 +1419,7 @@ public abstract class HudsonTestCase extends TestCase implements RootAction {
String
version
=
tokens
[
1
];
File
dependencyJar
=
resolveDependencyJar
(
embedder
,
artifactId
,
version
);
File
dst
=
new
File
(
home
,
"plugins/"
+
artifactId
+
".
h
pi"
);
File
dst
=
new
File
(
home
,
"plugins/"
+
artifactId
+
".
j
pi"
);
if
(!
dst
.
exists
()
||
dst
.
lastModified
()!=
dependencyJar
.
lastModified
())
{
FileUtils
.
copyFile
(
dependencyJar
,
dst
);
}
...
...
@@ -1446,19 +1453,32 @@ public abstract class HudsonTestCase extends TestCase implements RootAction {
// found it
return
Which
.
jarFile
(
dependencyPomResource
);
}
else
{
Artifact
a
;
a
=
embedder
.
createArtifact
(
groupId
,
artifactId
,
version
,
"compile"
/*doesn't matter*/
,
"hpi"
);
try
{
// currently the most of the plugins are still hpi
return
resolvePluginFile
(
embedder
,
artifactId
,
version
,
groupId
,
"hpi"
);
}
catch
(
AbstractArtifactResolutionException
x
){
try
{
embedder
.
resolve
(
a
,
Arrays
.
asList
(
embedder
.
createRepository
(
"http://maven.glassfish.org/content/groups/public/"
,
"repo"
)),
embedder
.
getLocalRepository
());
return
a
.
getFile
(
);
}
catch
(
AbstractArtifactResolutionException
x
)
{
// but also try with the new jpi
return
resolvePluginFile
(
embedder
,
artifactId
,
version
,
groupId
,
"jpi"
);
}
catch
(
AbstractArtifactResolutionException
x2
)
{
// could be a wrong groupId
resolutionError
=
x
;
}
}
}
}
throw
new
Exception
(
"Failed to resolve plugin: "
+
artifactId
+
" version "
+
version
,
resolutionError
);
throw
new
Exception
(
"Failed to resolve plugin (tryied with types: 'jpi' and 'hpi'): "
+
artifactId
+
" version "
+
version
,
resolutionError
);
}
private
File
resolvePluginFile
(
MavenEmbedder
embedder
,
String
artifactId
,
String
version
,
String
groupId
,
String
type
)
throws
MavenEmbedderException
,
ComponentLookupException
,
AbstractArtifactResolutionException
{
final
Artifact
jpi
=
embedder
.
createArtifact
(
groupId
,
artifactId
,
version
,
"compile"
/*doesn't matter*/
,
type
);
embedder
.
resolve
(
jpi
,
Arrays
.
asList
(
embedder
.
createRepository
(
"http://maven.glassfish.org/content/groups/public/"
,
"repo"
)),
embedder
.
getLocalRepository
());
return
jpi
.
getFile
();
}
});
}
...
...
test/src/main/java/org/jvnet/hudson/test/JenkinsRule.java
浏览文件 @
386618dc
...
...
@@ -59,6 +59,7 @@ import hudson.matrix.MatrixProject;
import
hudson.matrix.MatrixRun
;
import
hudson.maven.MavenBuild
;
import
hudson.maven.MavenEmbedder
;
import
hudson.maven.MavenEmbedderException
;
import
hudson.maven.MavenModule
;
import
hudson.maven.MavenModuleSet
;
import
hudson.maven.MavenModuleSetBuild
;
...
...
@@ -128,6 +129,7 @@ import org.apache.commons.httpclient.NameValuePair;
import
org.apache.commons.io.FileUtils
;
import
org.apache.maven.artifact.Artifact
;
import
org.apache.maven.artifact.resolver.AbstractArtifactResolutionException
;
import
org.codehaus.plexus.component.repository.exception.ComponentLookupException
;
import
org.hamcrest.Matchers
;
import
org.junit.rules.TemporaryFolder
;
import
org.junit.rules.TestRule
;
...
...
@@ -1419,31 +1421,34 @@ public class JenkinsRule implements TestRule, RootAction {
}
/**
* If this test harness is launched for a Jenkins plugin, locate the <tt>target/test-classes/the.
h
pl</tt>
* If this test harness is launched for a Jenkins plugin, locate the <tt>target/test-classes/the.
j
pl</tt>
* and add a recipe to install that to the new Jenkins.
*
* <p>
* This file is created by <tt>maven-hpi-plugin</tt> at the testCompile phase when the current
* packaging is <tt>
h
pi</tt>.
* packaging is <tt>
j
pi</tt>.
*/
protected
void
recipeLoadCurrentPlugin
()
throws
Exception
{
final
Enumeration
<
URL
>
e
=
getClass
().
getClassLoader
().
getResources
(
"the.h
pl"
);
if
(!
e
.
hasMoreElements
())
return
;
// nope
final
Enumeration
<
URL
>
jpls
=
getClass
().
getClassLoader
().
getResources
(
"the.j
pl"
);
final
Enumeration
<
URL
>
hpls
=
getClass
().
getClassLoader
().
getResources
(
"the.hpl"
);
final
URL
hpl
=
e
.
nextElement
();
final
List
<
URL
>
all
=
Collections
.
list
(
jpls
);
all
.
addAll
(
Collections
.
list
(
hpls
));
if
(
all
.
isEmpty
())
return
;
// nope
recipes
.
add
(
new
JenkinsRecipe
.
Runner
()
{
@Override
public
void
decorateHome
(
JenkinsRule
testCase
,
File
home
)
throws
Exception
{
while
(
e
.
hasMoreElements
())
{
final
URL
hpl
=
e
.
nextElement
();
for
(
URL
hpl
:
all
)
{
// make the plugin itself available
Manifest
m
=
new
Manifest
(
hpl
.
openStream
());
String
shortName
=
m
.
getMainAttributes
().
getValue
(
"Short-Name"
);
if
(
shortName
==
null
)
throw
new
Error
(
hpl
+
" doesn't have the Short-Name attribute"
);
FileUtils
.
copyURLToFile
(
hpl
,
new
File
(
home
,
"plugins/"
+
shortName
+
".
h
pl"
));
FileUtils
.
copyURLToFile
(
hpl
,
new
File
(
home
,
"plugins/"
+
shortName
+
".
j
pl"
));
// make dependency plugins available
// TODO: probably better to read POM, but where to read from?
...
...
@@ -1464,7 +1469,7 @@ public class JenkinsRule implements TestRule, RootAction {
String
version
=
tokens
[
1
];
File
dependencyJar
=
resolveDependencyJar
(
embedder
,
artifactId
,
version
);
File
dst
=
new
File
(
home
,
"plugins/"
+
artifactId
+
".
h
pi"
);
File
dst
=
new
File
(
home
,
"plugins/"
+
artifactId
+
".
j
pi"
);
if
(!
dst
.
exists
()
||
dst
.
lastModified
()!=
dependencyJar
.
lastModified
())
{
FileUtils
.
copyFile
(
dependencyJar
,
dst
);
}
...
...
@@ -1498,20 +1503,33 @@ public class JenkinsRule implements TestRule, RootAction {
// found it
return
Which
.
jarFile
(
dependencyPomResource
);
}
else
{
Artifact
a
;
a
=
embedder
.
createArtifact
(
groupId
,
artifactId
,
version
,
"compile"
/*doesn't matter*/
,
"hpi"
);
try
{
embedder
.
resolve
(
a
,
Arrays
.
asList
(
embedder
.
createRepository
(
"http://maven.glassfish.org/content/groups/public/"
,
"repo"
)),
embedder
.
getLocalRepository
());
return
a
.
getFile
();
}
catch
(
AbstractArtifactResolutionException
x
)
{
// currently the most of the plugins are still hpi
return
resolvePluginFile
(
embedder
,
artifactId
,
version
,
groupId
,
"hpi"
);
}
catch
(
AbstractArtifactResolutionException
x
){
try
{
// but also try with the new jpi
return
resolvePluginFile
(
embedder
,
artifactId
,
version
,
groupId
,
"jpi"
);
}
catch
(
AbstractArtifactResolutionException
x2
){
// could be a wrong groupId
resolutionError
=
x
;
}
}
}
}
throw
new
Exception
(
"Failed to resolve plugin: "
+
artifactId
+
" version "
+
version
,
resolutionError
);
}
private
File
resolvePluginFile
(
MavenEmbedder
embedder
,
String
artifactId
,
String
version
,
String
groupId
,
String
type
)
throws
MavenEmbedderException
,
ComponentLookupException
,
AbstractArtifactResolutionException
{
final
Artifact
jpi
=
embedder
.
createArtifact
(
groupId
,
artifactId
,
version
,
"compile"
/*doesn't matter*/
,
type
);
embedder
.
resolve
(
jpi
,
Arrays
.
asList
(
embedder
.
createRepository
(
"http://maven.glassfish.org/content/groups/public/"
,
"repo"
)),
embedder
.
getLocalRepository
());
return
jpi
.
getFile
();
}
});
}
...
...
test/src/main/java/org/jvnet/hudson/test/TestPluginManager.java
浏览文件 @
386618dc
...
...
@@ -75,15 +75,18 @@ public class TestPluginManager extends PluginManager {
}
}
// If running tests for a plugin, include the plugin being tested
URL
u
=
getClass
().
getClassLoader
().
getResource
(
"the.hpl"
);
URL
u
=
getClass
().
getClassLoader
().
getResource
(
"the.jpl"
);
if
(
u
==
null
){
u
=
getClass
().
getClassLoader
().
getResource
(
"the.hpl"
);
// keep backward compatible
}
if
(
u
!=
null
)
try
{
names
.
add
(
"the.
h
pl"
);
copyBundledPlugin
(
u
,
"the.
h
pl"
);
names
.
add
(
"the.
j
pl"
);
copyBundledPlugin
(
u
,
"the.
j
pl"
);
}
catch
(
IOException
e
)
{
LOGGER
.
log
(
Level
.
SEVERE
,
"Failed to copy the.
h
pl"
,
e
);
LOGGER
.
log
(
Level
.
SEVERE
,
"Failed to copy the.
j
pl"
,
e
);
}
// and pick up test dependency *.
h
pi that are placed by maven-hpi-plugin TestDependencyMojo.
// and pick up test dependency *.
j
pi that are placed by maven-hpi-plugin TestDependencyMojo.
// and copy them into $JENKINS_HOME/plugins.
URL
index
=
getClass
().
getResource
(
"/test-dependencies/index"
);
if
(
index
!=
null
)
{
// if built with maven-hpi-plugin < 1.52 this file won't exist.
...
...
@@ -91,7 +94,13 @@ public class TestPluginManager extends PluginManager {
try
{
String
line
;
while
((
line
=
r
.
readLine
())!=
null
)
{
copyBundledPlugin
(
new
URL
(
index
,
line
+
".hpi"
),
line
+
".hpi"
);
final
URL
url
=
new
URL
(
index
,
line
+
".jpi"
);
File
f
=
new
File
(
url
.
toURI
());
if
(
f
.
exists
()){
copyBundledPlugin
(
url
,
line
+
".jpi"
);
}
else
{
copyBundledPlugin
(
new
URL
(
index
,
line
+
".hpi"
),
line
+
".jpi"
);
// fallback to hpi
}
}
}
finally
{
r
.
close
();
...
...
test/src/main/resources/plugins/htmlpublisher.
h
pi
→
test/src/main/resources/plugins/htmlpublisher.
j
pi
浏览文件 @
386618dc
文件已移动
test/src/main/resources/plugins/legacy.hpi
0 → 100644
浏览文件 @
386618dc
此差异由.gitattributes 抑制。
test/src/main/resources/plugins/tasks.
h
pi
→
test/src/main/resources/plugins/tasks.
j
pi
浏览文件 @
386618dc
文件已移动
test/src/test/java/hudson/PluginManagerTest.java
浏览文件 @
386618dc
...
...
@@ -51,30 +51,54 @@ public class PluginManagerTest extends HudsonTestCase {
/**
* Manual submission form.
*/
public
void
testUpload
()
throws
Exception
{
public
void
testUpload
Jpi
()
throws
Exception
{
HtmlPage
page
=
new
WebClient
().
goTo
(
"pluginManager/advanced"
);
HtmlForm
f
=
page
.
getFormByName
(
"uploadPlugin"
);
File
dir
=
env
.
temporaryDirectoryAllocator
.
allocate
();
File
plugin
=
new
File
(
dir
,
"tasks.
h
pi"
);
FileUtils
.
copyURLToFile
(
getClass
().
getClassLoader
().
getResource
(
"plugins/tasks.
h
pi"
),
plugin
);
File
plugin
=
new
File
(
dir
,
"tasks.
j
pi"
);
FileUtils
.
copyURLToFile
(
getClass
().
getClassLoader
().
getResource
(
"plugins/tasks.
j
pi"
),
plugin
);
f
.
getInputByName
(
"name"
).
setValueAttribute
(
plugin
.
getAbsolutePath
());
submit
(
f
);
assertTrue
(
new
File
(
hudson
.
getRootDir
(),
"plugins/tasks.hpi"
).
exists
()
);
assertTrue
(
new
File
(
hudson
.
getRootDir
(),
"plugins/tasks.jpi"
).
exists
()
);
}
/**
* Manual submission form.
*/
public
void
testUploadHpi
()
throws
Exception
{
HtmlPage
page
=
new
WebClient
().
goTo
(
"pluginManager/advanced"
);
HtmlForm
f
=
page
.
getFormByName
(
"uploadPlugin"
);
File
dir
=
env
.
temporaryDirectoryAllocator
.
allocate
();
File
plugin
=
new
File
(
dir
,
"legacy.hpi"
);
FileUtils
.
copyURLToFile
(
getClass
().
getClassLoader
().
getResource
(
"plugins/legacy.hpi"
),
plugin
);
f
.
getInputByName
(
"name"
).
setValueAttribute
(
plugin
.
getAbsolutePath
());
submit
(
f
);
// uploaded legacy plugins get renamed to *.jpi
assertTrue
(
new
File
(
hudson
.
getRootDir
(),
"plugins/legacy.jpi"
).
exists
()
);
}
/**
* Tests the effect of {@link WithPlugin}.
*/
@WithPlugin
(
"tasks.
h
pi"
)
public
void
testWithRecipe
()
throws
Exception
{
@WithPlugin
(
"tasks.
j
pi"
)
public
void
testWithRecipe
Jpi
()
throws
Exception
{
assertNotNull
(
hudson
.
getPlugin
(
"tasks"
));
}
/**
* Tests the effect of {@link WithPlugin}.
*/
@WithPlugin
(
"legacy.hpi"
)
public
void
testWithRecipeHpi
()
throws
Exception
{
assertNotNull
(
hudson
.
getPlugin
(
"legacy"
));
}
/**
* Makes sure that plugins can see Maven2 plugin that's refactored out in 1.296.
*/
@WithPlugin
(
"tasks.
h
pi"
)
@WithPlugin
(
"tasks.
j
pi"
)
public
void
testOptionalMavenDependency
()
throws
Exception
{
PluginWrapper
.
Dependency
m2
=
null
;
PluginWrapper
tasks
=
hudson
.
getPluginManager
().
getPlugin
(
"tasks"
);
...
...
@@ -98,7 +122,7 @@ public class PluginManagerTest extends HudsonTestCase {
* resolve all the classes in the system (for example, a plugin X can define an extension point
* other plugins implement, so when X loads its config it better sees all the implementations defined elsewhere)
*/
@WithPlugin
(
"tasks.
h
pi"
)
@WithPlugin
(
"tasks.
j
pi"
)
@WithPluginManager
(
PluginManagerImpl_for_testUberClassLoaderIsAvailableDuringStart
.
class
)
public
void
testUberClassLoaderIsAvailableDuringStart
()
{
assertTrue
(((
PluginManagerImpl_for_testUberClassLoaderIsAvailableDuringStart
)
hudson
.
pluginManager
).
tested
);
...
...
@@ -158,8 +182,8 @@ public class PluginManagerTest extends HudsonTestCase {
}
public
void
testInstallWithoutRestart
()
throws
Exception
{
URL
res
=
getClass
().
getClassLoader
().
getResource
(
"plugins/htmlpublisher.
h
pi"
);
File
f
=
new
File
(
jenkins
.
getRootDir
(),
"plugins/htmlpublisher.
h
pi"
);
URL
res
=
getClass
().
getClassLoader
().
getResource
(
"plugins/htmlpublisher.
j
pi"
);
File
f
=
new
File
(
jenkins
.
getRootDir
(),
"plugins/htmlpublisher.
j
pi"
);
FileUtils
.
copyURLToFile
(
res
,
f
);
jenkins
.
pluginManager
.
dynamicLoad
(
f
);
...
...
test/src/test/java/hudson/util/FormFieldValidatorTest.java
浏览文件 @
386618dc
...
...
@@ -37,7 +37,7 @@ import org.jvnet.hudson.test.recipes.WithPlugin;
*/
public
class
FormFieldValidatorTest
extends
HudsonTestCase
{
@Bug
(
2771
)
@WithPlugin
(
"tasks.
h
pi"
)
@WithPlugin
(
"tasks.
j
pi"
)
public
void
test2771
()
throws
Exception
{
FreeStyleProject
p
=
createFreeStyleProject
();
new
WebClient
().
getPage
(
p
,
"configure"
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录