@@ -19,6 +19,7 @@ import (
1919 "errors"
2020 "fmt"
2121 "os"
22+ "path/filepath"
2223 "regexp"
2324 "slices"
2425 "strings"
@@ -111,6 +112,22 @@ var (
111112 DisableSliceFlagSeparator : true ,
112113 ArgsUsage : "[working-dir]" ,
113114 },
115+ {
116+ Name : "dockerfile" ,
117+ Usage : "Generate Dockerfile and .dockerignore for your project" ,
118+ Before : createAgentClient ,
119+ Action : generateAgentDockerfile ,
120+ Flags : []cli.Flag {
121+ silentFlag ,
122+ & cli.BoolFlag {
123+ Name : "overwrite" ,
124+ Usage : "Overwrite existing Dockerfile and/or .dockerignore if they exist" ,
125+ Required : false ,
126+ Value : false ,
127+ },
128+ },
129+ ArgsUsage : "[working-dir]" ,
130+ },
114131 {
115132 Name : "config" ,
116133 Usage : fmt .Sprintf ("Creates a %s in the working directory for an existing agent." , config .LiveKitTOMLFile ),
@@ -378,6 +395,7 @@ func createAgent(ctx context.Context, cmd *cli.Command) error {
378395 }
379396
380397 projectType , err := agentfs .DetectProjectType (workingDir )
398+ fmt .Printf ("Detected project type [%s]\n " , util .Accented (string (projectType )))
381399 if err != nil {
382400 return fmt .Errorf ("unable to determine project type: %w, please use a supported project type, or create your own Dockerfile in the current directory" , err )
383401 }
@@ -1232,3 +1250,68 @@ func requireConfig(workingDir, tomlFilename string) (bool, error) {
12321250 lkConfig , exists , err = config .LoadTOMLFile (workingDir , tomlFilename )
12331251 return exists , err
12341252}
1253+
1254+ func generateAgentDockerfile (ctx context.Context , cmd * cli.Command ) error {
1255+ if cmd .NArg () > 0 {
1256+ workingDir = cmd .Args ().First ()
1257+ }
1258+
1259+ if stat , err := os .Stat (workingDir ); err != nil || ! stat .IsDir () {
1260+ return fmt .Errorf ("invalid working directory: %s" , workingDir )
1261+ }
1262+
1263+ settingsMap , err := getClientSettings (ctx , cmd .Bool ("silent" ))
1264+ if err != nil {
1265+ return err
1266+ }
1267+
1268+ projectType , err := agentfs .DetectProjectType (workingDir )
1269+ fmt .Printf ("Detected project type [%s]\n " , util .Accented (string (projectType )))
1270+ if err != nil {
1271+ return fmt .Errorf ("unable to determine project type: %w, please use a supported project type, or create your own Dockerfile in the current directory" , err )
1272+ }
1273+
1274+ dockerfilePath := filepath .Join (workingDir , "Dockerfile" )
1275+ dockerignorePath := filepath .Join (workingDir , ".dockerignore" )
1276+ overwrite := cmd .Bool ("overwrite" )
1277+
1278+ writeDockerfile := true
1279+ writeDockerignore := true
1280+ if ! overwrite {
1281+ if _ , err := os .Stat (dockerfilePath ); err == nil {
1282+ fmt .Println (util .Accented ("Dockerfile" ) + " already exists; skipping. Use --overwrite to replace." )
1283+ writeDockerfile = false
1284+ }
1285+ if _ , err := os .Stat (dockerignorePath ); err == nil {
1286+ fmt .Println (util .Accented (".dockerignore" ) + " already exists; skipping. Use --overwrite to replace." )
1287+ writeDockerignore = false
1288+ }
1289+ }
1290+
1291+ if ! writeDockerfile && ! writeDockerignore {
1292+ return nil
1293+ }
1294+
1295+ // Generate contents without writing
1296+ dockerfileContent , dockerignoreContent , err := agentfs .GenerateDockerArtifacts (workingDir , projectType , settingsMap )
1297+ if err != nil {
1298+ return err
1299+ }
1300+
1301+ if writeDockerfile {
1302+ if err := os .WriteFile (dockerfilePath , dockerfileContent , 0644 ); err != nil {
1303+ return err
1304+ }
1305+
1306+ fmt .Printf ("Wrote new %s\n " , util .Accented ("Dockerfile" ))
1307+ }
1308+
1309+ if writeDockerignore {
1310+ if err := os .WriteFile (dockerignorePath , dockerignoreContent , 0644 ); err != nil {
1311+ return err
1312+ }
1313+ fmt .Printf ("Wrote new %s\n " , util .Accented (".dockerignore" ))
1314+ }
1315+
1316+ return nil
1317+ }
0 commit comments