forked from ProverCoderAI/docker-git
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpull-push.ts
More file actions
76 lines (73 loc) · 3.54 KB
/
pull-push.ts
File metadata and controls
76 lines (73 loc) · 3.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import type * as CommandExecutor from "@effect/platform/CommandExecutor"
import type { PlatformError } from "@effect/platform/Error"
import * as FileSystem from "@effect/platform/FileSystem"
import * as Path from "@effect/platform/Path"
import { Effect, pipe } from "effect"
import type { CommandFailedError } from "../../shell/errors.js"
import { defaultProjectsRoot } from "../menu-helpers.js"
import { git, gitBaseEnv, gitCapture, gitExitCode, successExitCode } from "./git-commands.js"
import { resolveStateGithubContext, withGithubAuthHintOnFailure } from "./github-auth-state.js"
import { isGithubHttpsRemote, withGithubAskpassEnv } from "./github-auth.js"
const resolveStateRoot = (path: Path.Path, cwd: string): string => path.resolve(defaultProjectsRoot(cwd))
export const statePull: Effect.Effect<
void,
CommandFailedError | PlatformError,
FileSystem.FileSystem | Path.Path | CommandExecutor.CommandExecutor
> = Effect.gen(function*(_) {
const fs = yield* _(FileSystem.FileSystem)
const path = yield* _(Path.Path)
const root = resolveStateRoot(path, process.cwd())
const originUrlExit = yield* _(gitExitCode(root, ["remote", "get-url", "origin"], gitBaseEnv))
if (originUrlExit !== successExitCode) {
yield* _(git(root, ["pull", "--rebase"], gitBaseEnv))
return
}
const auth = yield* _(resolveStateGithubContext(fs, path, root))
// CHANGE: resolve current branch and pass origin <branch> explicitly
// WHY: bare `git pull --rebase` can fail or pull the wrong branch in some git configurations
// QUOTE(ТЗ): "Сделай что бы правильные параметры передавались"
// REF: issue-181
// PURITY: SHELL
const branchRaw = yield* _(
pipe(
gitCapture(root, ["rev-parse", "--abbrev-ref", "HEAD"], gitBaseEnv),
Effect.map((value) => value.trim()),
Effect.orElse(() => Effect.succeed("main"))
)
)
const branch = branchRaw === "HEAD" ? "main" : branchRaw
const effect = auth.token && auth.token.length > 0 && isGithubHttpsRemote(auth.originUrl)
? withGithubAskpassEnv(auth.token, (env) => git(root, ["pull", "--rebase", "origin", branch], env))
: git(root, ["pull", "--rebase", "origin", branch], gitBaseEnv)
yield* _(withGithubAuthHintOnFailure(effect, auth.authHintNeeded))
}).pipe(Effect.asVoid)
export const statePush: Effect.Effect<
void,
CommandFailedError | PlatformError,
FileSystem.FileSystem | Path.Path | CommandExecutor.CommandExecutor
> = Effect.gen(function*(_) {
const fs = yield* _(FileSystem.FileSystem)
const path = yield* _(Path.Path)
const root = resolveStateRoot(path, process.cwd())
const originUrlExit = yield* _(gitExitCode(root, ["remote", "get-url", "origin"], gitBaseEnv))
if (originUrlExit !== successExitCode) {
yield* _(git(root, ["push", "-u", "origin", "HEAD"], gitBaseEnv))
return
}
const auth = yield* _(resolveStateGithubContext(fs, path, root))
const effect = auth.token && auth.token.length > 0 && isGithubHttpsRemote(auth.originUrl)
? withGithubAskpassEnv(
auth.token,
(env) =>
pipe(
gitCapture(root, ["rev-parse", "--abbrev-ref", "HEAD"], env),
Effect.map((value) => value.trim()),
Effect.map((branch) => (branch === "HEAD" ? "main" : branch)),
Effect.flatMap((branch) =>
git(root, ["push", "--no-verify", auth.originUrl, `HEAD:refs/heads/${branch}`], env)
)
)
)
: git(root, ["push", "--no-verify", "-u", "origin", "HEAD"], gitBaseEnv)
yield* _(withGithubAuthHintOnFailure(effect, auth.authHintNeeded))
}).pipe(Effect.asVoid)