@@ -18,6 +18,8 @@ import * as rx from "rxjs";
1818
1919import * as rxx from "@amrc-factoryplus/rx-util" ;
2020
21+ //import { Schemas } from "./hooks/schemas.js";
22+
2123const Instance = imm . Record ( {
2224 hook : null ,
2325 repo : null ,
@@ -55,6 +57,15 @@ export class Hooks {
5557 { leading : true , trailing : true } ) ) ;
5658 }
5759
60+ async update_done ( update ) {
61+ this . done = update ( this . done ) ;
62+ const h_st = this . done . entrySeq ( )
63+ . map ( ( [ inst , commit ] ) => ( { commit, ...inst . toJS ( ) } ) )
64+ . toArray ( ) ;
65+ await fsp . writeFile ( this . hook_state , JSON . stringify ( h_st ) , "utf8" ) ;
66+ this . log ( "Rewrite hook-state: %o" , h_st ) ;
67+ }
68+
5869 /* Accepts the current state of the server.
5970 * Calculates which hooks need to run and runs them. We keep a state
6071 * file recording what has been run. This looks like
@@ -64,41 +75,52 @@ export class Hooks {
6475 async run_hooks ( { configs, status } ) {
6576 const { done } = this ;
6677
78+ /* NOTE: some callbacks take (key, value) and some (value, key). */
79+
6780 /* Calculate the changes we need to make. */
68- const want = configs . entrySeq ( )
69- . filter ( ( [ repo , conf ] ) => conf . hooks )
70- . flatMap ( ( [ repo , conf ] ) => imm . Seq ( conf . hooks )
71- . entrySeq ( )
72- . map ( ( [ branch , hook ] ) => Instance ( { repo, branch, hook } ) ) )
73- . map ( inst => [ inst , status . get ( inst . repo ) ?. get ( inst . branch ) ] ) ;
81+ const want = configs
82+ . filter ( conf => conf . hooks )
83+ . flatMap ( ( conf , repo ) => imm . Map ( conf . hooks )
84+ . mapKeys ( ( branch , hook ) => Instance ( { repo , branch , hook } ) ) )
85+ . map ( ( hook , inst ) => status . get ( inst . repo ) ?. get ( inst . branch ) ) ;
86+
7487 this . log ( "Want: %o" , want . toJS ( ) ) ;
7588 this . log ( "Done: %o" , done . toJS ( ) ) ;
76- const changes = want . filter ( ( [ inst , commit ] ) => done . get ( inst ) != commit ) ;
77- this . log ( "Changed: %o" , changes . toJS ( ) ) ;
78-
79- for ( const [ inst , commit ] of changes ) {
80- const msg = format ( "hook %s for %s branch %s" ,
81- inst . hook , inst . repo , inst . branch ) ;
82- //const hook = this.hooks.get(inst.hook);
83- //if (!hook) {
84- // this.log("Undefined %s", msg);
85- // continue;
86- //}
87-
88- this . log ( "Running %s" , msg ) ;
89- await setTimeout ( 6000 ) ;
90- //const err = await hook(inst.repo, commit)
91- // .then(() => null, e => e);
92- //if (err)
93- // this.log("Error running %s: %s", msg, err);
94- this . log ( "Finished %s" , msg ) ;
95-
96- this . done = this . done . set ( inst , commit ) ;
97- const h_st = this . done . entrySeq ( )
98- . map ( ( [ inst , commit ] ) => ( { commit, ...inst . toJS ( ) } ) )
99- . toArray ( ) ;
100- await fsp . writeFile ( this . hook_state , JSON . stringify ( h_st ) , "utf8" ) ;
101- }
89+
90+ const removed = done . keySeq ( ) . filter ( inst => want . has ( inst ) ) ;
91+ this . log ( "Removed: %o" , removed . toJS ( ) ) ;
92+ await this . update_done ( d => d . deleteAll ( removed ) ) ;
93+
94+ const changed = want . filter ( ( commit , inst ) => done . get ( inst ) != commit ) ;
95+ this . log ( "Changed: %o" , changed . toJS ( ) ) ;
96+
97+ for ( const [ inst , commit ] of changed )
98+ await this . run_hook ( inst , commit ) ;
99+ }
100+
101+ async run_hook ( inst , commit ) {
102+ const msg = format ( "hook %s for %s branch %s" ,
103+ inst . hook , inst . repo , inst . branch ) ;
104+
105+ //const hook = this.hooks.get(inst.hook);
106+ //if (!hook) {
107+ // this.log("Undefined %s", msg);
108+ // return;
109+ //}
110+
111+ /* XXX Should we retry on error? I'm not sure here. In general
112+ * an error is unlikely to be resolved by retrying, but there
113+ * are some limited circumstances such as service-setup not run
114+ * yet where errors have external causes and can be fixed.
115+ * Perhaps we should distinguish permanent problems with the
116+ * repo contents from temporary service errors? */
117+ this . log ( "Running %s" , msg ) ;
118+ await setTimeout ( 6000 ) ;
119+ //await hook(inst.repo, commit)
120+ // .then(() => this.log("Finished %s", msg))
121+ // .catch(err => this.log("Error running %s: %s", msg, err));
122+
123+ await this . update_done ( d => d . set ( inst , commit ) ) ;
102124 }
103125}
104126
0 commit comments