|
| 1 | +/** |
| 2 | + * Pull agent configs from remote repository |
| 3 | + */ |
| 4 | + |
| 5 | +import * as p from "@clack/prompts"; |
| 6 | +import { getConfig } from "../config/manager"; |
| 7 | +import type { GlobalConfig } from "../config/types"; |
| 8 | +import { |
| 9 | + fetch, |
| 10 | + getBehindCount, |
| 11 | + getCurrentBranch, |
| 12 | + getGitStatus, |
| 13 | + getRemoteUrl, |
| 14 | + hasChanges, |
| 15 | + pull, |
| 16 | +} from "../utils/git"; |
| 17 | +import { expandHome } from "../utils/paths"; |
| 18 | + |
| 19 | +export async function pullCommand() { |
| 20 | + p.intro("Pull from Remote"); |
| 21 | + |
| 22 | + let config: GlobalConfig; |
| 23 | + try { |
| 24 | + config = getConfig(); |
| 25 | + } catch (_error) { |
| 26 | + p.cancel( |
| 27 | + "Configuration not found. Run 'syncode new' or 'syncode init' first.", |
| 28 | + ); |
| 29 | + return; |
| 30 | + } |
| 31 | + |
| 32 | + const _repoPath = expandHome(config.repoPath); |
| 33 | + |
| 34 | + const remoteUrl = await getRemoteUrl(); |
| 35 | + if (!remoteUrl) { |
| 36 | + p.cancel( |
| 37 | + "No remote repository configured. Add a remote with: git remote add origin <url>", |
| 38 | + ); |
| 39 | + return; |
| 40 | + } |
| 41 | + |
| 42 | + const branch = await getCurrentBranch(); |
| 43 | + p.log.info(`Branch: ${branch}`); |
| 44 | + p.log.info(`Remote: ${remoteUrl}`); |
| 45 | + |
| 46 | + console.log(""); |
| 47 | + |
| 48 | + // Check for uncommitted changes |
| 49 | + if (await hasChanges()) { |
| 50 | + p.log.warning("Uncommitted changes detected"); |
| 51 | + |
| 52 | + const gitStatus = await getGitStatus(); |
| 53 | + if (gitStatus) { |
| 54 | + console.log( |
| 55 | + gitStatus |
| 56 | + .split("\n") |
| 57 | + .map((l) => ` ${l}`) |
| 58 | + .join("\n"), |
| 59 | + ); |
| 60 | + console.log(""); |
| 61 | + } |
| 62 | + |
| 63 | + p.log.warning( |
| 64 | + "Cannot pull with uncommitted changes. Commit or stash them first.", |
| 65 | + ); |
| 66 | + p.outro("Pull cancelled"); |
| 67 | + return; |
| 68 | + } |
| 69 | + |
| 70 | + // Fetch to get latest remote state |
| 71 | + const fetchSpinner = p.spinner(); |
| 72 | + fetchSpinner.start("Fetching from remote"); |
| 73 | + |
| 74 | + const fetchResult = await fetch(); |
| 75 | + if (!fetchResult.success) { |
| 76 | + fetchSpinner.stop("Fetch failed"); |
| 77 | + p.log.error(fetchResult.message); |
| 78 | + p.outro("Pull cancelled"); |
| 79 | + return; |
| 80 | + } |
| 81 | + |
| 82 | + fetchSpinner.stop("Fetched from remote"); |
| 83 | + |
| 84 | + // Check if we're behind |
| 85 | + const behindCount = await getBehindCount(); |
| 86 | + if (behindCount === 0) { |
| 87 | + p.log.success("Already up to date"); |
| 88 | + p.outro("No changes to pull"); |
| 89 | + return; |
| 90 | + } |
| 91 | + |
| 92 | + p.log.info(`${behindCount} commit(s) behind remote`); |
| 93 | + |
| 94 | + // Pull from remote |
| 95 | + const spinner = p.spinner(); |
| 96 | + spinner.start(`Pulling from ${branch}`); |
| 97 | + |
| 98 | + const result = await pull(); |
| 99 | + |
| 100 | + if (result.success) { |
| 101 | + spinner.stop(`Pulled ${behindCount} commit(s) from ${branch}`); |
| 102 | + p.outro("Successfully pulled from remote"); |
| 103 | + } else { |
| 104 | + spinner.stop("Pull failed"); |
| 105 | + const { logError, getErrorLogFile } = require("../utils/trace"); |
| 106 | + const logFile = logError(new Error(result.message), "pull"); |
| 107 | + p.log.error(result.message); |
| 108 | + p.cancel(`Failed to pull from remote\n${getErrorLogFile(logFile)}`); |
| 109 | + } |
| 110 | +} |
0 commit comments