mirror of
https://gitee.com/dcren/initializr.git
synced 2025-07-15 23:13:30 +08:00
Merge pull request #279 from dsyer:feature/url
* pr/279: Polish contribution Add optional links to a dependency
This commit is contained in:
commit
bf306e5ecb
@ -102,6 +102,8 @@ class Dependency extends MetadataElement {
|
|||||||
|
|
||||||
List<String> keywords = []
|
List<String> keywords = []
|
||||||
|
|
||||||
|
List<Link> links = []
|
||||||
|
|
||||||
void setScope(String scope) {
|
void setScope(String scope) {
|
||||||
if (!SCOPE_ALL.contains(scope)) {
|
if (!SCOPE_ALL.contains(scope)) {
|
||||||
throw new InvalidInitializrMetadataException("Invalid scope $scope must be one of $SCOPE_ALL")
|
throw new InvalidInitializrMetadataException("Invalid scope $scope must be one of $SCOPE_ALL")
|
||||||
@ -161,6 +163,9 @@ class Dependency extends MetadataElement {
|
|||||||
"Invalid dependency, id should have the form groupId:artifactId[:version] but got $id")
|
"Invalid dependency, id should have the form groupId:artifactId[:version] but got $id")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
links.forEach { l ->
|
||||||
|
l.resolve()
|
||||||
|
}
|
||||||
updateVersionRanges(VersionParser.DEFAULT)
|
updateVersionRanges(VersionParser.DEFAULT)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,107 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2017 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.spring.initializr.metadata
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude
|
||||||
|
import groovy.transform.ToString
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Metadata for a link. Each link has a "relation" that potentially attaches a strong
|
||||||
|
* semantic to the nature of the link. The URI of the link itself can be templated by
|
||||||
|
* including variables in the form `{variableName}`.
|
||||||
|
* <p>
|
||||||
|
* An actual {@code URI} can be generated using {@code expand}, providing a mapping for
|
||||||
|
* those variables.
|
||||||
|
*
|
||||||
|
* @author Dave Syer
|
||||||
|
* @author Stephane Nicoll
|
||||||
|
*/
|
||||||
|
@ToString(ignoreNulls = true, includePackage = false)
|
||||||
|
class Link {
|
||||||
|
|
||||||
|
private static final String VARIABLE_REGEX = "\\{(\\w+)\\}";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The relation of the link.
|
||||||
|
*/
|
||||||
|
String rel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The URI the link is pointing to.
|
||||||
|
*/
|
||||||
|
String href
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify if the URI is templated.
|
||||||
|
*/
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_DEFAULT)
|
||||||
|
boolean templated
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
final Set<String> templateVariables = []
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A description of the link.
|
||||||
|
*/
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
|
String description
|
||||||
|
|
||||||
|
Set<String> getTemplateVariables() {
|
||||||
|
Collections.unmodifiableSet(templateVariables)
|
||||||
|
}
|
||||||
|
|
||||||
|
void setHref(String href) {
|
||||||
|
this.href = href
|
||||||
|
}
|
||||||
|
|
||||||
|
void resolve() {
|
||||||
|
if (!rel) {
|
||||||
|
throw new InvalidInitializrMetadataException(
|
||||||
|
"Invalid link $this: rel attribute is mandatory")
|
||||||
|
}
|
||||||
|
if (!href) {
|
||||||
|
throw new InvalidInitializrMetadataException(
|
||||||
|
"Invalid link $this: href attribute is mandatory")
|
||||||
|
}
|
||||||
|
def matcher = (href =~ VARIABLE_REGEX)
|
||||||
|
while (matcher.find()) {
|
||||||
|
def variable = matcher.group(1)
|
||||||
|
this.templateVariables << variable
|
||||||
|
}
|
||||||
|
this.templated = this.templateVariables
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expand the link using the specified parameters.
|
||||||
|
* @param parameters the parameters value
|
||||||
|
* @return an URI where all variables have been expanded
|
||||||
|
*/
|
||||||
|
URI expand(Map<String, String> parameters) {
|
||||||
|
String result = href
|
||||||
|
templateVariables.forEach { var ->
|
||||||
|
Object value = parameters[var]
|
||||||
|
if (!value) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Could not explan $href, missing value for '$var'")
|
||||||
|
}
|
||||||
|
result = result.replace("{$var}", value.toString())
|
||||||
|
}
|
||||||
|
new URI(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012-2016 the original author or authors.
|
* Copyright 2012-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -123,6 +123,15 @@ class DependencyTests {
|
|||||||
dependency.resolve()
|
dependency.resolve()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void invalidLink() {
|
||||||
|
def dependency = new Dependency(id : 'foo')
|
||||||
|
dependency.links << new Link(href: 'https://example.com')
|
||||||
|
|
||||||
|
thrown.expect(InvalidInitializrMetadataException)
|
||||||
|
dependency.resolve()
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void generateIdWithNoGroupId() {
|
void generateIdWithNoGroupId() {
|
||||||
def dependency = new Dependency()
|
def dependency = new Dependency()
|
||||||
|
@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2017 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.spring.initializr.metadata
|
||||||
|
|
||||||
|
import org.junit.Rule
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.rules.ExpectedException
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link Link}.
|
||||||
|
*
|
||||||
|
* @author Stephane Nicoll
|
||||||
|
*/
|
||||||
|
class LinkTests {
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public final ExpectedException thrown = ExpectedException.none()
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void resolveInvalidLinkNoRel() {
|
||||||
|
def link = new Link(href: 'https://example.com')
|
||||||
|
thrown.expect(InvalidInitializrMetadataException)
|
||||||
|
link.resolve()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void resolveInvalidLinkNoHref() {
|
||||||
|
def link = new Link(rel: 'reference', description: 'foo doc')
|
||||||
|
|
||||||
|
thrown.expect(InvalidInitializrMetadataException)
|
||||||
|
link.resolve()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void resolveLinkNoVariables() {
|
||||||
|
def link = new Link(rel: 'reference', href: 'https://example.com/2')
|
||||||
|
link.resolve()
|
||||||
|
assert !link.templated
|
||||||
|
assert link.templateVariables.size() == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void resolveLinkWithVariables() {
|
||||||
|
def link = new Link(rel: 'reference', href: 'https://example.com/{a}/2/{b}')
|
||||||
|
link.resolve()
|
||||||
|
assert link.templated
|
||||||
|
assert link.templateVariables.size() == 2
|
||||||
|
assert link.templateVariables.contains('a')
|
||||||
|
assert link.templateVariables.contains('b')
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void expandLink() {
|
||||||
|
def link = new Link(rel: 'reference', href: 'https://example.com/{a}/2/{b}')
|
||||||
|
link.resolve()
|
||||||
|
assert link.expand(['a': 'test', 'b': 'another']) ==
|
||||||
|
new URI('https://example.com/test/2/another')
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void expandLinkWithSameAttributeAtTwoPlaces() {
|
||||||
|
def link = new Link(rel: 'reference', href: 'https://example.com/{a}/2/{a}')
|
||||||
|
link.resolve()
|
||||||
|
assert link.expand(['a': 'test', 'b': 'another']) ==
|
||||||
|
new URI('https://example.com/test/2/test')
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void expandLinkMissingVariable() {
|
||||||
|
def link = new Link(rel: 'reference', href: 'https://example.com/{a}/2/{b}')
|
||||||
|
link.resolve()
|
||||||
|
|
||||||
|
thrown.expect(IllegalArgumentException)
|
||||||
|
thrown.expectMessage("missing value for 'b'")
|
||||||
|
link.expand(['a': 'test'])
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -39,6 +39,12 @@ initializr:
|
|||||||
description: Web dependency description
|
description: Web dependency description
|
||||||
facets:
|
facets:
|
||||||
- web
|
- web
|
||||||
|
links:
|
||||||
|
- rel: guide
|
||||||
|
href: https://example.com/guide
|
||||||
|
description: Building a RESTful Web Service
|
||||||
|
- rel: reference
|
||||||
|
href: https://example.com/doc
|
||||||
- name: Security
|
- name: Security
|
||||||
id: security
|
id: security
|
||||||
- name: Data JPA
|
- name: Data JPA
|
||||||
@ -55,6 +61,14 @@ initializr:
|
|||||||
keywords:
|
keywords:
|
||||||
- thefoo
|
- thefoo
|
||||||
- dafoo
|
- dafoo
|
||||||
|
links:
|
||||||
|
- rel: guide
|
||||||
|
href: https://example.com/guide1
|
||||||
|
- rel: reference
|
||||||
|
href: https://example.com/{bootVersion}/doc
|
||||||
|
- rel: guide
|
||||||
|
href: https://example.com/guide2
|
||||||
|
description: Some guide for foo
|
||||||
- name: Bar
|
- name: Bar
|
||||||
id: org.acme:bar
|
id: org.acme:bar
|
||||||
version: 2.1.0
|
version: 2.1.0
|
||||||
|
@ -52,6 +52,9 @@ class InitializrMetadataV21JsonMapper extends InitializrMetadataV2JsonMapper {
|
|||||||
if (dependency.versionRange) {
|
if (dependency.versionRange) {
|
||||||
content['versionRange'] = dependency.versionRange
|
content['versionRange'] = dependency.versionRange
|
||||||
}
|
}
|
||||||
|
if (dependency.links) {
|
||||||
|
content._links = LinkMapper.mapLinks(dependency.links)
|
||||||
|
}
|
||||||
content
|
content
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2017 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.spring.initializr.web.mapper
|
||||||
|
|
||||||
|
import io.spring.initializr.metadata.Link
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a json representation for {@link Link}
|
||||||
|
*
|
||||||
|
* @author Stephane Nicoll
|
||||||
|
*/
|
||||||
|
class LinkMapper {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map the specified links to a json model. If several links share
|
||||||
|
* the same relation, they are grouped together.
|
||||||
|
* @param links the links to map
|
||||||
|
* @return a model for the specified links
|
||||||
|
*/
|
||||||
|
static mapLinks(List<Link> links) {
|
||||||
|
def result = [:]
|
||||||
|
Map<String, List<Link>> byRel = new LinkedHashMap<>()
|
||||||
|
links.each {
|
||||||
|
def relLinks = byRel[it.rel]
|
||||||
|
if (!relLinks) {
|
||||||
|
relLinks = []
|
||||||
|
byRel[it.rel] = relLinks
|
||||||
|
}
|
||||||
|
relLinks.add(it)
|
||||||
|
}
|
||||||
|
byRel.forEach { rel, l ->
|
||||||
|
if (l.size() == 1) {
|
||||||
|
def root = [:]
|
||||||
|
mapLink(l[0], root)
|
||||||
|
result[rel] = root
|
||||||
|
} else {
|
||||||
|
def root = []
|
||||||
|
l.each {
|
||||||
|
def model = [:]
|
||||||
|
mapLink(it, model)
|
||||||
|
root << model
|
||||||
|
}
|
||||||
|
result[rel] = root
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
private static mapLink(Link link, def model) {
|
||||||
|
model.href = link.href
|
||||||
|
if (link.templated) {
|
||||||
|
model.templated = true
|
||||||
|
}
|
||||||
|
if (link.description) {
|
||||||
|
model.title = link.description
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012-2015 the original author or authors.
|
* Copyright 2012-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -17,7 +17,9 @@
|
|||||||
package io.spring.initializr.web.mapper
|
package io.spring.initializr.web.mapper
|
||||||
|
|
||||||
import groovy.json.JsonSlurper
|
import groovy.json.JsonSlurper
|
||||||
|
import io.spring.initializr.metadata.Dependency
|
||||||
import io.spring.initializr.metadata.InitializrMetadata
|
import io.spring.initializr.metadata.InitializrMetadata
|
||||||
|
import io.spring.initializr.metadata.Link
|
||||||
import io.spring.initializr.test.metadata.InitializrMetadataTestBuilder
|
import io.spring.initializr.test.metadata.InitializrMetadataTestBuilder
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
@ -52,4 +54,17 @@ class InitializrMetadataJsonMapperTests {
|
|||||||
result._links.foo.href
|
result._links.foo.href
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void keepLinksOrdering() {
|
||||||
|
def dependency = new Dependency(id: 'foo')
|
||||||
|
dependency.links << new Link(rel: 'guide', href: 'https://example.com/how-to')
|
||||||
|
dependency.links << new Link(rel: 'reference', href: 'https://example.com/doc')
|
||||||
|
InitializrMetadata metadata = InitializrMetadataTestBuilder.withDefaults()
|
||||||
|
.addDependencyGroup('test', dependency).build()
|
||||||
|
def json = jsonMapper.write(metadata, null)
|
||||||
|
def first = json.indexOf('https://example.com/how-to')
|
||||||
|
def second = json.indexOf('https://example.com/doc')
|
||||||
|
assert first < second
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,95 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2017 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.spring.initializr.web.mapper
|
||||||
|
|
||||||
|
import io.spring.initializr.metadata.Link
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link LinkMapper}.
|
||||||
|
*
|
||||||
|
* @author Stephane Nicoll
|
||||||
|
*/
|
||||||
|
class LinkMapperTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void mapSimpleRel() {
|
||||||
|
def links = new ArrayList()
|
||||||
|
links << new Link(rel: 'a', 'href': 'https://example.com',
|
||||||
|
description: 'some description')
|
||||||
|
def model = LinkMapper.mapLinks(links)
|
||||||
|
assert model.size() == 1
|
||||||
|
assert model.containsKey('a')
|
||||||
|
def linkModel = model['a']
|
||||||
|
assert linkModel.size() == 2
|
||||||
|
assert linkModel['href'] == 'https://example.com'
|
||||||
|
assert linkModel['title'] == 'some description'
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void mapTemplatedRel() {
|
||||||
|
def links = new ArrayList()
|
||||||
|
links << new Link(rel: 'a', 'href': 'https://example.com/{bootVersion}/a',
|
||||||
|
templated: true)
|
||||||
|
def model = LinkMapper.mapLinks(links)
|
||||||
|
assert model.size() == 1
|
||||||
|
assert model.containsKey('a')
|
||||||
|
def linkModel = model['a']
|
||||||
|
assert linkModel.size() == 2
|
||||||
|
assert linkModel['href'] == 'https://example.com/{bootVersion}/a'
|
||||||
|
assert linkModel['templated'] == true
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void mergeSeveralLinksInArray() {
|
||||||
|
def links = new ArrayList()
|
||||||
|
links << new Link(rel: 'a', 'href': 'https://example.com',
|
||||||
|
description: 'some description')
|
||||||
|
links << new Link(rel: 'a', 'href': 'https://example.com/2')
|
||||||
|
def model = LinkMapper.mapLinks(links)
|
||||||
|
assert model.size() == 1
|
||||||
|
assert model.containsKey('a')
|
||||||
|
def linksModel = model['a']
|
||||||
|
assert linksModel.size() == 2
|
||||||
|
assert linksModel[0]['href'] == 'https://example.com'
|
||||||
|
assert linksModel[1]['href'] == 'https://example.com/2'
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void keepOrdering() {
|
||||||
|
def links = new ArrayList()
|
||||||
|
links << new Link(rel: 'a', 'href': 'https://example.com')
|
||||||
|
links << new Link(rel: 'b', 'href': 'https://example.com')
|
||||||
|
def model = LinkMapper.mapLinks(links)
|
||||||
|
def iterator = model.keySet().iterator()
|
||||||
|
assert ++iterator == 'a'
|
||||||
|
assert ++iterator == 'b'
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void keepOrderingWithMultipleUrlForSameRel() {
|
||||||
|
def links = new ArrayList()
|
||||||
|
links << new Link(rel: 'a', 'href': 'https://example.com')
|
||||||
|
links << new Link(rel: 'b', 'href': 'https://example.com')
|
||||||
|
links << new Link(rel: 'a', 'href': 'https://example.com')
|
||||||
|
def model = LinkMapper.mapLinks(links)
|
||||||
|
def iterator = model.keySet().iterator()
|
||||||
|
assert ++iterator == 'a'
|
||||||
|
assert ++iterator == 'b'
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -131,7 +131,18 @@
|
|||||||
"groupId": "org.springframework.boot",
|
"groupId": "org.springframework.boot",
|
||||||
"id": "web",
|
"id": "web",
|
||||||
"name": "Web",
|
"name": "Web",
|
||||||
"scope": "compile"
|
"scope": "compile",
|
||||||
|
"links": [
|
||||||
|
{
|
||||||
|
"rel": "guide",
|
||||||
|
"description": "Building a RESTful Web Service",
|
||||||
|
"href": "https://example.com/guide"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "reference",
|
||||||
|
"href": "https://example.com/doc"
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"starter": true,
|
"starter": true,
|
||||||
@ -164,7 +175,23 @@
|
|||||||
"starter": true,
|
"starter": true,
|
||||||
"keywords": ["thefoo", "dafoo"],
|
"keywords": ["thefoo", "dafoo"],
|
||||||
"scope": "compile",
|
"scope": "compile",
|
||||||
"version": "1.3.5"
|
"version": "1.3.5",
|
||||||
|
"links": [
|
||||||
|
{
|
||||||
|
"rel": "guide",
|
||||||
|
"href": "https://example.com/guide1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "reference",
|
||||||
|
"href": "https://example.com/{bootVersion}/doc",
|
||||||
|
"templated": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "guide",
|
||||||
|
"description": "Some guide for foo",
|
||||||
|
"href": "https://example.com/guide2"
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"starter": true,
|
"starter": true,
|
||||||
|
@ -30,7 +30,16 @@
|
|||||||
{
|
{
|
||||||
"id": "web",
|
"id": "web",
|
||||||
"name": "Web",
|
"name": "Web",
|
||||||
"description": "Web dependency description"
|
"description": "Web dependency description",
|
||||||
|
"_links": {
|
||||||
|
"guide": {
|
||||||
|
"href": "https://example.com/guide",
|
||||||
|
"title": "Building a RESTful Web Service"
|
||||||
|
},
|
||||||
|
"reference": {
|
||||||
|
"href": "https://example.com/doc"
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "security",
|
"id": "security",
|
||||||
@ -47,7 +56,22 @@
|
|||||||
"values": [
|
"values": [
|
||||||
{
|
{
|
||||||
"id": "org.acme:foo",
|
"id": "org.acme:foo",
|
||||||
"name": "Foo"
|
"name": "Foo",
|
||||||
|
"_links": {
|
||||||
|
"guide": [
|
||||||
|
{
|
||||||
|
"href": "https://example.com/guide1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "https://example.com/guide2",
|
||||||
|
"title": "Some guide for foo"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"reference": {
|
||||||
|
"href": "https://example.com/{bootVersion}/doc",
|
||||||
|
"templated": true
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "org.acme:bar",
|
"id": "org.acme:bar",
|
||||||
|
Loading…
Reference in New Issue
Block a user