Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in / Register
Toggle navigation
S
spring-boot
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
DEMO
spring-boot
Commits
ec2a7b9a
Commit
ec2a7b9a
authored
Jun 23, 2021
by
Andy Wilkinson
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch '2.4.x' into 2.5.x
Closes gh-27045
parents
198c9873
363de4cf
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
420 additions
and
42 deletions
+420
-42
BomExtension.java
...java/org/springframework/boot/build/bom/BomExtension.java
+73
-6
CheckBom.java
...ain/java/org/springframework/boot/build/bom/CheckBom.java
+1
-1
Library.java
...main/java/org/springframework/boot/build/bom/Library.java
+166
-4
InteractiveUpgradeResolver.java
...ework/boot/build/bom/bomr/InteractiveUpgradeResolver.java
+106
-18
UpgradeApplicator.java
...pringframework/boot/build/bom/bomr/UpgradeApplicator.java
+15
-9
BomPluginIntegrationTests.java
...ngframework/boot/build/bom/BomPluginIntegrationTests.java
+28
-0
UpgradeApplicatorTests.java
...framework/boot/build/bom/bomr/UpgradeApplicatorTests.java
+21
-4
bom.gradle
buildSrc/src/test/resources/bom.gradle
+10
-0
No files found.
buildSrc/src/main/java/org/springframework/boot/build/bom/BomExtension.java
View file @
ec2a7b9a
...
...
@@ -56,10 +56,15 @@ import org.w3c.dom.Document;
import
org.w3c.dom.NodeList
;
import
org.springframework.boot.build.DeployedPlugin
;
import
org.springframework.boot.build.bom.Library.DependencyConstraintsDependencyVersions
;
import
org.springframework.boot.build.bom.Library.DependencyLockDependencyVersions
;
import
org.springframework.boot.build.bom.Library.DependencyVersions
;
import
org.springframework.boot.build.bom.Library.Exclusion
;
import
org.springframework.boot.build.bom.Library.Group
;
import
org.springframework.boot.build.bom.Library.LibraryVersion
;
import
org.springframework.boot.build.bom.Library.Module
;
import
org.springframework.boot.build.bom.Library.ProhibitedVersion
;
import
org.springframework.boot.build.bom.Library.VersionAlignment
;
import
org.springframework.boot.build.bom.bomr.version.DependencyVersion
;
import
org.springframework.boot.build.mavenplugin.MavenExec
;
import
org.springframework.util.FileCopyUtils
;
...
...
@@ -101,11 +106,17 @@ public class BomExtension {
this
.
upgradeHandler
.
gitHub
.
repository
,
this
.
upgradeHandler
.
gitHub
.
issueLabels
));
}
public
void
library
(
String
name
,
Closure
<?>
closure
)
{
this
.
library
(
name
,
null
,
closure
);
}
public
void
library
(
String
name
,
String
version
,
Closure
<?>
closure
)
{
LibraryHandler
libraryHandler
=
new
LibraryHandler
();
LibraryHandler
libraryHandler
=
new
LibraryHandler
(
version
);
ConfigureUtil
.
configure
(
closure
,
libraryHandler
);
addLibrary
(
new
Library
(
name
,
DependencyVersion
.
parse
(
version
),
libraryHandler
.
groups
,
libraryHandler
.
prohibitedVersions
));
LibraryVersion
libraryVersion
=
new
LibraryVersion
(
DependencyVersion
.
parse
(
libraryHandler
.
version
),
libraryHandler
.
versionAlignment
);
addLibrary
(
new
Library
(
name
,
libraryVersion
,
libraryHandler
.
groups
,
libraryHandler
.
prohibitedVersions
,
libraryHandler
.
dependencyVersions
));
}
public
void
effectiveBomArtifact
()
{
...
...
@@ -171,17 +182,18 @@ public class BomExtension {
this
.
libraries
.
add
(
library
);
String
versionProperty
=
library
.
getVersionProperty
();
if
(
versionProperty
!=
null
)
{
this
.
properties
.
put
(
versionProperty
,
library
.
getVersion
());
this
.
properties
.
put
(
versionProperty
,
library
.
getVersion
()
.
getVersion
()
);
}
for
(
Group
group
:
library
.
getGroups
())
{
for
(
Module
module
:
group
.
getModules
())
{
putArtifactVersionProperty
(
group
.
getId
(),
module
.
getName
(),
versionProperty
);
this
.
dependencyHandler
.
getConstraints
().
add
(
JavaPlatformPlugin
.
API_CONFIGURATION_NAME
,
createDependencyNotation
(
group
.
getId
(),
module
.
getName
(),
library
.
getVersion
()));
createDependencyNotation
(
group
.
getId
(),
module
.
getName
(),
library
.
getVersion
()
.
getVersion
()
));
}
for
(
String
bomImport
:
group
.
getBoms
())
{
putArtifactVersionProperty
(
group
.
getId
(),
bomImport
,
versionProperty
);
String
bomDependency
=
createDependencyNotation
(
group
.
getId
(),
bomImport
,
library
.
getVersion
());
String
bomDependency
=
createDependencyNotation
(
group
.
getId
(),
bomImport
,
library
.
getVersion
().
getVersion
());
this
.
dependencyHandler
.
add
(
JavaPlatformPlugin
.
API_CONFIGURATION_NAME
,
this
.
dependencyHandler
.
platform
(
bomDependency
));
this
.
dependencyHandler
.
add
(
BomPlugin
.
API_ENFORCED_CONFIGURATION_NAME
,
...
...
@@ -196,6 +208,23 @@ public class BomExtension {
private
final
List
<
ProhibitedVersion
>
prohibitedVersions
=
new
ArrayList
<>();
private
String
version
;
private
VersionAlignment
versionAlignment
;
private
DependencyVersions
dependencyVersions
;
public
LibraryHandler
(
String
version
)
{
this
.
version
=
version
;
}
public
void
version
(
String
version
,
Closure
<?>
closure
)
{
this
.
version
=
version
;
VersionHandler
versionHandler
=
new
VersionHandler
();
ConfigureUtil
.
configure
(
closure
,
versionHandler
);
this
.
versionAlignment
=
new
VersionAlignment
(
versionHandler
.
libraryName
);
}
public
void
group
(
String
id
,
Closure
<?>
closure
)
{
GroupHandler
groupHandler
=
new
GroupHandler
(
id
);
ConfigureUtil
.
configure
(
closure
,
groupHandler
);
...
...
@@ -215,6 +244,21 @@ public class BomExtension {
}
}
public
void
dependencyVersions
(
Closure
<?>
closure
)
{
DependencyVersionsHandler
dependencyVersionsHandler
=
new
DependencyVersionsHandler
();
ConfigureUtil
.
configure
(
closure
,
dependencyVersionsHandler
);
}
public
static
class
VersionHandler
{
private
String
libraryName
;
public
void
shouldAlignWithVersionFrom
(
String
libraryName
)
{
this
.
libraryName
=
libraryName
;
}
}
public
static
class
ProhibitedVersionHandler
{
private
String
reason
;
...
...
@@ -277,6 +321,29 @@ public class BomExtension {
}
public
class
DependencyVersionsHandler
{
public
void
extractFrom
(
Closure
<?>
closure
)
{
ExtractFromHandler
extractFromHandler
=
new
ExtractFromHandler
();
ConfigureUtil
.
configure
(
closure
,
extractFromHandler
);
}
public
class
ExtractFromHandler
{
public
void
dependencyLock
(
String
location
)
{
LibraryHandler
.
this
.
dependencyVersions
=
new
DependencyLockDependencyVersions
(
location
,
LibraryHandler
.
this
.
version
);
}
public
void
dependencyConstraints
(
String
location
)
{
LibraryHandler
.
this
.
dependencyVersions
=
new
DependencyConstraintsDependencyVersions
(
location
,
LibraryHandler
.
this
.
version
);
}
}
}
}
public
static
class
UpgradeHandler
{
...
...
buildSrc/src/main/java/org/springframework/boot/build/bom/CheckBom.java
View file @
ec2a7b9a
...
...
@@ -50,7 +50,7 @@ public class CheckBom extends DefaultTask {
for
(
Group
group
:
library
.
getGroups
())
{
for
(
Module
module
:
group
.
getModules
())
{
if
(!
module
.
getExclusions
().
isEmpty
())
{
checkExclusions
(
group
.
getId
(),
module
,
library
.
getVersion
());
checkExclusions
(
group
.
getId
(),
module
,
library
.
getVersion
()
.
getVersion
()
);
}
}
}
...
...
buildSrc/src/main/java/org/springframework/boot/build/bom/Library.java
View file @
ec2a7b9a
...
...
@@ -16,11 +16,20 @@
package
org
.
springframework
.
boot
.
build
.
bom
;
import
java.io.BufferedReader
;
import
java.io.IOException
;
import
java.io.InputStreamReader
;
import
java.net.URI
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Locale
;
import
java.util.Map
;
import
java.util.regex.Matcher
;
import
java.util.regex.Pattern
;
import
org.apache.maven.artifact.versioning.VersionRange
;
import
org.gradle.api.GradleException
;
import
org.springframework.boot.build.bom.bomr.version.DependencyVersion
;
...
...
@@ -34,7 +43,7 @@ public class Library {
private
final
String
name
;
private
final
Dependenc
yVersion
version
;
private
final
Librar
yVersion
version
;
private
final
List
<
Group
>
groups
;
...
...
@@ -42,6 +51,8 @@ public class Library {
private
final
List
<
ProhibitedVersion
>
prohibitedVersions
;
private
final
DependencyVersions
dependencyVersions
;
/**
* Create a new {@code Library} with the given {@code name}, {@code version}, and
* {@code groups}.
...
...
@@ -49,22 +60,24 @@ public class Library {
* @param version version of the library
* @param groups groups in the library
* @param prohibitedVersions version of the library that are prohibited
* @param dependencyVersions the library's dependency versions
*/
public
Library
(
String
name
,
DependencyVersion
version
,
List
<
Group
>
group
s
,
List
<
ProhibitedVersion
>
prohibited
Versions
)
{
public
Library
(
String
name
,
LibraryVersion
version
,
List
<
Group
>
groups
,
List
<
ProhibitedVersion
>
prohibitedVersion
s
,
DependencyVersions
dependency
Versions
)
{
this
.
name
=
name
;
this
.
version
=
version
;
this
.
groups
=
groups
;
this
.
versionProperty
=
"Spring Boot"
.
equals
(
name
)
?
null
:
name
.
toLowerCase
(
Locale
.
ENGLISH
).
replace
(
' '
,
'-'
)
+
".version"
;
this
.
prohibitedVersions
=
prohibitedVersions
;
this
.
dependencyVersions
=
dependencyVersions
;
}
public
String
getName
()
{
return
this
.
name
;
}
public
Dependenc
yVersion
getVersion
()
{
public
Librar
yVersion
getVersion
()
{
return
this
.
version
;
}
...
...
@@ -80,6 +93,10 @@ public class Library {
return
this
.
prohibitedVersions
;
}
public
DependencyVersions
getDependencyVersions
()
{
return
this
.
dependencyVersions
;
}
/**
* A version or range of versions that are prohibited from being used in a bom.
*/
...
...
@@ -104,6 +121,27 @@ public class Library {
}
public
static
class
LibraryVersion
{
private
final
DependencyVersion
version
;
private
final
VersionAlignment
versionAlignment
;
public
LibraryVersion
(
DependencyVersion
version
,
VersionAlignment
versionAlignment
)
{
this
.
version
=
version
;
this
.
versionAlignment
=
versionAlignment
;
}
public
DependencyVersion
getVersion
()
{
return
this
.
version
;
}
public
VersionAlignment
getVersionAlignment
()
{
return
this
.
versionAlignment
;
}
}
/**
* A collection of modules, Maven plugins, and Maven boms with the same group ID.
*/
...
...
@@ -194,4 +232,128 @@ public class Library {
}
public
interface
DependencyVersions
{
String
getVersion
(
String
groupId
,
String
artifactId
);
default
boolean
available
()
{
return
true
;
}
}
public
static
class
DependencyLockDependencyVersions
implements
DependencyVersions
{
private
final
Map
<
String
,
Map
<
String
,
String
>>
dependencyVersions
=
new
HashMap
<>();
private
final
String
sourceTemplate
;
private
final
String
libraryVersion
;
public
DependencyLockDependencyVersions
(
String
sourceTemplate
,
String
libraryVersion
)
{
this
.
sourceTemplate
=
sourceTemplate
;
this
.
libraryVersion
=
libraryVersion
;
}
@Override
public
boolean
available
()
{
return
!
this
.
libraryVersion
.
contains
(
"-SNAPSHOT"
);
}
@Override
public
String
getVersion
(
String
groupId
,
String
artifactId
)
{
if
(
this
.
dependencyVersions
.
isEmpty
())
{
loadVersions
();
}
return
this
.
dependencyVersions
.
computeIfAbsent
(
groupId
,
(
key
)
->
Collections
.
emptyMap
()).
get
(
artifactId
);
}
private
void
loadVersions
()
{
String
source
=
this
.
sourceTemplate
.
replace
(
"<libraryVersion>"
,
this
.
libraryVersion
);
try
{
try
(
BufferedReader
reader
=
new
BufferedReader
(
new
InputStreamReader
(
URI
.
create
(
source
).
toURL
().
openStream
())))
{
String
line
;
while
((
line
=
reader
.
readLine
())
!=
null
)
{
if
(!
line
.
startsWith
(
"#"
))
{
String
[]
components
=
line
.
split
(
":"
);
Map
<
String
,
String
>
groupDependencies
=
this
.
dependencyVersions
.
computeIfAbsent
(
components
[
0
],
(
key
)
->
new
HashMap
<>());
groupDependencies
.
put
(
components
[
1
],
components
[
2
]);
}
}
}
}
catch
(
IOException
ex
)
{
throw
new
GradleException
(
"Failed to load versions from dependency lock file '"
+
source
+
"'"
,
ex
);
}
}
}
public
static
class
DependencyConstraintsDependencyVersions
implements
DependencyVersions
{
private
static
final
Pattern
CONSTRAINT_PATTERN
=
Pattern
.
compile
(
"api \"(.+):(.+):(.+)\""
);
private
final
Map
<
String
,
Map
<
String
,
String
>>
dependencyVersions
=
new
HashMap
<>();
private
final
String
sourceTemplate
;
private
final
String
libraryVersion
;
public
DependencyConstraintsDependencyVersions
(
String
sourceTemplate
,
String
libraryVersion
)
{
this
.
sourceTemplate
=
sourceTemplate
;
this
.
libraryVersion
=
libraryVersion
;
}
@Override
public
String
getVersion
(
String
groupId
,
String
artifactId
)
{
if
(
this
.
dependencyVersions
.
isEmpty
())
{
loadVersions
();
}
return
this
.
dependencyVersions
.
computeIfAbsent
(
groupId
,
(
key
)
->
Collections
.
emptyMap
()).
get
(
artifactId
);
}
private
void
loadVersions
()
{
String
version
=
this
.
libraryVersion
;
if
(
version
.
endsWith
(
"-SNAPSHOT"
))
{
version
=
version
.
substring
(
0
,
version
.
lastIndexOf
(
'.'
))
+
".x"
;
}
String
source
=
this
.
sourceTemplate
.
replace
(
"<libraryVersion>"
,
version
);
try
{
try
(
BufferedReader
reader
=
new
BufferedReader
(
new
InputStreamReader
(
URI
.
create
(
source
).
toURL
().
openStream
())))
{
String
line
;
while
((
line
=
reader
.
readLine
())
!=
null
)
{
Matcher
matcher
=
CONSTRAINT_PATTERN
.
matcher
(
line
.
trim
());
if
(
matcher
.
matches
())
{
Map
<
String
,
String
>
groupDependencies
=
this
.
dependencyVersions
.
computeIfAbsent
(
matcher
.
group
(
1
),
(
key
)
->
new
HashMap
<>());
groupDependencies
.
put
(
matcher
.
group
(
2
),
matcher
.
group
(
3
));
}
}
}
}
catch
(
IOException
ex
)
{
throw
new
GradleException
(
"Failed to load versions from dependency constraints declared in '"
+
source
+
"'"
,
ex
);
}
}
}
public
static
class
VersionAlignment
{
private
final
String
libraryName
;
public
VersionAlignment
(
String
libraryName
)
{
this
.
libraryName
=
libraryName
;
}
public
String
getLibraryName
()
{
return
this
.
libraryName
;
}
}
}
buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/InteractiveUpgradeResolver.java
View file @
ec2a7b9a
...
...
@@ -19,19 +19,25 @@ package org.springframework.boot.build.bom.bomr;
import
java.util.ArrayList
;
import
java.util.Collection
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.HashSet
;
import
java.util.LinkedHashMap
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Set
;
import
java.util.SortedSet
;
import
java.util.stream.Collectors
;
import
org.apache.maven.artifact.versioning.DefaultArtifactVersion
;
import
org.gradle.api.InvalidUserDataException
;
import
org.gradle.api.internal.tasks.userinput.UserInputHandler
;
import
org.springframework.boot.build.bom.Library
;
import
org.springframework.boot.build.bom.Library.DependencyVersions
;
import
org.springframework.boot.build.bom.Library.Group
;
import
org.springframework.boot.build.bom.Library.Module
;
import
org.springframework.boot.build.bom.Library.ProhibitedVersion
;
import
org.springframework.boot.build.bom.Library.VersionAlignment
;
import
org.springframework.boot.build.bom.UpgradePolicy
;
import
org.springframework.boot.build.bom.bomr.version.DependencyVersion
;
import
org.springframework.util.StringUtils
;
...
...
@@ -59,39 +65,91 @@ public final class InteractiveUpgradeResolver implements UpgradeResolver {
@Override
public
List
<
Upgrade
>
resolveUpgrades
(
Collection
<
Library
>
libraries
)
{
return
libraries
.
stream
().
map
(
this
::
resolveUpgrade
).
filter
((
upgrade
)
->
upgrade
!=
null
)
.
collect
(
Collectors
.
toList
());
Map
<
String
,
Library
>
librariesByName
=
new
HashMap
<>();
for
(
Library
library
:
libraries
)
{
librariesByName
.
put
(
library
.
getName
(),
library
);
}
return
libraries
.
stream
().
map
((
library
)
->
resolveUpgrade
(
library
,
librariesByName
))
.
filter
((
upgrade
)
->
upgrade
!=
null
).
collect
(
Collectors
.
toList
());
}
private
Upgrade
resolveUpgrade
(
Library
library
)
{
private
Upgrade
resolveUpgrade
(
Library
library
,
Map
<
String
,
Library
>
libraries
)
{
List
<
VersionOption
>
versionOptions
=
getVersionOptions
(
library
,
libraries
);
if
(
versionOptions
.
isEmpty
())
{
return
null
;
}
VersionOption
current
=
new
VersionOption
(
library
.
getVersion
().
getVersion
());
VersionOption
selected
=
this
.
userInputHandler
.
selectOption
(
library
.
getName
()
+
" "
+
library
.
getVersion
().
getVersion
(),
versionOptions
,
current
);
return
(
selected
.
equals
(
current
))
?
null
:
new
Upgrade
(
library
,
selected
.
version
);
}
private
List
<
VersionOption
>
getVersionOptions
(
Library
library
,
Map
<
String
,
Library
>
libraries
)
{
if
(
library
.
getVersion
().
getVersionAlignment
()
!=
null
)
{
VersionOption
alignedVersionOption
=
alignedVersionOption
(
library
,
libraries
);
if
(!
isPermitted
(
alignedVersionOption
.
version
,
library
.
getProhibitedVersions
()))
{
throw
new
InvalidUserDataException
(
"Version alignment failed. Version "
+
alignedVersionOption
.
version
+
" from "
+
library
.
getName
()
+
" is prohibited"
);
}
return
Collections
.
singletonList
(
alignedVersionOption
);
}
Map
<
String
,
SortedSet
<
DependencyVersion
>>
moduleVersions
=
new
LinkedHashMap
<>();
DependencyVersion
libraryVersion
=
library
.
getVersion
().
getVersion
();
for
(
Group
group
:
library
.
getGroups
())
{
for
(
Module
module
:
group
.
getModules
())
{
moduleVersions
.
put
(
group
.
getId
()
+
":"
+
module
.
getName
(),
getLaterVersionsForModule
(
group
.
getId
(),
module
.
getName
(),
library
.
getVersion
()
));
getLaterVersionsForModule
(
group
.
getId
(),
module
.
getName
(),
library
Version
));
}
for
(
String
bom
:
group
.
getBoms
())
{
moduleVersions
.
put
(
group
.
getId
()
+
":"
+
bom
,
getLaterVersionsForModule
(
group
.
getId
(),
bom
,
library
.
getVersion
()
));
getLaterVersionsForModule
(
group
.
getId
(),
bom
,
library
Version
));
}
for
(
String
plugin
:
group
.
getPlugins
())
{
moduleVersions
.
put
(
group
.
getId
()
+
":"
+
plugin
,
getLaterVersionsForModule
(
group
.
getId
(),
plugin
,
library
.
getVersion
()
));
getLaterVersionsForModule
(
group
.
getId
(),
plugin
,
library
Version
));
}
}
List
<
DependencyVersion
>
allVersions
=
moduleVersions
.
values
().
stream
().
flatMap
(
SortedSet:
:
stream
).
distinct
()
.
filter
((
dependencyVersion
)
->
isPermitted
(
dependencyVersion
,
library
.
getProhibitedVersions
()))
.
collect
(
Collectors
.
toList
());
if
(
allVersions
.
isEmpty
())
{
return
null
;
return
Collections
.
emptyList
()
;
}
List
<
VersionOption
>
versionOptions
=
allVersions
.
stream
()
.
map
((
version
)
->
new
VersionOption
(
version
,
getMissingModules
(
moduleVersions
,
version
)))
return
allVersions
.
stream
()
.
map
((
version
)
->
new
Resolved
VersionOption
(
version
,
getMissingModules
(
moduleVersions
,
version
)))
.
collect
(
Collectors
.
toList
());
VersionOption
current
=
new
VersionOption
(
library
.
getVersion
(),
Collections
.
emptyList
());
VersionOption
selected
=
this
.
userInputHandler
.
selectOption
(
library
.
getName
()
+
" "
+
library
.
getVersion
(),
versionOptions
,
current
);
return
(
selected
.
equals
(
current
))
?
null
:
new
Upgrade
(
library
,
selected
.
version
);
}
private
VersionOption
alignedVersionOption
(
Library
library
,
Map
<
String
,
Library
>
libraries
)
{
VersionAlignment
versionAlignment
=
library
.
getVersion
().
getVersionAlignment
();
Library
alignmentLibrary
=
libraries
.
get
(
versionAlignment
.
getLibraryName
());
DependencyVersions
dependencyVersions
=
alignmentLibrary
.
getDependencyVersions
();
if
(
dependencyVersions
==
null
)
{
throw
new
InvalidUserDataException
(
"Cannot align with library '"
+
versionAlignment
.
getLibraryName
()
+
"' as it does not define any dependency versions"
);
}
if
(!
dependencyVersions
.
available
())
{
return
null
;
}
Set
<
String
>
versions
=
new
HashSet
<>();
for
(
Group
group
:
library
.
getGroups
())
{
for
(
Module
module
:
group
.
getModules
())
{
String
version
=
dependencyVersions
.
getVersion
(
group
.
getId
(),
module
.
getName
());
if
(
version
!=
null
)
{
versions
.
add
(
version
);
}
}
}
if
(
versions
.
isEmpty
())
{
throw
new
InvalidUserDataException
(
"Cannot align with library '"
+
versionAlignment
.
getLibraryName
()
+
"' as its dependency versions do not include any of this library's modules"
);
}
if
(
versions
.
size
()
>
1
)
{
throw
new
InvalidUserDataException
(
"Cannot align with library '"
+
versionAlignment
.
getLibraryName
()
+
"' as it uses multiple different versions of this library's modules"
);
}
String
requiredVersion
=
versions
.
iterator
().
next
();
return
new
AlignedVersionOption
(
DependencyVersion
.
parse
(
requiredVersion
),
alignmentLibrary
);
}
private
boolean
isPermitted
(
DependencyVersion
dependencyVersion
,
List
<
ProhibitedVersion
>
prohibitedVersions
)
{
...
...
@@ -125,23 +183,53 @@ public final class InteractiveUpgradeResolver implements UpgradeResolver {
return
versions
;
}
private
static
final
class
VersionOption
{
private
static
class
VersionOption
{
private
final
DependencyVersion
version
;
protected
VersionOption
(
DependencyVersion
version
)
{
this
.
version
=
version
;
}
@Override
public
String
toString
()
{
return
this
.
version
.
toString
();
}
}
private
static
final
class
AlignedVersionOption
extends
VersionOption
{
private
final
Library
alignedWith
;
private
AlignedVersionOption
(
DependencyVersion
version
,
Library
alignedWith
)
{
super
(
version
);
this
.
alignedWith
=
alignedWith
;
}
@Override
public
String
toString
()
{
return
super
.
toString
()
+
" (aligned with "
+
this
.
alignedWith
.
getName
()
+
" "
+
this
.
alignedWith
.
getVersion
().
getVersion
()
+
")"
;
}
}
private
static
final
class
ResolvedVersionOption
extends
VersionOption
{
private
final
List
<
String
>
missingModules
;
private
VersionOption
(
DependencyVersion
version
,
List
<
String
>
missingModules
)
{
this
.
version
=
version
;
private
Resolved
VersionOption
(
DependencyVersion
version
,
List
<
String
>
missingModules
)
{
super
(
version
)
;
this
.
missingModules
=
missingModules
;
}
@Override
public
String
toString
()
{
if
(
this
.
missingModules
.
isEmpty
())
{
return
this
.
version
.
toString
();
return
super
.
toString
();
}
return
this
.
version
+
" (some modules are missing: "
return
super
.
toString
()
+
" (some modules are missing: "
+
StringUtils
.
collectionToDelimitedString
(
this
.
missingModules
,
", "
)
+
")"
;
}
...
...
buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/UpgradeApplicator.java
View file @
ec2a7b9a
...
...
@@ -46,8 +46,14 @@ class UpgradeApplicator {
Matcher
matcher
=
Pattern
.
compile
(
"library\\(\""
+
upgrade
.
getLibrary
().
getName
()
+
"\", \"(.+)\"\\)"
)
.
matcher
(
buildFileContents
);
if
(!
matcher
.
find
())
{
throw
new
IllegalStateException
(
"Failed to find definition for library '"
+
upgrade
.
getLibrary
().
getName
()
+
"' in bom '"
+
this
.
buildFile
+
"'"
);
matcher
=
Pattern
.
compile
(
"library\\(\""
+
upgrade
.
getLibrary
().
getName
()
+
"\"\\) \\{\\s+version\\(\"(.+)\"\\)"
,
Pattern
.
MULTILINE
)
.
matcher
(
buildFileContents
);
if
(!
matcher
.
find
())
{
throw
new
IllegalStateException
(
"Failed to find definition for library '"
+
upgrade
.
getLibrary
().
getName
()
+
"' in bom '"
+
this
.
buildFile
+
"'"
);
}
}
String
version
=
matcher
.
group
(
1
);
if
(
version
.
startsWith
(
"${"
)
&&
version
.
endsWith
(
"}"
))
{
...
...
@@ -55,7 +61,7 @@ class UpgradeApplicator {
return
this
.
gradleProperties
;
}
else
{
updateBuildFile
(
upgrade
,
buildFileContents
);
updateBuildFile
(
upgrade
,
buildFileContents
,
matcher
.
start
(
1
),
matcher
.
end
(
1
)
);
return
this
.
buildFile
;
}
}
...
...
@@ -63,15 +69,15 @@ class UpgradeApplicator {
private
void
updateGradleProperties
(
Upgrade
upgrade
,
String
version
)
throws
IOException
{
String
property
=
version
.
substring
(
2
,
version
.
length
()
-
1
);
String
gradlePropertiesContents
=
new
String
(
Files
.
readAllBytes
(
this
.
gradleProperties
),
StandardCharsets
.
UTF_8
);
String
modified
=
gradlePropertiesContents
.
replace
(
property
+
"="
+
upgrade
.
getLibrary
().
getVersion
(),
property
+
"="
+
upgrade
.
getVersion
());
String
modified
=
gradlePropertiesContents
.
replace
(
property
+
"="
+
upgrade
.
get
Library
().
getVersion
().
getVersion
(),
property
+
"="
+
upgrade
.
get
Version
());
overwrite
(
this
.
gradleProperties
,
modified
);
}
private
void
updateBuildFile
(
Upgrade
upgrade
,
String
buildFileContents
)
throws
IOException
{
String
modified
=
buildFileContents
.
replace
(
"library(\""
+
upgrade
.
getLibrary
().
getName
()
+
"\", \""
+
upgrade
.
getLibrary
().
getVersion
()
+
"\")"
,
"library(\""
+
upgrade
.
getLibrary
().
getName
()
+
"\", \""
+
upgrade
.
getVersion
()
+
"\")"
);
private
void
updateBuildFile
(
Upgrade
upgrade
,
String
buildFileContents
,
int
versionStart
,
int
versionEnd
)
throws
IOException
{
String
modified
=
buildFileContents
.
substring
(
0
,
versionStart
)
+
upgrade
.
getVersion
()
+
buildFileContents
.
substring
(
versionEnd
);
overwrite
(
this
.
buildFile
,
modified
);
}
...
...
buildSrc/src/test/java/org/springframework/boot/build/bom/BomPluginIntegrationTests.java
View file @
ec2a7b9a
...
...
@@ -197,6 +197,34 @@ public class BomPluginIntegrationTests {
});
}
// @Test
// void versionAlignmentIsVerified() throws IOException {
// try (PrintWriter out = new PrintWriter(new FileWriter(this.buildFile))) {
// out.println("plugins {");
// out.println(" id 'org.springframework.boot.bom'");
// out.println("}");
// out.println("bom {");
// out.println(" library('OAuth2 OIDC SDK', '8.36.1') {");
// out.println(" alignedWith('Spring Security') {");
// out.println(
// "
// source('https://github.com/spring-projects/spring-security/blob/${libraryVersion}/config/gradle/dependency-locks/optional.lockfile')");
// out.println(" pattern('com.nimbusds:oauth2-oidc-sdk:(.+)')");
// out.println(" }");
// out.println(" group('com.nimbusds') {");
// out.println(" modules = [");
// out.println(" 'oauth2-oidc-sdk'");
// out.println(" ]");
// out.println(" }");
// out.println(" }");
// out.println(" library('Spring Security', '5.4.7') {");
// out.println(" }");
// out.println("}");
// }
// System.out.println(runGradle(DeployedPlugin.GENERATE_POM_TASK_NAME,
// "-s").getOutput());
// }
private
BuildResult
runGradle
(
String
...
args
)
{
return
GradleRunner
.
create
().
withDebug
(
true
).
withProjectDir
(
this
.
projectDir
).
withArguments
(
args
)
.
withPluginClasspath
().
build
();
...
...
buildSrc/src/test/java/org/springframework/boot/build/bom/bomr/UpgradeApplicatorTests.java
View file @
ec2a7b9a
...
...
@@ -28,6 +28,7 @@ import org.junit.jupiter.api.Test;
import
org.junit.jupiter.api.io.TempDir
;
import
org.springframework.boot.build.bom.Library
;
import
org.springframework.boot.build.bom.Library.LibraryVersion
;
import
org.springframework.boot.build.bom.bomr.version.DependencyVersion
;
import
org.springframework.util.FileCopyUtils
;
...
...
@@ -51,13 +52,28 @@ class UpgradeApplicatorTests {
String
originalContents
=
new
String
(
Files
.
readAllBytes
(
bom
.
toPath
()),
StandardCharsets
.
UTF_8
);
File
gradleProperties
=
new
File
(
this
.
temp
,
"gradle.properties"
);
FileCopyUtils
.
copy
(
new
File
(
"src/test/resources/gradle.properties"
),
gradleProperties
);
new
UpgradeApplicator
(
bom
.
toPath
(),
gradleProperties
.
toPath
())
.
apply
(
new
Upgrade
(
new
Library
(
"ActiveMQ"
,
DependencyVersion
.
parse
(
"5.15.11"
)
,
null
,
null
),
DependencyVersion
.
parse
(
"5.16"
)));
new
UpgradeApplicator
(
bom
.
toPath
(),
gradleProperties
.
toPath
())
.
apply
(
new
Upgrade
(
new
Library
(
"ActiveMQ"
,
new
LibraryVersion
(
DependencyVersion
.
parse
(
"5.15.11"
),
null
),
null
,
null
,
null
),
DependencyVersion
.
parse
(
"5.16"
)));
String
bomContents
=
new
String
(
Files
.
readAllBytes
(
bom
.
toPath
()),
StandardCharsets
.
UTF_8
);
assertThat
(
bomContents
.
length
()).
isEqualTo
(
originalContents
.
length
()
-
3
);
}
@Test
void
whenUpgradeIsAppliedToLibraryWithAlignedVersionThenBomIsUpdated
()
throws
IOException
{
File
bom
=
new
File
(
this
.
temp
,
"bom.gradle"
);
FileCopyUtils
.
copy
(
new
File
(
"src/test/resources/bom.gradle"
),
bom
);
String
originalContents
=
new
String
(
Files
.
readAllBytes
(
bom
.
toPath
()),
StandardCharsets
.
UTF_8
);
File
gradleProperties
=
new
File
(
this
.
temp
,
"gradle.properties"
);
FileCopyUtils
.
copy
(
new
File
(
"src/test/resources/gradle.properties"
),
gradleProperties
);
new
UpgradeApplicator
(
bom
.
toPath
(),
gradleProperties
.
toPath
()).
apply
(
new
Upgrade
(
new
Library
(
"OAuth2 OIDC SDK"
,
new
LibraryVersion
(
DependencyVersion
.
parse
(
"8.36.1"
),
null
),
null
,
null
,
null
),
DependencyVersion
.
parse
(
"8.36.2"
)));
String
bomContents
=
new
String
(
Files
.
readAllBytes
(
bom
.
toPath
()),
StandardCharsets
.
UTF_8
);
assertThat
(
bomContents
.
length
()).
isEqualTo
(
originalContents
.
length
());
assertThat
(
bomContents
).
contains
(
"version(\"8.36.2\")"
);
}
@Test
void
whenUpgradeIsAppliedToLibraryWithVersionPropertyThenGradlePropertiesIsUpdated
()
throws
IOException
{
File
bom
=
new
File
(
this
.
temp
,
"bom.gradle"
);
...
...
@@ -65,7 +81,8 @@ class UpgradeApplicatorTests {
File
gradleProperties
=
new
File
(
this
.
temp
,
"gradle.properties"
);
FileCopyUtils
.
copy
(
new
File
(
"src/test/resources/gradle.properties"
),
gradleProperties
);
new
UpgradeApplicator
(
bom
.
toPath
(),
gradleProperties
.
toPath
()).
apply
(
new
Upgrade
(
new
Library
(
"Kotlin"
,
DependencyVersion
.
parse
(
"1.3.70"
),
null
,
null
),
DependencyVersion
.
parse
(
"1.4"
)));
new
Library
(
"Kotlin"
,
new
LibraryVersion
(
DependencyVersion
.
parse
(
"1.3.70"
),
null
),
null
,
null
,
null
),
DependencyVersion
.
parse
(
"1.4"
)));
Properties
properties
=
new
Properties
();
try
(
InputStream
in
=
new
FileInputStream
(
gradleProperties
))
{
properties
.
load
(
in
);
...
...
buildSrc/src/test/resources/bom.gradle
View file @
ec2a7b9a
...
...
@@ -48,4 +48,14 @@ bom {
]
}
}
library
(
"OAuth2 OIDC SDK"
)
{
version
(
"8.36.1"
)
{
shouldAlignWithVersionFrom
(
"Spring Security"
)
}
group
(
"com.nimbusds"
)
{
modules
=
[
"oauth2-oidc-sdk"
]
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment