11import { add_subcommand } from "./add" ;
22import { remove_subcommand } from "./remove" ;
33
4- import { ANSI } from "../../term_ctl" ;
4+ import { ANSI , WrappedTerminal } from "../../term_ctl" ;
55import type { Program } from "../../types" ;
66import type { AbstractFileSystem } from "../../filesystem" ;
77import { list_subcommand } from "./list" ;
@@ -19,6 +19,8 @@ const GRAPH_PATH = GRAPH_DIR + "/graph.json";
1919
2020const BIN_DIR = "/usr/bin" ;
2121
22+ const TRIGGER_DIR = "/var/lib/pkg/triggers" ;
23+
2224// TODO: subcommand template / helper
2325
2426const append_url_pathnames = ( url : URL , pathnames : string [ ] ) => {
@@ -414,6 +416,85 @@ export const graph_query = {
414416 }
415417}
416418
419+ interface TriggerFile {
420+ install_exec ?: string ;
421+ uninstall_exec ?: string ;
422+ }
423+
424+ export const triggers = {
425+ load_trigger_file : async ( fs : AbstractFileSystem , trigger_name : string ) : Promise < TriggerFile | null > => {
426+ const trigger_path = fs . join ( TRIGGER_DIR , trigger_name + ".json" ) ;
427+ if ( ! ( await fs . exists ( trigger_path ) ) ) {
428+ return null ;
429+ }
430+
431+ const data = await fs . read_file ( trigger_path ) as string ;
432+ return JSON . parse ( data ) as TriggerFile ;
433+ } ,
434+
435+ trigger_exists : async ( fs : AbstractFileSystem , trigger_name : string ) : Promise < boolean > => {
436+ return ( await triggers . load_trigger_file ( fs , trigger_name ) ) !== null ;
437+ } ,
438+
439+ // returns boolean indicating if the trigger was found and processed
440+ process_install_trigger : async ( term : WrappedTerminal , trigger_name : string , data : unknown , pkg_name : string , pkg_version : string ) => {
441+ const fs = term . get_fs ( ) ;
442+
443+ const trigger = await triggers . load_trigger_file ( fs , trigger_name ) ;
444+ if ( ! trigger ) {
445+ return false ;
446+ }
447+
448+ if ( ! trigger . install_exec ) {
449+ // nothing to do
450+ return true ;
451+ }
452+
453+ const data_str = JSON . stringify ( data ) ;
454+ const spawn_result = term . spawn ( trigger . install_exec , [ pkg_name , pkg_version , data_str ] ) ;
455+
456+ try {
457+ const exit_code = await spawn_result . completion ;
458+ if ( exit_code !== 0 ) {
459+ term . writeln ( `${ ANSI . PREFABS . error } Warning: trigger ${ trigger_name } exited with code ${ exit_code } .${ ANSI . STYLE . reset_all } ` ) ;
460+ }
461+ } catch ( e ) {
462+ term . writeln ( `${ ANSI . PREFABS . error } Warning: trigger ${ trigger_name } failed: ${ e } .${ ANSI . STYLE . reset_all } ` ) ;
463+ }
464+
465+ return true ;
466+ } ,
467+
468+ // returns boolean indicating if the trigger was found and processed
469+ process_uninstall_trigger : async ( term : WrappedTerminal , trigger_name : string , data : unknown , pkg_name : string , pkg_version : string ) => {
470+ const fs = term . get_fs ( ) ;
471+
472+ const trigger = await triggers . load_trigger_file ( fs , trigger_name ) ;
473+ if ( ! trigger ) {
474+ return false ;
475+ }
476+
477+ if ( ! trigger . uninstall_exec ) {
478+ // nothing to do
479+ return true ;
480+ }
481+
482+ const data_str = JSON . stringify ( data ) ;
483+ const spawn_result = term . spawn ( trigger . uninstall_exec , [ pkg_name , pkg_version , data_str ] ) ;
484+
485+ try {
486+ const exit_code = await spawn_result . completion ;
487+ if ( exit_code !== 0 ) {
488+ term . writeln ( `${ ANSI . PREFABS . error } Warning: trigger ${ trigger_name } exited with code ${ exit_code } .${ ANSI . STYLE . reset_all } ` ) ;
489+ }
490+ } catch ( e ) {
491+ term . writeln ( `${ ANSI . PREFABS . error } Warning: trigger ${ trigger_name } failed: ${ e } .${ ANSI . STYLE . reset_all } ` ) ;
492+ }
493+
494+ return true ;
495+ }
496+ }
497+
417498// extract from ANSI to make code less verbose
418499const { STYLE , PREFABS } = ANSI ;
419500
0 commit comments