Skip to content
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

Enable multiple revisions for project repos (first attempt 2024) #4659

Draft
wants to merge 75 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
7d027ec
Multiple revisions 1st: AssetManager, Cmd Clone Pull Run
marcodelapierre Jan 15, 2024
106e8df
removed revision paramter from clone pull run
marcodelapierre Jan 16, 2024
0a9e6f8
updated unit tests for AssetManager
marcodelapierre Jan 16, 2024
37d332e
Merge branch 'master' into add/mult_revisions
marcodelapierre Jan 16, 2024
5a9b159
AssetManager provider.revision assigned at AssetManager object creation
marcodelapierre Jan 16, 2024
94d34f3
Codespell typo in changelog
marcodelapierre Jan 16, 2024
4744774
AssetManager: removed checkout method
marcodelapierre Jan 16, 2024
d9e7b2b
Merge branch 'master' into add/mult_revisions
marcodelapierre Jan 17, 2024
08718ef
assetmanager: fixed build signature, and unit tests
marcodelapierre Jan 17, 2024
242a600
assetmanager: one more build signature fix
marcodelapierre Jan 17, 2024
35ad1e9
AssetManager: fix for multi revs in find() method
marcodelapierre Jan 17, 2024
463b6f1
Multiple revisions: added for Cmds Drop, View, Config, Info
marcodelapierre Jan 17, 2024
2d3273e
minor fixes to log outputs in CmdRun
marcodelapierre Jan 17, 2024
d2e5ffe
AssetManager: documented new localPath schema
marcodelapierre Jan 18, 2024
60c3c5e
K8sDriverLauncher : added revision support
marcodelapierre Jan 18, 2024
4bf1e37
updates to AssetManagerTest
marcodelapierre Jan 18, 2024
7e32111
edit to AssetManagerTest, git.pull for TAGS does not output result of…
marcodelapierre Jan 18, 2024
3b2d461
minor fix in GitlabRepositoryProvider: using DEFAULT_BRANCH instead o…
marcodelapierre Jan 18, 2024
2e6461e
Minor edits
bentsherman Jan 23, 2024
a8d2dee
Merge branch 'master' into add/mult_revisions
marcodelapierre Feb 5, 2024
eaf45d8
[ci fast] Merge branch 'master' into add/mult_revisions
pditommaso Feb 10, 2024
ed17284
Merge branch 'master' into add/mult_revisions
marcodelapierre Feb 23, 2024
b3f141d
parametrised revision delimiter
marcodelapierre Feb 28, 2024
6706bd9
nf pull: option to list or not revs for each project
marcodelapierre Feb 28, 2024
e62f543
nicer output for nf list -r
marcodelapierre Feb 28, 2024
bd19877
minor edit to CmdList
marcodelapierre Feb 29, 2024
c0268af
AssetManager: adding listRevisions method (work in progress)
marcodelapierre Feb 29, 2024
aae2afc
small tune to CmdList
marcodelapierre Feb 29, 2024
268ec79
minor tweak to CmdList
marcodelapierre Feb 29, 2024
ac8d755
AssetManager: listRevisions method now working
marcodelapierre Feb 29, 2024
70c8bcc
CmdDrop option to drop all revisions of given project
marcodelapierre Feb 29, 2024
8bcd717
AssetManagerTest: added test for method listRevisions
marcodelapierre Mar 4, 2024
4616e7f
docs - cli: add -a options for list and drop
marcodelapierre Mar 4, 2024
e4b9d78
docs - cli: add/update -r option for relevant commands
marcodelapierre Mar 4, 2024
958955a
CmdInfo: now also prints info on pulled revisions
marcodelapierre Mar 4, 2024
f220e98
CmdInfo made smarter when non only non default revisions pulled
marcodelapierre Mar 4, 2024
2ad9a24
CmdInfoTest updated
marcodelapierre Mar 4, 2024
35ea812
CmdInfoTest fix
marcodelapierre Mar 4, 2024
80ecacd
CmdInfo: added code comment
marcodelapierre Mar 4, 2024
5e4b45f
AssetManager: default revision recognised correctly if specified in m…
marcodelapierre Mar 4, 2024
aa94d7b
small CLI Docs update
marcodelapierre Mar 4, 2024
d965ee5
added a couple of comments
marcodelapierre Mar 6, 2024
f6e6174
Merge branch 'master' into add/mult_revisions
marcodelapierre Mar 11, 2024
ca48a97
Merge branch 'master' into add/mult_revisions
pditommaso Mar 17, 2024
12d31a2
fix merge conflicts
marcodelapierre Mar 21, 2024
9aacb2b
Review: REVISION_DELIM and added comments
marcodelapierre Mar 21, 2024
12718c7
review: added method getProjectWithRevision
marcodelapierre Mar 21, 2024
0b57262
updated method getBaseNameWithRevision
marcodelapierre Mar 21, 2024
17067ea
docs/sharing: added paragraph on multiple revisions, with caveat on r…
marcodelapierre Mar 21, 2024
67dc5d5
cmd info: removed sticky current revision, updated docs
marcodelapierre Mar 21, 2024
7716416
fixed unit tests in CmdInfoTest
marcodelapierre Mar 21, 2024
45be84b
Merge branch 'master' into add/mult_revisions
marcodelapierre Apr 4, 2024
2af4ba7
merged from master
marcodelapierre Apr 8, 2024
afa8a1c
Merge branch 'master' into add/mult_revisions
marcodelapierre Apr 12, 2024
dc4bdee
Merge branch 'master' into add/mult_revisions
marcodelapierre Apr 15, 2024
d2fb143
AssetManager: added bare repo, fixed chicken and egg at instantiation
marcodelapierre May 17, 2024
fc909ef
AssetManager: playing around with bare repo and commitID - good progress
marcodelapierre May 24, 2024
b969d42
assetmanager: extra tests with bare repo/commit id , going well
marcodelapierre May 24, 2024
0b0b510
assetmanager: local bare revision to commit using .resolve() method
marcodelapierre May 24, 2024
a334c55
AssetManager: using commitId, ok but inconsistencies to fix
marcodelapierre May 27, 2024
6b04d14
assetmanager: added notes on outstanding issues to fix
marcodelapierre May 27, 2024
5d41cf8
assetmanager: extra note
marcodelapierre May 27, 2024
ff00499
assetmanager: update bare to find rev ; download() uses commit
marcodelapierre May 27, 2024
198594d
assetmanager: download() project from local bare repo, not remote url
marcodelapierre May 27, 2024
ff1b439
assetmanager: note update
marcodelapierre May 27, 2024
6091fcb
assetmanager: note update 2
marcodelapierre May 27, 2024
7643b7b
fix bug in commitFromRevisionUsingBareLocal
marcodelapierre May 27, 2024
ca40946
download() does not use checkoutRemoteBranch()
marcodelapierre May 27, 2024
3b44f9f
fix to updateLocalBareRepo
marcodelapierre May 29, 2024
d69f542
Revert "fix to updateLocalBareRepo"
marcodelapierre May 29, 2024
0cb331a
assetmanager comments
marcodelapierre May 29, 2024
042e99f
Merge branch 'master' into add/mult_revisions
marcodelapierre Jun 13, 2024
125959f
updated nextflow.scm.mmd
marcodelapierre Jun 13, 2024
5bdb2b3
updated docs/sharing
marcodelapierre Jun 13, 2024
61bd4bf
Merge branch 'master' into add/mult_revisions
marcodelapierre Jun 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 19 additions & 4 deletions docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ The `clone` command downloads a pipeline from a Git-hosting platform into the *c
: Service hub where the project is hosted. Options: `gitlab` or `bitbucket`.

`-r` (`master`)
: Revision to clone - It can be a git branch, tag, or revision number.
: Revision of the project to clone (either a git branch, tag or commit SHA number).

`-user`
: Private repository user name.
Expand Down Expand Up @@ -415,6 +415,9 @@ The `config` command is used for printing the project's configuration i.e. the `
`-properties`
: Print config using Java properties notation.

`-r, -revision`
: Revision of the project (either a git branch, tag or commit SHA number).

`-a, -show-profiles`
: Show all configuration profiles.

Expand Down Expand Up @@ -535,12 +538,18 @@ The `drop` command is used to remove the projects which have been downloaded int

**Options**

`-a, -all-revisions`
: For specified project, drop all revisions.

`-f`
: Delete the repository without taking care of local changes.

`-h, -help`
: Print the command usage.

`-r, -revision`
: Revision of the project to drop (either a git branch, tag or commit SHA number).

**Examples**

Drop the `nextflow-io/hello` project.
Expand Down Expand Up @@ -664,7 +673,7 @@ $ nextflow info [options] [project]

**Description**

The `info` command prints out the nextflow runtime information about the hardware as well as the software versions of the Nextflow version and build, operating system, and Groovy and Java runtime. It can also be used to display information about a specific project.
The `info` command prints out the nextflow runtime information about the hardware as well as the software versions of the Nextflow version and build, operating system, and Groovy and Java runtime. It can also be used to display information about a specific project; in this case, note how revisions marked as `P` are pulled locally.

If no run name or session id is provided, it will clean the latest run.

Expand Down Expand Up @@ -878,6 +887,9 @@ The `list` commands prints a list of the projects which are already downloaded i

**Options**

`-a, -all-revisions`
: For each project, also list revisions.

`-h, -help`
: Print the command usage.

Expand Down Expand Up @@ -1072,7 +1084,7 @@ The `pull` command downloads a pipeline from a Git-hosting platform into the glo
: Service hub where the project is hosted. Options: `gitlab` or `bitbucket`

`-r, -revision`
: Revision of the project to run (either a git branch, tag or commit hash).
: Revision of the project to pull (either a git branch, tag or commit SHA number).
: When passing a git tag or branch, the `workflow.revision` and `workflow.commitId` fields are populated. When passing only the commit hash, `workflow.revision` is not defined.

`-user`
Expand Down Expand Up @@ -1217,7 +1229,7 @@ The `run` command is used to execute a local pipeline script or remote pipeline
: Execute the script using the cached results, useful to continue executions that was stopped by an error.

`-r, -revision`
: Revision of the project to run (either a git branch, tag or commit hash).
: Revision of the project to run (either a git branch, tag or commit SHA number).
: When passing a git tag or branch, the `workflow.revision` and `workflow.commitId` fields are populated. When passing only the commit hash, `workflow.revision` is not defined.

`-stub-run, -stub`
Expand Down Expand Up @@ -1426,6 +1438,9 @@ The `view` command is used to inspect the pipelines that are already stored in t
`-q`
: Hide header line.

`-r, -revision`
: Revision of the project (either a git branch, tag or commit SHA number).

**Examples**

Viewing the contents of a downloaded pipeline.
Expand Down
5 changes: 4 additions & 1 deletion docs/developer/diagrams/nextflow.scm.mmd
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@ classDiagram

class AssetManager {
project : String
revision : String
commitId : String
localPath : File
localBarePath : File
mainScript : String
repositoryProvider : RepositoryProvider
provider : RepositoryProvider
hub : String
providerConfigs : List~ProviderConfig~
}
Expand Down
11 changes: 8 additions & 3 deletions docs/sharing.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ nextflow run nextflow-io/hello -r v1.1

It will execute two different project revisions corresponding to the Git tag/branch having that names.

:::{versionadded} 24.XX.0-edge
:::

Nextflow downloads and locally maintains each explicitly requested Git branch, tag or commit ID in a separate directory path, thus enabling to run multiple revisions of the same pipeline at the same time. Each downloaded revision is stored in a sub-directory path to the default pipeline path one, named after the corresponding commit ID, according to the schema `<project>/.nextflow/commits/<commit>`.

## Commands to manage projects

The following commands allows you to perform some basic operations that can be used to manage your projects.
Expand Down Expand Up @@ -94,13 +99,13 @@ repository : http://github.com/nextflow-io/hello
local path : $HOME/.nextflow/assets/nextflow-io/hello
main script : main.nf
revisions :
* master (default)
P master (default)
mybranch
v1.1 [t]
P v1.1 [t]
v1.2 [t]
```

Starting from the top it shows: 1) the project name; 2) the Git repository URL; 3) the local folder where the project has been downloaded; 4) the script that is executed when launched; 5) the list of available revisions i.e. branches and tags. Tags are marked with a `[t]` on the right, the current checked-out revision is marked with a `*` on the left.
Starting from the top it shows: 1) the project name; 2) the Git repository URL; 3) the local path where the default project can be found (alternate revisions are in sister paths with an extra suffix `:<revision id>`); 4) the script that is executed when launched; 5) the list of available revisions i.e. branches and tags. Tags are marked with a `[t]` on the right, the locally pulled revisions are marked with a `P` on the left.

### Pulling or updating a project

Expand Down
13 changes: 7 additions & 6 deletions modules/nextflow/src/main/groovy/nextflow/cli/CmdClone.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/

package nextflow.cli

import com.beust.jcommander.Parameter
import com.beust.jcommander.Parameters
import groovy.transform.CompileStatic
Expand All @@ -37,7 +38,7 @@ class CmdClone extends CmdBase implements HubOptions {
@Parameter(required=true, description = 'name of the project to clone')
List<String> args

@Parameter(names='-r', description = 'Revision to clone - It can be a git branch, tag or revision number')
@Parameter(names='-r', description = 'Revision of the project to clone (either a git branch, tag or commit SHA number)')
String revision

@Parameter(names=['-d','-deep'], description = 'Create a shallow clone of the specified depth')
Expand All @@ -52,11 +53,11 @@ class CmdClone extends CmdBase implements HubOptions {
Plugins.init()
// the pipeline name
String pipeline = args[0]
final manager = new AssetManager(pipeline, this)
final manager = new AssetManager(pipeline, revision, this)

// the target directory is the second parameter
// otherwise default the current pipeline name
def target = new File(args.size()> 1 ? args[1] : manager.getBaseName())
def target = new File(args.size()> 1 ? args[1] : manager.getBaseNameWithRevision())
if( target.exists() ) {
if( target.isFile() )
throw new AbortOperationException("A file with the same name already exists: $target")
Expand All @@ -68,9 +69,9 @@ class CmdClone extends CmdBase implements HubOptions {
}

manager.checkValidRemoteRepo()
print "Cloning ${manager.project}${revision ? ':'+revision:''} ..."
manager.clone(target, revision, deep)
print "Cloning ${manager.getProjectWithRevision()} ..."
manager.clone(target, deep)
print "\r"
println "${manager.project} cloned to: $target"
println "${manager.getProjectWithRevision()} cloned to: $target"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ class CmdConfig extends CmdBase {
@Parameter(description = 'project name')
List<String> args = []

@Parameter(names=['-r','-revision'], description = 'Revision of the project (either a git branch, tag or commit SHA number)')
String revision

@Parameter(names=['-a','-show-profiles'], description = 'Show all configuration profiles')
boolean showAllProfiles

Expand Down Expand Up @@ -183,7 +186,7 @@ class CmdConfig extends CmdBase {
return file.parent ?: Paths.get('/')
}

final manager = new AssetManager(path)
final manager = new AssetManager(path, revision)
manager.isLocal() ? manager.localPath.toPath() : manager.configFile?.parent

}
Expand Down
42 changes: 33 additions & 9 deletions modules/nextflow/src/main/groovy/nextflow/cli/CmdDrop.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

package nextflow.cli

import static nextflow.scm.AssetManager.REVISION_DELIM

import com.beust.jcommander.Parameter
import com.beust.jcommander.Parameters
import groovy.transform.CompileStatic
Expand All @@ -39,6 +41,12 @@ class CmdDrop extends CmdBase {
@Parameter(required=true, description = 'name of the project to drop')
List<String> args

@Parameter(names=['-r','-revision'], description = 'Revision of the project to drop (either a git branch, tag or commit SHA number)')
String revision

@Parameter(names=['-a','-all-revisions'], description = 'For specified project, drop all revisions')
Boolean allrevisions

@Parameter(names='-f', description = 'Delete the repository without taking care of local changes')
boolean force

Expand All @@ -48,18 +56,34 @@ class CmdDrop extends CmdBase {
@Override
void run() {
Plugins.init()
def manager = new AssetManager(args[0])
if( !manager.localPath.exists() ) {
throw new AbortOperationException("No match found for: ${args[0]}")

List<AssetManager> dropList = []
if ( allrevisions ) {
def referenceManager = new AssetManager(args[0])
referenceManager.listRevisions().each {
dropList << new AssetManager(it.tokenize(REVISION_DELIM)[0], it.tokenize(REVISION_DELIM)[1])
}
} else {
dropList << new AssetManager(args[0], revision)
}

if( this.force || manager.isClean() ) {
manager.close()
if( !manager.localPath.deleteDir() )
throw new AbortOperationException("Unable to delete project `${manager.project}` -- Check access permissions for path: ${manager.localPath}")
return
if ( !dropList ) {
throw new AbortOperationException("No revisions found for specified project: ${args[0]}")
}

throw new AbortOperationException("Local project repository contains uncommitted changes -- won't drop it")
dropList.each { manager ->
if( !manager.localPath.exists() ) {
throw new AbortOperationException("No match found for: ${manager.getProjectWithRevision()}")
}

if( this.force || manager.isClean() ) {
manager.close()
if( !manager.localPath.deleteDir() )
throw new AbortOperationException("Unable to delete project `${manager.getProjectWithRevision()}` -- Check access permissions for path: ${manager.localPath}")
return
}

throw new AbortOperationException("Local project repository contains uncommitted changes -- won't drop it")
}
}
}
19 changes: 14 additions & 5 deletions modules/nextflow/src/main/groovy/nextflow/cli/CmdInfo.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

package nextflow.cli

import static nextflow.scm.AssetManager.REVISION_DELIM

import java.lang.management.ManagementFactory
import java.nio.file.spi.FileSystemProvider

Expand Down Expand Up @@ -75,9 +77,16 @@ class CmdInfo extends CmdBase {
}

Plugins.init()
final manager = new AssetManager(args[0])
if( !manager.isLocal() )
throw new AbortOperationException("Unknown project `${args[0]}`")
def manager = new AssetManager(args[0], null)
if( !manager.isLocal() ) {
// if default branch not found locally, use first one from list of local pulls
if ( manager.listRevisions() ) {
manager = new AssetManager(args[0], manager.getPulledRevisions()[0])
}
else {
throw new AbortOperationException("Unknown project `${args[0]}`")
}
}

if( !format || format == 'text' ) {
printText(manager,level)
Expand All @@ -101,7 +110,7 @@ class CmdInfo extends CmdBase {

out.println " project name: ${manager.project}"
out.println " repository : ${manager.repositoryUrl}"
out.println " local path : ${manager.localPath}"
out.println " local path : ${manager.localPath.toString().tokenize(REVISION_DELIM)[0]}"
out.println " main script : ${manager.mainScriptName}"
if( manager.homePage && manager.homePage != manager.repositoryUrl )
out.println " home page : ${manager.homePage}"
Expand Down Expand Up @@ -138,7 +147,7 @@ class CmdInfo extends CmdBase {
def result = [:]
result.projectName = manager.project
result.repository = manager.repositoryUrl
result.localPath = manager.localPath?.toString()
result.localPath = manager.localPath?.toString().tokenize(REVISION_DELIM)[0]
result.manifest = manager.manifest.toMap()
result.revisions = manager.getBranchesAndTags(checkForUpdates)
return result
Expand Down
16 changes: 15 additions & 1 deletion modules/nextflow/src/main/groovy/nextflow/cli/CmdList.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@

package nextflow.cli

import static nextflow.scm.AssetManager.REVISION_DELIM

import com.beust.jcommander.Parameter
import com.beust.jcommander.Parameters
import groovy.transform.CompileStatic
import groovy.util.logging.Slf4j
Expand All @@ -33,6 +36,9 @@ class CmdList extends CmdBase {

static final public NAME = 'list'

@Parameter(names=['-a','-all-revisions'], description = 'For each project, also list revisions')
Boolean revisions

@Override
final String getName() { NAME }

Expand All @@ -45,7 +51,15 @@ class CmdList extends CmdBase {
return
}

all.each { println it }
if (revisions) {
all.collect{ it.tokenize(REVISION_DELIM) }
.groupBy{ it[0] }
.each{ println ' ' + it.value[0][0] ; it.value.each{ y -> println ( y.size()==1 ? ' (default)' : ' ' + y[1] ) } }
} else {
all.collect{ it.replaceAll( /$REVISION_DELIM.*/, '' ) }
.unique()
.each{ println ' ' + it }
}
}

}
12 changes: 8 additions & 4 deletions modules/nextflow/src/main/groovy/nextflow/cli/CmdPull.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
*/

package nextflow.cli

import static nextflow.scm.AssetManager.REVISION_DELIM

import com.beust.jcommander.Parameter
import com.beust.jcommander.Parameters
import groovy.transform.CompileStatic
Expand All @@ -40,7 +43,7 @@ class CmdPull extends CmdBase implements HubOptions {
@Parameter(names='-all', description = 'Update all downloaded projects', arity = 0)
boolean all

@Parameter(names=['-r','-revision'], description = 'Revision of the project to run (either a git branch, tag or commit SHA number)')
@Parameter(names=['-r','-revision'], description = 'Revision of the project to pull (either a git branch, tag or commit SHA number)')
String revision

@Parameter(names=['-d','-deep'], description = 'Create a shallow clone of the specified depth')
Expand Down Expand Up @@ -73,10 +76,11 @@ class CmdPull extends CmdBase implements HubOptions {
Plugins.init()

list.each {
log.info "Checking $it ..."
def manager = new AssetManager(it, this)
log.info "Checking $it${revision ? REVISION_DELIM + revision : ''} ..."
def manager = new AssetManager(it, revision, this)

def result = manager.download(revision,deep)
manager.updateLocalBareRepo()
def result = manager.download(deep)
manager.updateModules()

def scriptFile = manager.getScriptFile()
Expand Down
Loading
Loading