-
Notifications
You must be signed in to change notification settings - Fork 661
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Default revision #5610
base: master
Are you sure you want to change the base?
Default revision #5610
Changes from all commits
bc52d2b
3fb101c
cc8350e
89ad6c0
26d27bd
9d9f19b
8128830
662efc5
79dec92
d1ebdcc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -55,11 +55,23 @@ class Manifest { | |
|
||
|
||
String getDefaultBranch() { | ||
target.defaultBranch | ||
target.defaultBranch ?: 'master' | ||
} | ||
|
||
/** | ||
* Gets the default revision to use | ||
* Priority order: | ||
* 1. defaultRevision if set | ||
* 2. version if set | ||
* 3. defaultBranch | ||
* @return The revision to use | ||
*/ | ||
String getDefaultRevision() { | ||
target.defaultRevision ?: getVersion() ?: getDefaultBranch() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think 'version' should be in this list at all. 'defaultRevision'/'defaultBranch' are pointers to a (potentially) different branch/revision from the one checked out. Version, if set, would usually represent the version of the checked out branch/revision, so I think including it in the list effectively means that whichever branch is checked out will become the default. It seems like this could result in surprising behaviour. Probably better only to rely on manifest fields which are explicitly related to defaults. |
||
} | ||
|
||
String getDescription() { | ||
target.description | ||
target.description | ||
} | ||
|
||
String getAuthor() { | ||
|
@@ -104,6 +116,10 @@ class Manifest { | |
target.nextflowVersion | ||
} | ||
|
||
/** | ||
* Gets the version | ||
* @return The version string or null if not set | ||
*/ | ||
String getVersion() { | ||
target.version | ||
} | ||
|
@@ -139,6 +155,7 @@ class Manifest { | |
.map(c -> c.toMap()) | ||
.collect(Collectors.toList()) | ||
result.defaultBranch = getDefaultBranch() | ||
result.defaultRevision = getDefaultRevision() | ||
result.description = getDescription() | ||
result.homePage = homePage | ||
result.gitmodules = getGitmodules() | ||
|
@@ -193,4 +210,100 @@ class Manifest { | |
MAINTAINER, | ||
CONTRIBUTOR | ||
} | ||
|
||
/** | ||
* Checks if the current version is a development version | ||
* @return true if version ends with 'dev' or '-dev', false otherwise | ||
*/ | ||
boolean isDevelopmentVersion() { | ||
def version = getVersion() | ||
if (!version) return false | ||
return version.endsWith('dev') || version.endsWith('-dev') | ||
} | ||
|
||
/** | ||
* Checks if the current version is a release candidate | ||
* @return true if version contains '-RC', false otherwise | ||
*/ | ||
boolean isReleaseCandidate() { | ||
def version = getVersion() | ||
if (!version) return false | ||
return version.contains('-RC') | ||
} | ||
|
||
/** | ||
* Checks if the current version is a hotfix | ||
* @return true if version contains '-hotfix', false otherwise | ||
*/ | ||
boolean isHotfix() { | ||
def version = getVersion() | ||
if (!version) return false | ||
return version.contains('-hotfix') | ||
} | ||
|
||
/** | ||
* Validates if a version string is a valid semantic version | ||
* @param version The version string to validate | ||
* @return true if valid, false otherwise | ||
*/ | ||
boolean isValidVersion(String version) { | ||
if (!version) return false | ||
// Matches standard versions like 1.0.0, release candidates like 1.0.0-RC1, development versions like 1.0.0dev, and hotfixes like 1.0.0-hotfix | ||
version ==~ /^\d+\.\d+\.\d+(-RC\d+|-dev|dev|-hotfix)?$/ | ||
} | ||
|
||
/** | ||
* Compares two version strings | ||
* @return -1 if v1 < v2, 0 if v1 == v2, 1 if v1 > v2 | ||
*/ | ||
private int compareVersions(String v1, String v2) { | ||
def v1Parts = v1.tokenize('.') | ||
def v2Parts = v2.tokenize('.') | ||
|
||
for (int i = 0; i < Math.min(v1Parts.size(), v2Parts.size()); i++) { | ||
def v1Part = v1Parts[i].replaceAll(/(-RC\d+|-dev|dev|-hotfix)$/, '') as int | ||
def v2Part = v2Parts[i].replaceAll(/(-RC\d+|-dev|dev|-hotfix)$/, '') as int | ||
if (v1Part != v2Part) { | ||
return v1Part <=> v2Part | ||
} | ||
} | ||
|
||
v1Parts.size() <=> v2Parts.size() | ||
} | ||
|
||
/** | ||
* Checks if the current version is greater than the provided version | ||
* @param otherVersion The version to compare against | ||
* @return true if current version is greater, false otherwise | ||
*/ | ||
boolean isVersionGreaterThan(String otherVersion) { | ||
def version = getVersion() | ||
if (!version || !otherVersion) return false | ||
|
||
// Strip any suffixes for comparison | ||
def v1 = version.replaceAll(/(-RC\d+|-dev|dev|-hotfix)$/, '') | ||
def v2 = otherVersion.replaceAll(/(-RC\d+|-dev|dev|-hotfix)$/, '') | ||
|
||
compareVersions(v1, v2) > 0 | ||
} | ||
|
||
/** | ||
* Checks if the current version is compatible with the provided version | ||
* @param otherVersion The version to check compatibility with | ||
* @return true if compatible, false otherwise | ||
*/ | ||
boolean isVersionCompatibleWith(String otherVersion) { | ||
def version = getVersion() | ||
if (!version || !otherVersion) return false | ||
|
||
// Development versions are always compatible | ||
if (isDevelopmentVersion()) return true | ||
|
||
// For release candidates and hotfixes, compare base versions | ||
def v1 = version.replaceAll(/(-RC\d+|-dev|dev|-hotfix)$/, '') | ||
def v2 = otherVersion.replaceAll(/(-RC\d+|-dev|dev|-hotfix)$/, '') | ||
|
||
// Version should be greater than or equal to the other version | ||
compareVersions(v1, v2) >= 0 | ||
} | ||
Comment on lines
+213
to
+308
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All of these version-related methods seem to be assuming/enforcing a very specific versioning scheme on pipelines. I don't think Nextflow can make these kind of assumptions/expectations since any organisation could be writing their own Nextflow pipelines and might use a different versioning scheme which is completely incompatible. It doesn't look like any of these methods are used in this PR though, so I think they can just be removed. |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -937,9 +937,18 @@ class AssetManager { | |
assert localPath | ||
|
||
def current = getCurrentRevision() | ||
if( current != defaultBranch ) { | ||
def defaultRev = getManifest().getDefaultRevision() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This shouldn't be asking the manifest directly; it needs to use the |
||
if( current != defaultRev ) { | ||
// NOTE This is the issue | ||
if( !revision ) { | ||
throw new AbortOperationException("Project `$project` is currently stuck on revision: $current -- you need to explicitly specify a revision with the option `-r` in order to use it") | ||
Ref head = git.getRepository().findRef(Constants.HEAD); | ||
|
||
// try to resolve the the current object id to a tag name | ||
Map<ObjectId, String> names = git.nameRev().addPrefix( "refs/tags/" ).add(head.objectId).call() | ||
def tag = names.get( head.objectId ) ?: head.objectId.name() | ||
if( current != tag ) { | ||
Comment on lines
+944
to
+949
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not quite sure I understand this change. It looks like the new logic boils down to "don't throw the error if the current revision is a tag (any tag)". Is that the intention? |
||
throw new AbortOperationException("Project `$project` is currently stuck on revision: $current -- you need to explicitly specify a revision with the option `-r` in order to use it") | ||
} | ||
} | ||
} | ||
if( !revision || revision == current ) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A git repository has its own concept of a 'default' branch, which is usually
master
ormain
- but can be absolutely anything. If the manifest doesn't specify a default branch/revision, we want to use the default branch set in git.So, rather than assuming 'master', this method needs to return null if no value is specified in the manifest file. This allows the logic in
AssetManager.getDefaultBranch()
to interrogate git's default branch.