diff --git a/cli/installations.go b/cli/installations.go index 1bb6218..a70e840 100644 --- a/cli/installations.go +++ b/cli/installations.go @@ -37,6 +37,7 @@ type Installation struct { DiskInstance disk.Disk `json:"-"` Path string `json:"path"` Profile string `json:"profile"` + Vanilla bool `json:"vanilla"` } func InitInstallations() (*Installations, error) { @@ -127,6 +128,7 @@ func (i *Installations) AddInstallation(ctx *GlobalContext, installPath string, installation := &Installation{ Path: absolutePath, Profile: profile, + Vanilla: false, } if err := installation.Validate(ctx); err != nil { @@ -285,16 +287,23 @@ func (i *Installation) WriteLockFile(ctx *GlobalContext, lockfile LockFile) erro return err } - marshaledLockfile, err := json.MarshalIndent(lockfile, "", " ") - if err != nil { - return errors.Wrap(err, "failed to serialize lockfile json") - } - d, err := i.GetDisk() if err != nil { return err } + lockfileDir := filepath.Dir(lockfilePath) + if err := d.Exists(lockfileDir); d.IsNotExist(err) { + if err := d.MkDir(lockfileDir); err != nil { + return errors.Wrap(err, "failed creating lockfile directory") + } + } + + marshaledLockfile, err := json.MarshalIndent(lockfile, "", " ") + if err != nil { + return errors.Wrap(err, "failed to serialize lockfile json") + } + if err := d.Write(lockfilePath, marshaledLockfile); err != nil { return errors.Wrap(err, "failed writing lockfile") } @@ -302,6 +311,31 @@ func (i *Installation) WriteLockFile(ctx *GlobalContext, lockfile LockFile) erro return nil } +func (i *Installation) ResolveProfile(ctx *GlobalContext) (LockFile, error) { + lockFile, err := i.LockFile(ctx) + if err != nil { + return nil, err + } + + resolver := NewDependencyResolver(ctx.APIClient) + + gameVersion, err := i.GetGameVersion(ctx) + if err != nil { + return nil, errors.Wrap(err, "failed to detect game version") + } + + lockfile, err := ctx.Profiles.Profiles[i.Profile].Resolve(resolver, lockFile, gameVersion) + if err != nil { + return nil, errors.Wrap(err, "could not resolve mods") + } + + if err := i.WriteLockFile(ctx, lockfile); err != nil { + return nil, errors.Wrap(err, "failed to write lockfile") + } + + return lockfile, nil +} + type InstallUpdate struct { ModName string OverallProgress float64 @@ -314,21 +348,14 @@ func (i *Installation) Install(ctx *GlobalContext, updates chan InstallUpdate) e return errors.Wrap(err, "failed to validate installation") } - lockFile, err := i.LockFile(ctx) - if err != nil { - return err - } + lockfile := make(LockFile) - resolver := NewDependencyResolver(ctx.APIClient) - - gameVersion, err := i.GetGameVersion(ctx) - if err != nil { - return errors.Wrap(err, "failed to detect game version") - } - - lockfile, err := ctx.Profiles.Profiles[i.Profile].Resolve(resolver, lockFile, gameVersion) - if err != nil { - return errors.Wrap(err, "could not resolve mods") + if !i.Vanilla { + var err error + lockfile, err = i.ResolveProfile(ctx) + if err != nil { + return errors.Wrap(err, "failed to resolve lockfile") + } } d, err := i.GetDisk() @@ -435,7 +462,7 @@ func (i *Installation) Install(ctx *GlobalContext, updates chan InstallUpdate) e completed++ } - return i.WriteLockFile(ctx, lockfile) + return nil } func (i *Installation) SetProfile(ctx *GlobalContext, profile string) error { diff --git a/cli/installations_test.go b/cli/installations_test.go index 139eb3e..a60396c 100644 --- a/cli/installations_test.go +++ b/cli/installations_test.go @@ -37,5 +37,9 @@ func TestAddInstallation(t *testing.T) { err = installation.Install(ctx, nil) testza.AssertNoError(t, err) + + installation.Vanilla = true + err = installation.Install(ctx, nil) + testza.AssertNoError(t, err) } } diff --git a/cmd/installation/set-vanilla.go b/cmd/installation/set-vanilla.go new file mode 100644 index 0000000..ededcac --- /dev/null +++ b/cmd/installation/set-vanilla.go @@ -0,0 +1,46 @@ +package installation + +import ( + "github.com/pkg/errors" + "github.com/spf13/cobra" + "github.com/spf13/viper" + + "github.com/satisfactorymodding/ficsit-cli/cli" +) + +func init() { + setVanillaCmd.Flags().BoolP("off", "o", false, "Disable vanilla") + + Cmd.AddCommand(setVanillaCmd) +} + +var setVanillaCmd = &cobra.Command{ + Use: "set-vanilla ", + Short: "Set the installation to vanilla mode or not", + Args: cobra.ExactArgs(1), + PreRun: func(cmd *cobra.Command, args []string) { + _ = viper.BindPFlag("off", cmd.Flags().Lookup("off")) + }, + RunE: func(cmd *cobra.Command, args []string) error { + global, err := cli.InitCLI(false) + if err != nil { + return err + } + + var installation *cli.Installation + for _, install := range global.Installations.Installations { + if install.Path == args[0] { + installation = install + break + } + } + + if installation == nil { + return errors.New("installation not found") + } + + installation.Vanilla = !viper.GetBool("off") + + return global.Save() + }, +} diff --git a/tea/components/header.go b/tea/components/header.go index 54cd599..59b6efc 100644 --- a/tea/components/header.go +++ b/tea/components/header.go @@ -44,6 +44,18 @@ func (h headerComponent) View() string { } else { out += "None" } + out += "\n" + + out += h.labelStyle.Render("Vanilla: ") + if h.root.GetCurrentInstallation() != nil { + if h.root.GetCurrentInstallation().Vanilla { + out += "On" + } else { + out += "Off" + } + } else { + out += "N/A" + } return lipgloss.NewStyle().Margin(1, 0).Render(out) } diff --git a/tea/scenes/main_menu.go b/tea/scenes/main_menu.go index fe64903..1d017da 100644 --- a/tea/scenes/main_menu.go +++ b/tea/scenes/main_menu.go @@ -73,6 +73,13 @@ func NewMainMenu(root components.RootModel) tea.Model { return newModel, newModel.Init() }, }, + utils.SimpleItem[mainMenu]{ + ItemTitle: "Toggle Vanilla", + Activate: func(msg tea.Msg, currentModel mainMenu) (tea.Model, tea.Cmd) { + currentModel.root.GetCurrentInstallation().Vanilla = !currentModel.root.GetCurrentInstallation().Vanilla + return currentModel, nil + }, + }, utils.SimpleItem[mainMenu]{ ItemTitle: "Profiles", Activate: func(msg tea.Msg, currentModel mainMenu) (tea.Model, tea.Cmd) {