Skip to content

Commit da3a086

Browse files
authored
Merge pull request #3636 from OpenNeuroOrg/download-bug-fixes
fix(cli): Checkout latest snapshot by default and allow version for download action
2 parents afdac39 + af257cb commit da3a086

File tree

4 files changed

+81
-14
lines changed

4 files changed

+81
-14
lines changed

cli/src/commands/download.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import type { CommandOptions } from "@cliffy/command"
33
import { readConfig } from "../config.ts"
44
import { logger } from "../logger.ts"
55
import { getRepoAccess } from "./git-credential.ts"
6+
import { getLatestSnapshotVersion } from "../graphq.ts"
7+
import { version } from "node:os"
68

79
export const download = new Command()
810
.name("download")
@@ -11,10 +13,12 @@ export const download = new Command()
1113
.option(
1214
"-d, --draft",
1315
"Download a draft instead of the latest version snapshot.",
16+
{ conflicts: ["version"] },
1417
)
1518
.option(
16-
"-v, --version",
19+
"-v, --version <version:string>",
1720
"Download a specific version.",
21+
{ conflicts: ["draft"] },
1822
)
1923
.action(downloadAction)
2024

@@ -44,14 +48,23 @@ export async function downloadAction(
4448

4549
console.log("Downloading...")
4650

47-
// Clone main/master and git-annex branches
51+
let version
52+
if (options.version) {
53+
version = options.version
54+
} else if (!options.draft) {
55+
version = await getLatestSnapshotVersion(datasetId)
56+
}
57+
58+
// Clone the repo
4859
worker.postMessage({
4960
"command": "clone",
61+
"version": version,
5062
})
5163

5264
// Setup any git-annex remotes required for downloads
5365
worker.postMessage({
5466
"command": "remote-setup",
67+
"version": version,
5568
})
5669

5770
// Close after all tasks are queued

cli/src/graphq.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,26 @@ export async function prepareUpload(
9292

9393
export async function finishUpload() {
9494
}
95+
96+
export async function getLatestSnapshotVersion(datasetId: string) {
97+
const query = `
98+
query($datasetId: ID!) {
99+
dataset(id: $datasetId) {
100+
latestSnapshot {
101+
id
102+
tag
103+
}
104+
}
105+
}
106+
`
107+
const res = await request(query, { datasetId })
108+
const body = await res.json()
109+
if (body.errors) {
110+
throw new ResponseError(JSON.stringify(body.errors))
111+
}
112+
if (body.data) {
113+
return body.data.dataset.latestSnapshot.tag
114+
} else {
115+
throw new QueryError("Invalid response")
116+
}
117+
}

cli/src/worker/git.ts

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
import type { GitWorkerEventAdd } from "./types/git-context.ts"
1+
import type {
2+
GitWorkerEventAdd,
3+
GitWorkerEventClone,
4+
GitWorkerEventRemoteSetup,
5+
} from "./types/git-context.ts"
26
import type { GitAnnexAttributes, GitAnnexBackend } from "../gitattributes.ts"
37
import { matchGitAttributes, parseGitAttributes } from "../gitattributes.ts"
48
import { dirname, join } from "@std/path"
@@ -28,11 +32,12 @@ async function done() {
2832
/**
2933
* Clone or fetch the draft
3034
*/
31-
async function update() {
35+
async function update(event: GitWorkerEventClone) {
36+
const version = event.data?.version
3237
try {
3338
await context.fs.promises.access(join(context.repoPath, ".git"))
3439
logger.info(
35-
`Fetching ${context.datasetId} draft from "${context.repoEndpoint}"`,
40+
`Fetching ${context.datasetId} from "${context.repoEndpoint}"`,
3641
)
3742
// Reset first to be sure that an interrupted run didn't create untracked files
3843
await resetWorktree(context, await getDefault(context))
@@ -49,19 +54,26 @@ async function update() {
4954
theirs: "origin/git-annex",
5055
},
5156
)
52-
logger.info("Checkout latest HEAD.")
5357
// Make sure the default branch checkout is updated
5458
const defaultBranch = await getDefault(context)
59+
const ref = version || defaultBranch
60+
logger.info(`Checking out ${ref} branch.`)
5561
await git.checkout({
5662
...context.config(),
57-
ref: defaultBranch, // Checkout main
63+
ref, // Checkout main
5864
noUpdateHead: false, // Make sure we update the local branch HEAD
5965
})
6066
} catch (_err) {
6167
logger.info(
62-
`Cloning ${context.datasetId} draft from "${context.repoEndpoint}"`,
68+
`Cloning ${context.datasetId} from "${context.repoEndpoint}"`,
6369
)
70+
// Get the default branch
6471
await git.clone(context.config())
72+
// Checkout a specific version if needed
73+
if (version) {
74+
logger.info(`Checking out ${version}.`)
75+
await git.checkout({ ...context.config(), ref: version })
76+
}
6577
await git.fetch({ ...context.config(), ref: "git-annex" })
6678
try {
6779
await git.branch({
@@ -232,14 +244,14 @@ async function createAnnexBranch() {
232244
/**
233245
* Generate a commit for remote.log updates if needed
234246
*/
235-
async function remoteSetup() {
236-
await commitAnnexBranch()
247+
async function remoteSetup(event: GitWorkerEventRemoteSetup) {
248+
await commitAnnexBranch(event.data?.version)
237249
}
238250

239251
/**
240252
* Generate one commit for all pending git-annex branch changes
241253
*/
242-
async function commitAnnexBranch() {
254+
async function commitAnnexBranch(version?: string) {
243255
// Find the UUID of this repository if it exists already
244256
const expectedRemote = "OpenNeuro" // TODO - This could be more flexible?
245257
let uuid
@@ -347,7 +359,7 @@ async function commitAnnexBranch() {
347359
}
348360
}
349361
} finally {
350-
const defaultBranch = await getDefault(context)
362+
const defaultBranch = version || await getDefault(context)
351363
await git.checkout({
352364
...context.config(),
353365
ref: defaultBranch,
@@ -556,7 +568,7 @@ self.onmessage = (event: GitWorkerEvent) => {
556568
)
557569
setupLogging(event.data.logLevel)
558570
} else if (event.data.command === "clone") {
559-
workQueue.enqueue(update)
571+
workQueue.enqueue(update, event)
560572
} else if (event.data.command === "clearWorktree") {
561573
workQueue.enqueue(clearWorktree)
562574
} else if (event.data.command === "add") {
@@ -566,7 +578,7 @@ self.onmessage = (event: GitWorkerEvent) => {
566578
} else if (event.data.command === "push") {
567579
workQueue.enqueue(push)
568580
} else if (event.data.command === "remote-setup") {
569-
workQueue.enqueue(remoteSetup)
581+
workQueue.enqueue(remoteSetup, event)
570582
} else if (event.data.command === "done") {
571583
workQueue.enqueue(done)
572584
}

cli/src/worker/types/git-context.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,26 @@ export interface GitWorkerEventAdd {
104104
}
105105
}
106106

107+
/** Clone event to clone or fetch a version */
108+
export interface GitWorkerEventClone {
109+
data: {
110+
command: "clone"
111+
// Version to clone
112+
version?: string
113+
}
114+
}
115+
116+
export interface GitWorkerEventRemoteSetup {
117+
data: {
118+
command: "remoteSetup"
119+
// Version to checkout after setup
120+
version?: string
121+
}
122+
}
123+
107124
export type GitWorkerEvent =
108125
| GitWorkerEventSetup
109126
| GitWorkerEventGeneric
110127
| GitWorkerEventAdd
128+
| GitWorkerEventClone
129+
| GitWorkerEventRemoteSetup

0 commit comments

Comments
 (0)