#groovy #nexus #artifact
#groovy #nexus #артефакт
Вопрос:
Я хочу отсортировать версию Iterable<Component> components
. Как при печати в консоли он показывает мне следующий результат:
artifact 1.0.1
artifact 1.0.10
artifact 1.0.11
artifact 1.0.12
artifcat 1.0.2
artifcat 1.0.3
artifcat 1.0.4
Это мой код
import org.sonatype.nexus.repository.storage.Component
import org.sonatype.nexus.repository.storage.Query
import org.sonatype.nexus.repository.storage.StorageFacet
def repoName = "artifact"
log.info("delete components for repository: " repoName)
def repo = repository.repositoryManager.get(repoName)
def tx = repo.facet(StorageFacet).txSupplier().get()
try {
tx.begin()
Iterable<Component> components = tx.findComponents(Query.builder()
.where('version < ').param('1.1.0')
.build(), [repo])
tx.commit()
for(Component c : components) {
log.info("Name " c.name() " Version" c.version())
}
} catch (Exception e) {
log.warn("Transaction failed {}", e.toString())
tx.rollback()
} finally {
tx.close()
}
Комментарии:
1. Существуют некоторые сценарии, которые не представлены в вашем примере вывода, чтобы точно знать, каковы требования.
components.sort {it.version()}
Дает ли желаемый порядок?2.В вашем заголовке указана сортировка числовых строк, но ваш вывод показывает
1.0.2
, что после1.0.11
этого, возможно, вашим требованием является альфа-сортировка.3. «откуда это взялось» — в Groovy, если замыкание не объявляет список аргументов, замыкание примет 1 необязательный аргумент named
it
.{ it.version() }
{ it -> it.version() }
и{ comp -> comp.version() }
функционально эквивалентны.4. «components = components.sort { it.size() }» — это допустимый параметр Groovy и не выдаст ошибку во время выполнения, если все элементы в
components
нем имеют метод с именемsize
, который не принимает никаких аргументов.5. Я думал, вы хотите отсортировать по версии, поэтому я предложил
components = components.sort { it.version() }
.
Ответ №1:
Некоторая простая сортировка по версии может быть выполнена следующим образом:
def components = []
'''
artifact 1.2.1
artifact 1.0.1
artifact 1.0.10
artifact 2.0.10
artifact 1.0.11
artifact 1.0.12
artifact 1.4.12
artifcat 1.0.2
artifcat 1.0.3
artifcat 1.0.4'''.splitEachLine( ' ' ){ name, version ->
components << [ name:name, version:version ]
}
// augment each component with numeric represenation of version
components.each{
it.versionNumeric = it.version.split( /./ )*.toInteger().reverse().withIndex().sum{ num, pow -> 100.power( pow ) * num }
}
components.sort{ it.versionNumeric }*.version.join 'n'
С принтами
1.0.1
1.0.2
1.0.3
1.0.4
1.0.10
1.0.11
1.0.12
1.2.1
1.4.12
2.0.10
Ответ №2:
Другой пример:
def components = '''
artifact 1.2.1
artifact 1.0.1
artifact 1.0.10
artifact 2.0.10
artifact 10.2
artifact 1.0.11
artifact 1.0.12
artifact 1.4.12
artifcat 1.0.2
artifcat 1.0.3
artifcat 1.0.4
artifact 1.0.4.2'''.readLines()*.tokenize(' ').collect { name, version ->
[name: name, version: version]
}
def sorted = components.sort { a, b ->
def f = { it.version.tokenize('.')*.toInteger() }
[f(a), f(b)].transpose().findResult { ai, bi ->
ai <=> bi ?: null
} ?: a.version <=> b.version
}
sorted.each { c ->
println c.version
}
который печатает:
─➤ groovy solution.groovy
1.0.1
1.0.2
1.0.3
1.0.4
1.0.4.2
1.0.10
1.0.11
1.0.12
1.2.1
1.4.12
2.0.10
10.2
Обратите внимание, что это решение также (по крайней мере, более или менее) обрабатывает версии с разным количеством элементов, таких как 10.2
и 1.0.4.2
.