@@ -528,7 +528,11 @@ func Generate(location string, envs []string, verbose bool) error {
528528 return nil
529529}
530530
531- func ModAddLocalModule (module * ExtensionModule , target string ) error {
531+ func ModAddLocalModule (
532+ module * TenPackageModule ,
533+ target string ,
534+ moduleType string ,
535+ ) error {
532536 // go mod edit -replace <mod>=<full path>
533537 //
534538 // Note that the module must be replaced with the full path, as the module
@@ -540,8 +544,9 @@ func ModAddLocalModule(module *ExtensionModule, target string) error {
540544 "edit" ,
541545 "-replace" ,
542546 fmt .Sprintf (
543- "%s=./ten_packages/extension /%s" ,
547+ "%s=./ten_packages/%s /%s" ,
544548 module .module ,
549+ moduleType ,
545550 path .Base (module .location ),
546551 ),
547552 },
@@ -613,11 +618,12 @@ func (b *BuildOption) Valid() error {
613618// -------------- builder ----------------
614619
615620type AppBuilder struct {
616- pkgName string
617- acquiredGoVersion string
618- options * BuildOption
619- cachedEnv map [string ]string
620- extensions []* ExtensionModule
621+ pkgName string
622+ acquiredGoVersion string
623+ options * BuildOption
624+ cachedEnv map [string ]string
625+ extensionPackageModules []* TenPackageModule
626+ systemPackageModules []* TenPackageModule
621627}
622628
623629func NewAppBuilder (
@@ -626,18 +632,19 @@ func NewAppBuilder(
626632 options * BuildOption ,
627633) * AppBuilder {
628634 return & AppBuilder {
629- pkgName : pkgName ,
630- acquiredGoVersion : goVersion ,
631- options : options ,
632- cachedEnv : make (map [string ]string ),
633- extensions : make ([]* ExtensionModule , 0 ),
635+ pkgName : pkgName ,
636+ acquiredGoVersion : goVersion ,
637+ options : options ,
638+ cachedEnv : make (map [string ]string ),
639+ extensionPackageModules : make ([]* TenPackageModule , 0 ),
640+ systemPackageModules : make ([]* TenPackageModule , 0 ),
634641 }
635642}
636643
637644// runTidyAndGenerate executes 'go mod tidy' and 'go generate' on GO app and all
638645// GO extensions.
639646func (ab * AppBuilder ) runTidyAndGenerate (envs []string ) error {
640- for _ , ext := range ab .extensions {
647+ for _ , ext := range ab .extensionPackageModules {
641648 if err := ModTidy (ext .location , envs , ab .options .Verbose ); err != nil {
642649 return err
643650 }
@@ -690,9 +697,16 @@ func (ab *AppBuilder) Build() error {
690697 return fmt .Errorf ("precheck failed. Root cause: \n \t %w" , err )
691698 }
692699
693- if err := ab .autoDetectExtensions (); err != nil {
700+ if err := ab .autoDetectExtensionPackageModules (); err != nil {
694701 return fmt .Errorf (
695- "auto detect extensions failed. Root cause: \n \t %w" ,
702+ "auto detect extension packages failed. Root cause: \n \t %w" ,
703+ err ,
704+ )
705+ }
706+
707+ if err := ab .autoDetectSystemPackageModules (); err != nil {
708+ return fmt .Errorf (
709+ "auto detect system packages failed. Root cause: \n \t %w" ,
696710 err ,
697711 )
698712 }
@@ -713,7 +727,7 @@ func (ab *AppBuilder) Build() error {
713727 return err
714728 }
715729
716- if err := ab .requireExtensionModules (); err != nil {
730+ if err := ab .requireExtensionAndSystemPackageModules (); err != nil {
717731 return err
718732 }
719733
@@ -967,21 +981,69 @@ func (ab *AppBuilder) buildExecEnvs() []string {
967981
968982// -------------- extension --------------
969983
970- type ExtensionModule struct {
984+ type TenPackageModule struct {
971985 // The module name in go.mod
972986 module string
973987
974988 location string
975989}
976990
977- func (em * ExtensionModule ) String () string {
978- return fmt .Sprintf ("%s @ %s" , em .module , em .location )
991+ func (tpm * TenPackageModule ) String () string {
992+ return fmt .Sprintf ("%s @ %s" , tpm .module , tpm .location )
979993}
980994
981- func LoadExtensionModule (
995+ func LoadSystemPackageModule (
982996 location string ,
983997 verbose bool ,
984- ) (* ExtensionModule , error ) {
998+ ) (* TenPackageModule , error ) {
999+ // Check if the folder contains a manifest.json to determine if it is a
1000+ // system package.
1001+ if ! IsFilePresent (path .Join (location , "manifest.json" )) {
1002+ if verbose {
1003+ log .Printf (
1004+ "%s is not a system package, no manifest.json.\n " ,
1005+ location ,
1006+ )
1007+ }
1008+
1009+ return nil , nil
1010+ }
1011+
1012+ // Check if the folder contains a go.mod to determine if it is a GO system
1013+ // package.
1014+ modFile := path .Join (location , "go.mod" )
1015+ if ! IsFilePresent (modFile ) {
1016+ if verbose {
1017+ log .Printf ("%s is not a GO system package, no go.mod" , location )
1018+ }
1019+
1020+ return nil , nil
1021+ }
1022+
1023+ bytes , err := os .ReadFile (modFile )
1024+ if err != nil {
1025+ return nil , fmt .Errorf (
1026+ "%s system package is invalid. \n \t %w" ,
1027+ location ,
1028+ err ,
1029+ )
1030+ }
1031+
1032+ module := ModulePath (bytes )
1033+ if len (module ) == 0 {
1034+ return nil , fmt .Errorf ("no mod is detected in %s/go.mod" , location )
1035+ }
1036+
1037+ return & TenPackageModule {
1038+ module : module ,
1039+ location : location ,
1040+ }, nil
1041+ }
1042+
1043+ func LoadExtensionPackageModule (
1044+ location string ,
1045+ verbose bool ,
1046+ ) (* TenPackageModule , error ) {
9851047 // Check if the folder contains a manifest.json to determine if it is an
9861048 // extension.
9871049 if ! IsFilePresent (path .Join (location , "manifest.json" )) {
@@ -1024,13 +1086,58 @@ func LoadExtensionModule(
10241086 return nil , fmt .Errorf ("no mod is detected in %s/go.mod" , location )
10251087 }
10261088
1027- return & ExtensionModule {
1089+ return & TenPackageModule {
10281090 module : module ,
10291091 location : location ,
10301092 }, nil
10311093}
10321094
1033- func (ab * AppBuilder ) autoDetectExtensions () error {
1095+ func (ab * AppBuilder ) autoDetectSystemPackageModules () error {
1096+ sysBaseDir := path .Join (ab .options .AppDir , "ten_packages/system" )
1097+ if ! IsDirPresent (sysBaseDir ) {
1098+ if ab .options .Verbose {
1099+ log .Println (
1100+ "The base directory [ten_packages/system] is absent, no system packages." ,
1101+ )
1102+ }
1103+
1104+ return nil
1105+ }
1106+
1107+ entries , err := os .ReadDir (sysBaseDir )
1108+ if err != nil {
1109+ return err
1110+ }
1111+
1112+ // Check if the system package is a GO module.
1113+ for _ , entry := range entries {
1114+ if entry .IsDir () {
1115+ sysModFile := path .Join (sysBaseDir , entry .Name (), "go.mod" )
1116+ if ! IsFilePresent (sysModFile ) {
1117+ continue
1118+ }
1119+
1120+ sysModDir := path .Join (sysBaseDir , entry .Name ())
1121+ sysMod , err := LoadSystemPackageModule (
1122+ sysModDir ,
1123+ ab .options .Verbose ,
1124+ )
1125+ if err != nil {
1126+ return err
1127+ }
1128+
1129+ if sysMod == nil {
1130+ continue
1131+ }
1132+
1133+ ab .systemPackageModules = append (ab .systemPackageModules , sysMod )
1134+ }
1135+ }
1136+
1137+ return nil
1138+ }
1139+
1140+ func (ab * AppBuilder ) autoDetectExtensionPackageModules () error {
10341141 extBaseDir := path .Join (ab .options .AppDir , "ten_packages/extension" )
10351142 if ! IsDirPresent (extBaseDir ) {
10361143 if ab .options .Verbose {
@@ -1136,7 +1243,7 @@ func (ab *AppBuilder) autoDetectExtensions() error {
11361243 }
11371244
11381245 extDir := path .Join (extBaseDir , entry .Name ())
1139- ext , err := LoadExtensionModule (extDir , ab .options .Verbose )
1246+ ext , err := LoadExtensionPackageModule (extDir , ab .options .Verbose )
11401247 if err != nil {
11411248 return err
11421249 }
@@ -1156,12 +1263,12 @@ func (ab *AppBuilder) autoDetectExtensions() error {
11561263 }
11571264
11581265 uniqueModules [ext .module ] = ext .location
1159- ab .extensions = append (ab .extensions , ext )
1266+ ab .extensionPackageModules = append (ab .extensionPackageModules , ext )
11601267 }
11611268
1162- if ab .options .Verbose && len (ab .extensions ) > 0 {
1269+ if ab .options .Verbose && len (ab .extensionPackageModules ) > 0 {
11631270 log .Println ("Go Extensions are detected:" )
1164- for _ , ext := range ab .extensions {
1271+ for _ , ext := range ab .extensionPackageModules {
11651272 log .Printf ("\t %s\n " , ext )
11661273 }
11671274 }
@@ -1241,7 +1348,7 @@ func (ab *AppBuilder) generateAutoImportFile() error {
12411348 }
12421349 }
12431350
1244- if len (ab .extensions ) == 0 {
1351+ if len (ab .extensionPackageModules ) == 0 {
12451352 log .Println (
12461353 "No extension is detected, no need to generate import file." ,
12471354 )
@@ -1259,7 +1366,7 @@ func (ab *AppBuilder) generateAutoImportFile() error {
12591366 _ , _ = f .WriteString ("// Code generated by app builder. DO NOT EDIT.\n \n " )
12601367 _ , _ = f .WriteString (fmt .Sprintf ("package %s\n \n " , ab .pkgName ))
12611368
1262- for _ , ext := range ab .extensions {
1369+ for _ , ext := range ab .extensionPackageModules {
12631370 _ , _ = f .WriteString (fmt .Sprintf ("import _ \" %s\" \n " , ext .module ))
12641371 }
12651372
@@ -1270,10 +1377,11 @@ func (ab *AppBuilder) generateAutoImportFile() error {
12701377 return nil
12711378}
12721379
1273- func (ab * AppBuilder ) requireExtensionModules () error {
1274- if len (ab .extensions ) == 0 {
1380+ func (ab * AppBuilder ) requireExtensionAndSystemPackageModules () error {
1381+ if len (ab .extensionPackageModules ) == 0 &&
1382+ len (ab .systemPackageModules ) == 0 {
12751383 log .Println (
1276- "No extension is detected, no need to require extension modules." ,
1384+ "No extension or system package is detected, no need to require extension and system modules." ,
12771385 )
12781386
12791387 return nil
@@ -1299,9 +1407,9 @@ func (ab *AppBuilder) requireExtensionModules() error {
12991407 }
13001408 }
13011409
1302- // Add GO extensions as the module of the app.
1303- for _ , ext := range ab .extensions {
1304- if err := ModAddLocalModule (ext , ab .options .AppDir ); err != nil {
1410+ // Add GO extension packages as the module of the app.
1411+ for _ , ext := range ab .extensionPackageModules {
1412+ if err := ModAddLocalModule (ext , ab .options .AppDir , "extension" ); err != nil {
13051413 return fmt .Errorf (
13061414 "Failed to add %s as go module of the app. \n \t %w" ,
13071415 ext .location ,
@@ -1310,6 +1418,17 @@ func (ab *AppBuilder) requireExtensionModules() error {
13101418 }
13111419 }
13121420
1421+ // Add GO system packages as the module of the app.
1422+ for _ , sys := range ab .systemPackageModules {
1423+ if err := ModAddLocalModule (sys , ab .options .AppDir , "system" ); err != nil {
1424+ return fmt .Errorf (
1425+ "Failed to add %s as go module of the app. \n \t %w" ,
1426+ sys .location ,
1427+ err ,
1428+ )
1429+ }
1430+ }
1431+
13131432 if ab .options .Verbose {
13141433 log .Println ("Add extension modules to app successfully." )
13151434 }
0 commit comments