1
1
package command
2
2
3
3
import (
4
- "archive/tar"
5
- "compress/gzip"
6
4
"context"
7
- "encoding/json"
8
5
"errors"
9
6
"fmt"
10
7
"io"
11
8
"math/rand"
12
- "net/http"
13
9
"os"
14
10
"os/exec"
15
11
"regexp"
@@ -433,58 +429,39 @@ var generateCmd = &cobra.Command{
433
429
Message : "Choose the language you'd like to use:" ,
434
430
Options : []string {"Nodejs" , "Golang" , "Python" },
435
431
Default : "Nodejs" ,
436
- Help : "The generated code will be in the language you choose here." ,
432
+ Help : "The project code will be in the language you choose here." ,
437
433
}, & language ); err != nil {
438
434
return err
439
435
}
440
436
441
- var samples []struct {
442
- Name string `json:"name"`
443
- Category string `json:"category"`
444
- Readme string `json:"readme"`
445
- }
446
- req , err := http .NewRequestWithContext (cmd .Context (), http .MethodGet , "https://docs.defang.io/samples.json" , nil )
447
- if err != nil {
448
- return err
449
- }
450
- req .Header .Set ("Accept-Encoding" , "gzip" )
451
- resp , err := httpClient .Do (req )
452
- if err == nil {
453
- defer resp .Body .Close ()
454
- term .Debug (resp .Header )
455
- // Check that the server actually sent compressed data
456
- reader := resp .Body
457
- if resp .Header .Get ("Content-Encoding" ) == "gzip" {
458
- reader , err = gzip .NewReader (resp .Body )
459
- if err != nil {
460
- return err
461
- }
462
- defer reader .Close ()
463
- }
464
- if json .NewDecoder (reader ).Decode (& samples ) != nil {
465
- term .Debug (" - unable to decode samples.json:" , err )
466
- }
467
- }
437
+ var category , sample string
468
438
469
- const generateWithAI = "Generate with AI"
439
+ // Fetch the list of samples from the Defang repository
440
+ if samples , err := cli .FetchSamples (cmd .Context ()); err != nil {
441
+ term .Debug (" - unable to fetch samples:" , err )
442
+ } else if len (samples ) > 0 {
443
+ const generateWithAI = "Generate with AI"
470
444
471
- language = strings .ToLower (language ) // make it match the category strings
472
- sampleNames := []string {generateWithAI }
473
- // sampleDescriptions := []string{"Generate a sample from scratch using a language prompt"}
474
- for _ , sample := range samples {
475
- if sample .Category == language {
476
- sampleNames = append (sampleNames , sample .Name )
477
- // sampleDescriptions = append(sampleDescriptions, sample.Readme)
445
+ category = strings .ToLower (language )
446
+ sampleNames := []string {generateWithAI }
447
+ // sampleDescriptions := []string{"Generate a sample from scratch using a language prompt"}
448
+ for _ , sample := range samples {
449
+ if sample .Category == category {
450
+ sampleNames = append (sampleNames , sample .Name )
451
+ // sampleDescriptions = append(sampleDescriptions, sample.Readme)
452
+ }
478
453
}
479
- }
480
454
481
- var sample string
482
- if err := survey .AskOne (& survey.Select {
483
- Message : "Choose a sample service:" ,
484
- Options : sampleNames ,
485
- Help : "The generated code will be based on the sample you choose here." ,
486
- }, & sample ); err != nil {
487
- return err
455
+ if err := survey .AskOne (& survey.Select {
456
+ Message : "Choose a sample service:" ,
457
+ Options : sampleNames ,
458
+ Help : "The project code will be based on the sample you choose here." ,
459
+ }, & sample ); err != nil {
460
+ return err
461
+ }
462
+ if sample == generateWithAI {
463
+ sample = ""
464
+ }
488
465
}
489
466
490
467
var qs = []* survey.Question {
@@ -511,8 +488,8 @@ Generate will write files in the current folder. You can edit them and then depl
511
488
},
512
489
}
513
490
514
- if sample != generateWithAI {
515
- qs = qs [1 :] // skip the description question
491
+ if sample != "" {
492
+ qs = qs [1 :] // user picked a sample, so we skip the description question
516
493
}
517
494
518
495
prompt := struct {
@@ -521,7 +498,7 @@ Generate will write files in the current folder. You can edit them and then depl
521
498
}{}
522
499
523
500
// ask the remaining questions
524
- err = survey .Ask (qs , & prompt )
501
+ err : = survey .Ask (qs , & prompt )
525
502
if err != nil {
526
503
return err
527
504
}
@@ -555,49 +532,16 @@ Generate will write files in the current folder. You can edit them and then depl
555
532
556
533
if prompt .Description != "" {
557
534
term .Info (" * Working on it. This may take 1 or 2 minutes..." )
558
- _ , err = cli .Generate (cmd .Context (), client , language , prompt .Description )
535
+ _ , err : = cli .GenerateWithAI (cmd .Context (), client , language , prompt .Description )
559
536
if err != nil {
560
537
return err
561
538
}
562
539
} else {
563
540
term .Info (" * Fetching sample from the Defang repository..." )
564
- resp , err := http .Get ("https://github.com/defang-io/defang/archive/refs/heads/main.tar.gz" )
565
- if err != nil {
566
- return err
567
- }
568
- defer resp .Body .Close ()
569
- term .Debug (resp .Header )
570
- body , err := gzip .NewReader (resp .Body )
541
+ err := cli .InitFromSample (cmd .Context (), category , sample )
571
542
if err != nil {
572
543
return err
573
544
}
574
- defer body .Close ()
575
- tarReader := tar .NewReader (body )
576
- term .Info (" * Writing files to disk..." )
577
- for {
578
- h , err := tarReader .Next ()
579
- if err != nil {
580
- if err == io .EOF {
581
- break
582
- }
583
- return err
584
- }
585
-
586
- if base , ok := strings .CutPrefix (h .Name , "defang-main/samples/" + language + "/" + sample + "/" ); ok && len (base ) > 0 {
587
- fmt .Println (" -" , base )
588
- if h .FileInfo ().IsDir () {
589
- os .MkdirAll (base , 0755 )
590
- continue
591
- }
592
- f , err := os .Create (base )
593
- if err != nil {
594
- return err
595
- }
596
- if _ , err := io .Copy (f , tarReader ); err != nil {
597
- return err
598
- }
599
- }
600
- }
601
545
}
602
546
603
547
term .Info (" * Code generated successfully in folder" , prompt .Folder )
0 commit comments