Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: simplify init #9

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 120 additions & 5 deletions cmd/init/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,21 @@ package init
import (
"fmt"
"os"
"time"

tea "github.com/charmbracelet/bubbletea"
"github.com/jedib0t/go-pretty/v6/progress"
"github.com/spf13/cobra"

bsfv1 "github.com/buildsafedev/bsf-apis/go/buildsafe/v1"
"github.com/buildsafedev/bsf/cmd/configure"
"github.com/buildsafedev/bsf/cmd/precheck"
"github.com/buildsafedev/bsf/cmd/styles"
"github.com/buildsafedev/bsf/pkg/clients/search"
"github.com/buildsafedev/bsf/pkg/generate"
bgit "github.com/buildsafedev/bsf/pkg/git"
"github.com/buildsafedev/bsf/pkg/hcl2nix"
"github.com/buildsafedev/bsf/pkg/langdetect"
"github.com/buildsafedev/bsf/pkg/nix/cmd"
)

// InitCmd represents the init command
Expand All @@ -35,17 +40,103 @@ var InitCmd = &cobra.Command{

sc, err := search.NewClientWithAddr(conf.BuildSafeAPI, conf.BuildSafeAPITLS)
if err != nil {
fmt.Println(styles.ErrorStyle.Render("error:", err.Error()))
os.Exit(1)
}

m := model{sc: sc}
m.resetSpinner()
if _, err := tea.NewProgram(m).Run(); err != nil {
err = initializeProject(sc)
if err != nil {
errorMessage := err.Error()
fmt.Println(styles.ErrorStyle.Render("Error:", errorMessage))
if errorMessage != "project already initialised. bsf.hcl found" {
cleanUp()
}
os.Exit(1)
}

fmt.Println(styles.SucessStyle.Render("Initialized successfully!"))
},
}

func initializeProject(sc bsfv1.SearchServiceClient) error {
// Set up the progress writer
pw, steps := setupProgressTracker()

trackers := make([]*progress.Tracker, len(steps))
for i, step := range steps {
trackers[i] = &progress.Tracker{Message: step, Total: 100}
pw.AppendTracker(trackers[i])
}

go pw.Render()

// Initialize progress tracking
updateProgress := func(tracker *progress.Tracker, progress int64) {
tracker.SetValue(progress)
if progress >= 100 {
tracker.MarkAsDone()
}
}

// Detect project language
pt, pd, err := langdetect.FindProjectType()
if err != nil {
return err
}
updateProgress(trackers[0], 100)

// Resolve dependencies
fh, err := hcl2nix.NewFileHandlers(false)
if err != nil {
return err
}
defer fh.ModFile.Close()
defer fh.LockFile.Close()
defer fh.FlakeFile.Close()
defer fh.DefFlakeFile.Close()
updateProgress(trackers[1], 100)

// Write configuration
conf, err := generatehcl2NixConf(pt, pd)
if err != nil {
return err
}
err = hcl2nix.WriteConfig(conf, fh.ModFile)
if err != nil {
return err
}
updateProgress(trackers[2], 100)

// Generate files
err = generate.Generate(fh, sc)
if err != nil {
return err
}
updateProgress(trackers[3], 100)

// Lock dependencies
err = cmd.Lock(func(progress int) {
updateProgress(trackers[4], int64(progress))
})
if err != nil {
return err
}

// Add to git
err = bgit.Add("bsf/")
if err != nil {
return err
}

// Set up git ignore
err = bgit.Ignore("bsf-result/")
if err != nil {
return err
}

return nil
}

// GetBSFInitializers generates the nix files
func GetBSFInitializers() (bsfv1.SearchServiceClient, *hcl2nix.FileHandlers, error) {
if _, err := os.Stat("bsf.hcl"); err != nil {
Expand All @@ -72,10 +163,34 @@ func GetBSFInitializers() (bsfv1.SearchServiceClient, *hcl2nix.FileHandlers, err
}

// CleanUp removes the bsf config if any error occurs in init process (ctrl+c or any init process stage)
func cleanUp(){
func cleanUp() {
configs := []string{"bsf", "bsf.hcl", "bsf.lock"}

for _, f := range configs {
os.RemoveAll(f)
}
}

func setupProgressTracker() (progress.Writer, []string) {
pw := progress.NewWriter()
pw.SetAutoStop(true)
pw.SetTrackerLength(25)
pw.SetMessageLength(50)
pw.SetUpdateFrequency(time.Millisecond * 100)
pw.Style().Colors = progress.StyleColorsExample
pw.Style().Options.PercentFormat = "%4.1f%%"
pw.Style().Visibility.ETA = true
pw.Style().Visibility.Percentage = true
pw.Style().Visibility.Time = true

// Define the steps and create trackers for each
steps := []string{
"Detecting project language...",
"Resolving dependencies...",
"Writing configuration...",
"Generating files...",
"Locking dependencies...",
}

return pw, steps
}
159 changes: 0 additions & 159 deletions cmd/init/model.go

This file was deleted.

2 changes: 1 addition & 1 deletion pkg/hcl2nix/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func NewFileHandlers(expectInit bool) (*FileHandlers, error) {
}

if exists != expectInit {
return nil, fmt.Errorf("Project already initialised. bsf.hcl found")
return nil, fmt.Errorf("project already initialised. bsf.hcl found")
}

lockFile, err := os.Create("bsf.lock")
Expand Down
1 change: 0 additions & 1 deletion pkg/nix/cmd/closure.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,6 @@ func addNarHashToGraph(graph *gographviz.Graph) {
}

wg.Wait()
return
}

// GetNarHashFromPath returns the sha256 hash of the nar
Expand Down
9 changes: 8 additions & 1 deletion pkg/nix/cmd/lock.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import (
"fmt"
"os"
"os/exec"
"time"
)

// Lock generates the Nix flake lock file
func Lock() error {
func Lock(reportProgress func(int)) error {
dir, err := os.Getwd()
if err != nil {
return err
Expand All @@ -24,6 +25,12 @@ func Lock() error {
return fmt.Errorf("failed with %s", err)
}

// Simulate incremental progress
for i := 0; i <= 100; i += 10 {
time.Sleep(100 * time.Millisecond)
reportProgress(i)
}

err = cmd.Wait()
if err != nil {
if exitError, ok := err.(*exec.ExitError); ok {
Expand Down
Loading