4
4
// here to make the resulting config reasonably stable
5
5
// across serializaiton. No random identifiers.
6
6
7
- import { deep_eql , multibase32 , multibase64 } from "../deps/common.ts" ;
7
+ import { deep_eql , multibase32 , multibase64 , zod } from "../deps/common.ts" ;
8
8
9
9
// ports specific imports
10
10
import portsValidators from "../modules/ports/types.ts" ;
@@ -43,8 +43,16 @@ import type {
43
43
Provision ,
44
44
WellKnownProvision ,
45
45
} from "../modules/envs/types.ts" ;
46
+ import modulesValidators from "../modules/types.ts" ;
46
47
47
- export type EnvParent = string | string [ ] | boolean ;
48
+ const validators = {
49
+ envVars : zod . record (
50
+ modulesValidators . envVarName ,
51
+ zod . union ( [ zod . string ( ) , zod . number ( ) ] ) ,
52
+ ) ,
53
+ } ;
54
+
55
+ export type EnvParent = string | string [ ] | boolean | undefined ;
48
56
49
57
export type EnvDefArgs = {
50
58
name : string ;
@@ -91,7 +99,7 @@ export type TaskDefArgs = {
91
99
workingDir ?: string | Path ;
92
100
vars ?: Record < string , string | number > ;
93
101
allowedBuildDeps ?: ( InstallConfigFat | AllowedPortDep ) [ ] ;
94
- installs ?: InstallConfigFat [ ] ;
102
+ installs ?: InstallConfigFat | InstallConfigFat [ ] ;
95
103
inherit ?: EnvParent ;
96
104
} ;
97
105
@@ -191,12 +199,20 @@ export class Ghjkfile {
191
199
// brittle.
192
200
if ( typeof args . inherit == "string" ) {
193
201
this . addEnv ( { name : args . inherit } ) ;
194
- }
195
- if ( Array . isArray ( args . inherit ) ) {
202
+ } else if ( Array . isArray ( args . inherit ) ) {
196
203
for ( const name of args . inherit ) {
197
204
this . addEnv ( { name } ) ;
198
205
}
199
206
}
207
+ // FIXME: combine the task env processing
208
+ // with normal env processing
209
+ // we currrently process task envs at once in the end
210
+ // to do env deduplication
211
+ if ( args . vars ) {
212
+ args . vars = unwrapParseRes ( validators . envVars . safeParse ( args . vars ) , {
213
+ vars : args . vars ,
214
+ } ) ;
215
+ }
200
216
let key = args . name ;
201
217
if ( ! key ) {
202
218
switch ( args . ty ) {
@@ -413,7 +429,7 @@ export class Ghjkfile {
413
429
: null ;
414
430
}
415
431
416
- /** this processes the defined envs, normalizing dependency (i.e. "envBase")
432
+ /** this processes the defined envs, resolving inherit
417
433
* relationships to produce the standard EnvsModuleConfig
418
434
*/
419
435
#processEnvs(
@@ -450,7 +466,11 @@ export class Ghjkfile {
450
466
}
451
467
}
452
468
453
- const moduleConfig : EnvsModuleConfig = { envs : { } , defaultEnv } ;
469
+ const moduleConfig : EnvsModuleConfig = {
470
+ envs : { } ,
471
+ defaultEnv,
472
+ envsNamed : [ ] ,
473
+ } ;
454
474
const workingSet = indie ;
455
475
while ( workingSet . length > 0 ) {
456
476
const item = workingSet . pop ( ) ! ;
@@ -559,6 +579,12 @@ export class Ghjkfile {
559
579
moduleConfig . envs [ final . name ] . provides . push ( prov ) ;
560
580
}
561
581
582
+ // envs that have names which start with underscors
583
+ // don't show up in the cli list
584
+ if ( ! final . name . startsWith ( "_" ) ) {
585
+ moduleConfig . envsNamed . push ( final . name ) ;
586
+ }
587
+
562
588
const curRevDeps = revDeps . get ( final . name ) ;
563
589
if ( curRevDeps ) {
564
590
workingSet . push ( ...curRevDeps ) ;
@@ -609,8 +635,8 @@ export class Ghjkfile {
609
635
}
610
636
const workingSet = indie ;
611
637
const localToFinalKey = { } as Record < string , string > ;
638
+ const gatheredEnvs = { } as Record < string , EnvRecipe > ;
612
639
const moduleConfig : TasksModuleConfig = {
613
- envs : { } ,
614
640
tasks : { } ,
615
641
tasksNamed : [ ] ,
616
642
} ;
@@ -620,80 +646,95 @@ export class Ghjkfile {
620
646
const { workingDir, desc, dependsOn, inherit } = args ;
621
647
622
648
const envBaseResolved = this . #resolveEnvBases(
623
- inherit ?? [ ] ,
649
+ inherit ,
624
650
defaultBaseEnv ,
625
651
) ;
626
-
627
- const base = envBaseResolved
628
- ? this . #mergeEnvs( envBaseResolved , `task_${ args . name ?? key } ` )
629
- : null ;
630
-
631
- let installSetId : string | undefined ;
632
- if (
652
+ const needsSeparateSet =
633
653
// if task has installs itself
634
654
args . installs ?. length ||
635
655
// task inherits from more than one parent
636
- ( envBaseResolved && envBaseResolved . length > 1 )
637
- ) {
638
- // we need to create a new install set
639
- const taskInstallSet : InstallSet = {
640
- installs : [ ...args . installs ?? [ ] ] ,
641
- allowedBuildDeps : Object . fromEntries (
642
- reduceAllowedDeps ( args . allowedBuildDeps ?? [ ] ) . map ( (
643
- dep ,
644
- ) => [ dep . manifest . name , dep ] ) ,
645
- ) ,
646
- } ;
647
- if ( base ) {
648
- taskInstallSet . installs . push ( ...base . installSet . installs ) ;
649
- for (
650
- const [ key , val ] of Object . entries (
651
- base . installSet . allowedBuildDeps ,
652
- )
653
- ) {
654
- // prefer the port dep config of the child over any
655
- // similar deps in the base
656
- if ( ! taskInstallSet . allowedBuildDeps [ key ] ) {
657
- taskInstallSet . allowedBuildDeps [ key ] = val ;
656
+ ( envBaseResolved && envBaseResolved . length > 1 ) ;
657
+
658
+ // task only needs decalre a separate env
659
+ // if it's overriding/adding something
660
+ const needsSeparateEnv = needsSeparateSet || args . vars ;
661
+
662
+ let envKey : string | undefined ;
663
+ if ( needsSeparateEnv ) {
664
+ const base = envBaseResolved
665
+ ? this . #mergeEnvs( envBaseResolved , `____task_${ args . name ?? key } ` )
666
+ : null ;
667
+
668
+ let installSetId : string | undefined ;
669
+ if ( needsSeparateSet ) {
670
+ // we need to create a new install set
671
+ const taskInstallSet : InstallSet = {
672
+ installs : Array . isArray ( args . installs )
673
+ ? [ ...args . installs ]
674
+ : args . installs
675
+ ? [ args . installs ]
676
+ : [ ] ,
677
+ allowedBuildDeps : Object . fromEntries (
678
+ reduceAllowedDeps ( args . allowedBuildDeps ?? [ ] ) . map ( (
679
+ dep ,
680
+ ) => [ dep . manifest . name , dep ] ) ,
681
+ ) ,
682
+ } ;
683
+ if ( base ) {
684
+ taskInstallSet . installs . push ( ...base . installSet . installs ) ;
685
+ for (
686
+ const [ key , val ] of Object . entries (
687
+ base . installSet . allowedBuildDeps ,
688
+ )
689
+ ) {
690
+ // prefer the port dep config of the child over any
691
+ // similar deps in the base
692
+ if ( ! taskInstallSet . allowedBuildDeps [ key ] ) {
693
+ taskInstallSet . allowedBuildDeps [ key ] = val ;
694
+ }
658
695
}
659
696
}
697
+ installSetId = `ghjkTaskInstSet___${
698
+ objectHash ( JSON . parse ( JSON . stringify ( taskInstallSet ) ) )
699
+ } `;
700
+ this . #installSets. set ( installSetId , taskInstallSet ) ;
701
+ } else if ( envBaseResolved ?. length == 1 ) {
702
+ installSetId = this . finalizedEnvs [ envBaseResolved [ 0 ] ] . installSetId ;
660
703
}
661
- installSetId = `ghjkTaskInstSet___${
662
- objectHash ( JSON . parse ( JSON . stringify ( taskInstallSet ) ) )
663
- } `;
664
- this . #installSets. set ( installSetId , taskInstallSet ) ;
665
- } else if ( envBaseResolved ?. length == 1 ) {
666
- installSetId = this . finalizedEnvs [ envBaseResolved [ 0 ] ] . installSetId ;
667
- }
668
704
669
- const mergedEnvVars = {
670
- ...base ?. vars ,
671
- ...args . vars ,
672
- } ;
673
- const taskEnvRecipe : EnvRecipe = {
674
- provides : [
675
- ...Object . entries ( mergedEnvVars ) . map ( (
676
- [ key , val ] ,
677
- ) => {
678
- const prov : WellKnownProvision = {
679
- ty : "posix.envVar" ,
680
- key,
681
- val : val . toString ( ) ,
682
- } ;
683
- return prov ;
684
- } ) ,
685
- ] ,
686
- } ;
687
- if ( installSetId ) {
688
- const prov : InstallSetRefProvision = {
689
- ty : "ghjk.ports.InstallSetRef" ,
690
- setId : installSetId ,
705
+ const mergedEnvVars = {
706
+ ...base ?. vars ,
707
+ ...args . vars ,
691
708
} ;
692
- taskEnvRecipe . provides . push ( prov ) ;
693
- }
694
709
695
- const envHash = objectHash ( JSON . parse ( JSON . stringify ( taskEnvRecipe ) ) ) ;
696
- moduleConfig . envs [ envHash ] = taskEnvRecipe ;
710
+ const taskEnvRecipe : EnvRecipe = {
711
+ provides : [
712
+ ...Object . entries ( mergedEnvVars ) . map ( (
713
+ [ key , val ] ,
714
+ ) => {
715
+ const prov : WellKnownProvision = {
716
+ ty : "posix.envVar" ,
717
+ key,
718
+ val : val . toString ( ) ,
719
+ } ;
720
+ return prov ;
721
+ } ) ,
722
+ ] ,
723
+ } ;
724
+ if ( installSetId ) {
725
+ const prov : InstallSetRefProvision = {
726
+ ty : "ghjk.ports.InstallSetRef" ,
727
+ setId : installSetId ,
728
+ } ;
729
+ taskEnvRecipe . provides . push ( prov ) ;
730
+ }
731
+
732
+ const envHash = objectHash ( JSON . parse ( JSON . stringify ( taskEnvRecipe ) ) ) ;
733
+ gatheredEnvs [ envHash ] = taskEnvRecipe ;
734
+ envKey = envHash ;
735
+ } else if ( envBaseResolved ?. length == 1 ) {
736
+ envKey = envBaseResolved [ 0 ] ;
737
+ }
697
738
698
739
const def : TaskDefHashed = {
699
740
ty : args . ty ,
@@ -710,7 +751,7 @@ export class Ghjkfile {
710
751
) ,
711
752
}
712
753
: { } ,
713
- envHash ,
754
+ envKey ,
714
755
} ;
715
756
const taskHash = objectHash ( def ) ;
716
757
// we prefer the name as a key if present
@@ -767,6 +808,12 @@ export class Ghjkfile {
767
808
} ) ;
768
809
}
769
810
811
+ // add the task envs to the envsModuleConfig
812
+ for ( const [ hash , env ] of Object . entries ( gatheredEnvs ) ) {
813
+ envsConfig . envs [ hash ] = env ;
814
+ }
815
+
816
+ // reduce task based env hooks
770
817
for ( const [ _name , env ] of Object . entries ( envsConfig . envs ) ) {
771
818
env . provides = env . provides . map (
772
819
( prov ) => {
@@ -891,7 +938,10 @@ export class EnvBuilder {
891
938
* Add multiple environment variable.
892
939
*/
893
940
vars ( envVars : Record < string , string | number > ) {
894
- Object . assign ( this . #vars, envVars ) ;
941
+ Object . assign (
942
+ this . #vars,
943
+ unwrapParseRes ( validators . envVars . safeParse ( envVars ) , { envVars } ) ,
944
+ ) ;
895
945
return this ;
896
946
}
897
947
@@ -963,7 +1013,6 @@ type InlineTaskHookProvision = Provision & {
963
1013
export function reduceAllowedDeps (
964
1014
deps : ( AllowedPortDep | InstallConfigFat ) [ ] ,
965
1015
) : AllowedPortDep [ ] {
966
- console . log ( deps ) ;
967
1016
return deps . map (
968
1017
( dep : any ) => {
969
1018
{
0 commit comments