@@ -5,11 +5,14 @@ import (
55 "embed"
66 "fmt"
77 "os"
8+ "path"
89 "path/filepath"
910 "regexp"
1011 "strings"
1112 "text/template"
1213
14+ "golang.org/x/mod/module"
15+
1316 "github.com/launchrctl/launchr/internal/launchr"
1417 "github.com/launchrctl/launchr/pkg/cli"
1518 "github.com/launchrctl/launchr/pkg/log"
@@ -152,6 +155,13 @@ func (b *Builder) Build(ctx context.Context) error {
152155 return err
153156 }
154157
158+ // prebuild
159+ cli .Println ("Executing prebuild scripts" )
160+ err = b .preBuild (ctx )
161+ if err != nil {
162+ return err
163+ }
164+
155165 // Build the main go package.
156166 cli .Println ("Building %s" , b .PkgName )
157167 err = b .goBuild (ctx )
@@ -210,6 +220,101 @@ func (b *Builder) goBuild(ctx context.Context) error {
210220 return nil
211221}
212222
223+ func (b * Builder ) preBuild (ctx context.Context ) error {
224+ output , err := b .env .execGoList (ctx )
225+ if err != nil {
226+ return err
227+ }
228+
229+ pluginVersionMap := make (map [string ]string )
230+ lines := strings .Split (output , "\n " )
231+ for _ , line := range lines {
232+ pv := strings .Split (line , " " )
233+ for _ , p := range b .BuildOptions .Plugins {
234+ if strings .Contains (pv [0 ], p .Path ) {
235+ pluginVersionMap [p .Path ] = pv [1 ]
236+ continue
237+ }
238+ }
239+ }
240+
241+ assetsPath := filepath .Join (b .wd , b .env .wd , "assets" )
242+ buildName := filepath .Base (b .env .wd )
243+ err = os .MkdirAll (assetsPath , 0750 )
244+ if err != nil {
245+ return err
246+ }
247+
248+ for pluginName , v := range pluginVersionMap {
249+ packagePath , _ := getModulePath (pluginName , v )
250+ if _ , err = os .Stat (packagePath ); os .IsNotExist (err ) {
251+ log .Debug ("you don't have this module/version installed (%s)" , packagePath )
252+ continue
253+ }
254+
255+ // check if prebuild script exists.
256+ prebuildScriptPath := filepath .Join (packagePath , "scripts" , "prebuild.go" )
257+ if _ , err = os .Stat (prebuildScriptPath ); os .IsNotExist (err ) {
258+ log .Debug ("prebuild script does not exist for %s, skipping" , pluginName )
259+ continue
260+ }
261+
262+ tmpPath := filepath .Join (os .TempDir (), buildName , filepath .Base (pluginName ))
263+
264+ // clean tmp folder if it existed before.
265+ err = os .RemoveAll (tmpPath )
266+ if err != nil {
267+ return err
268+ }
269+
270+ // prepare tmp folder for assets and force prebuild script to push data there.
271+ err = os .MkdirAll (tmpPath , 0750 )
272+ if err != nil {
273+ return err
274+ }
275+
276+ log .Debug ("executing prebuild script for plugin %s" , pluginName )
277+ cmd := b .env .NewCommand (ctx , b .env .Go (), "run" , "scripts/prebuild.go" , v , tmpPath )
278+ cmd .Dir = packagePath
279+
280+ err = b .env .RunCmd (ctx , cmd )
281+ if err != nil {
282+ return err
283+ }
284+
285+ // prepare plugin assets folder.
286+ pluginAssetsPath := filepath .Join (assetsPath , pluginName )
287+ err = os .MkdirAll (pluginAssetsPath , 0750 )
288+ if err != nil {
289+ return err
290+ }
291+
292+ if _ , err = os .Stat (pluginAssetsPath ); err == nil {
293+ err = os .Remove (pluginAssetsPath )
294+ if err != nil {
295+ return err
296+ }
297+ }
298+
299+ // move assets from tmp dir to assets folder.
300+ err = os .Rename (tmpPath , pluginAssetsPath )
301+ if err != nil {
302+ return err
303+ }
304+ }
305+
306+ // create empty .info file for embed.
307+ // prevent embed error in case of 0 assets in folder.
308+ file , err := os .Create (filepath .Clean (filepath .Join (assetsPath , ".info" )))
309+ if err != nil {
310+ fmt .Println (err .Error ())
311+ os .Exit (2 )
312+ }
313+ defer file .Close ()
314+
315+ return nil
316+ }
317+
213318func (b * Builder ) runGen (ctx context.Context ) error {
214319 genArgs := []string {"generate" , "./..." }
215320 cmd := b .env .NewCommand (ctx , b .env .Go (), genArgs ... )
@@ -221,3 +326,22 @@ func (b *Builder) runGen(ctx context.Context) error {
221326 cmd .Env = env
222327 return b .env .RunCmd (ctx , cmd )
223328}
329+
330+ func getModulePath (name , version string ) (string , error ) {
331+ cache , ok := os .LookupEnv ("GOMODCACHE" )
332+ if ! ok {
333+ cache = path .Join (os .Getenv ("GOPATH" ), "pkg" , "mod" )
334+ }
335+
336+ escapedPath , err := module .EscapePath (name )
337+ if err != nil {
338+ return "" , err
339+ }
340+
341+ escapedVersion , err := module .EscapeVersion (version )
342+ if err != nil {
343+ return "" , err
344+ }
345+
346+ return path .Join (cache , escapedPath + "@" + escapedVersion ), nil
347+ }
0 commit comments