1+ import * as NodeServices from "@effect/platform-node/NodeServices" ;
2+ import { GitCommandError } from "@t3tools/contracts" ;
13import { assert , it } from "@effect/vitest" ;
4+ import * as Context from "effect/Context" ;
5+ import * as Effect from "effect/Effect" ;
6+ import * as FileSystem from "effect/FileSystem" ;
7+ import * as Layer from "effect/Layer" ;
8+ import * as Queue from "effect/Queue" ;
9+ import { ChildProcessSpawner } from "effect/process" ;
210
11+ import packageJson from "../../package.json" with { type : "json" } ;
12+ import * as ServerConfig from "../config.ts" ;
13+ import * as GitVcsDriver from "../vcs/GitVcsDriver.ts" ;
14+ import * as VcsProcess from "../vcs/VcsProcess.ts" ;
15+ import * as TriageService from "./TriageService.ts" ;
316import { pickSourceRef } from "./TriageService.ts" ;
417
518const MAIN = "a1dc856ee61278d0199c36d4bcdef5fdea4d21fe\trefs/heads/main" ;
@@ -22,3 +35,107 @@ it("falls back to main when the server's version has no tag", () => {
2235 } ) ;
2336 assert . isUndefined ( pickSourceRef ( "" , "0.1.1" ) ) ;
2437} ) ;
38+
39+ const TestLayer = GitVcsDriver . layer . pipe (
40+ Layer . provideMerge ( ServerConfig . layerTest ( process . cwd ( ) , { prefix : "t3-triage-service-" } ) ) ,
41+ Layer . provideMerge ( VcsProcess . layer ) ,
42+ Layer . provideMerge ( NodeServices . layer ) ,
43+ ) ;
44+
45+ const RELEASE_COMMIT = "7027b1f" ;
46+
47+ /** The service over a stub git that answers each command with `answer`. */
48+ const makeTriage = (
49+ answer : ( command : string ) => Effect . Effect < string , GitCommandError > = ( command ) =>
50+ Effect . succeed (
51+ command === "ls-remote" ? `${ RELEASE_COMMIT } \trefs/tags/v${ packageJson . version } \n` : "" ,
52+ ) ,
53+ ) =>
54+ Effect . gen ( function * ( ) {
55+ const git = yield * GitVcsDriver . GitVcsDriver ;
56+ const commands : string [ ] = [ ] ;
57+ const triage = yield * Layer . build ( TriageService . layer ) . pipe (
58+ Effect . map ( Context . get ( TriageService . TriageService ) ) ,
59+ Effect . provideService ( GitVcsDriver . GitVcsDriver , {
60+ ...git ,
61+ execute : ( input ) => {
62+ const command = input . args [ 0 ] ?? "" ;
63+ commands . push ( command ) ;
64+ return answer ( command ) . pipe (
65+ Effect . map ( ( stdout ) => ( {
66+ exitCode : ChildProcessSpawner . ExitCode ( 0 ) ,
67+ stdout,
68+ stderr : "" ,
69+ stdoutTruncated : false ,
70+ stderrTruncated : false ,
71+ } ) ) ,
72+ ) ;
73+ } ,
74+ } ) ,
75+ ) ;
76+ return { triage, commands } ;
77+ } ) ;
78+
79+ const readContext = Effect . gen ( function * ( ) {
80+ const fs = yield * FileSystem . FileSystem ;
81+ const config = yield * ServerConfig . ServerConfig ;
82+ const sessions = `${ config . stateDir } /triage` ;
83+ const [ session ] = yield * fs . readDirectory ( sessions ) ;
84+ return yield * fs . readFileString ( `${ sessions } /${ session } /context.md` ) ;
85+ } ) ;
86+
87+ it . effect ( "sessions started during a clone share it, and a release tag is looked up once" , ( ) =>
88+ Effect . gen ( function * ( ) {
89+ const fetches = yield * Queue . unbounded < void > ( ) ;
90+ const { triage, commands } = yield * makeTriage ( ( command ) =>
91+ command === "fetch"
92+ ? Queue . offer ( fetches , undefined ) . pipe ( Effect . andThen ( Effect . never ) )
93+ : Effect . succeed (
94+ command === "ls-remote" ? `${ RELEASE_COMMIT } \trefs/tags/v${ packageJson . version } \n` : "" ,
95+ ) ,
96+ ) ;
97+
98+ yield * triage . prepare ( { client : { } } ) ;
99+ yield * triage . prepare ( { client : { } } ) ;
100+ yield * Queue . take ( fetches ) ;
101+
102+ assert . deepEqual (
103+ commands . filter ( ( command ) => command === "ls-remote" || command === "init" ) ,
104+ [ "ls-remote" , "init" ] ,
105+ ) ;
106+ } ) . pipe ( Effect . provide ( TestLayer ) ) ,
107+ ) ;
108+
109+ it . effect ( "reuses a finished clone without fetching" , ( ) =>
110+ Effect . gen ( function * ( ) {
111+ const fs = yield * FileSystem . FileSystem ;
112+ const config = yield * ServerConfig . ServerConfig ;
113+ yield * fs . makeDirectory ( `${ config . baseDir } /source/${ RELEASE_COMMIT } ` , { recursive : true } ) ;
114+ const { triage, commands } = yield * makeTriage ( ) ;
115+
116+ yield * triage . prepare ( { client : { } } ) ;
117+
118+ assert . deepEqual ( commands , [ "ls-remote" ] ) ;
119+ assert . include ( yield * readContext , "The server cloned the source for its own version" ) ;
120+ } ) . pipe ( Effect . provide ( TestLayer ) ) ,
121+ ) ;
122+
123+ it . effect ( "still starts triage when the source lookup fails" , ( ) =>
124+ Effect . gen ( function * ( ) {
125+ const { triage } = yield * makeTriage ( ( ) =>
126+ Effect . fail (
127+ new GitCommandError ( {
128+ operation : "TriageService.resolveSourceRef" ,
129+ command : "git ls-remote" ,
130+ cwd : "/" ,
131+ detail : "Could not resolve host: github.com" ,
132+ } ) ,
133+ ) ,
134+ ) ;
135+
136+ const { prompt } = yield * triage . prepare ( { client : { } } ) ;
137+
138+ assert . include ( prompt , "triage-playbook.md" ) ;
139+ assert . include ( yield * readContext , "Could not resolve host: github.com" ) ;
140+ } ) . pipe ( Effect . provide ( TestLayer ) ) ,
141+ ) ;
0 commit comments