feat: vanilla toggle per install (#13)
* feat: vanilla toggle per install * fix: update set-vanilla cmd description * fix: use viper for the set-vanilla off flag * fix: writing lockfile when the directory didn't exist * fix: check for nil selected install in header vanilla message --------- Co-authored-by: Vilsol <me@vil.so>
This commit is contained in:
parent
4e1993fe25
commit
ea983cf851
5 changed files with 116 additions and 20 deletions
|
@ -37,6 +37,7 @@ type Installation struct {
|
||||||
DiskInstance disk.Disk `json:"-"`
|
DiskInstance disk.Disk `json:"-"`
|
||||||
Path string `json:"path"`
|
Path string `json:"path"`
|
||||||
Profile string `json:"profile"`
|
Profile string `json:"profile"`
|
||||||
|
Vanilla bool `json:"vanilla"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func InitInstallations() (*Installations, error) {
|
func InitInstallations() (*Installations, error) {
|
||||||
|
@ -127,6 +128,7 @@ func (i *Installations) AddInstallation(ctx *GlobalContext, installPath string,
|
||||||
installation := &Installation{
|
installation := &Installation{
|
||||||
Path: absolutePath,
|
Path: absolutePath,
|
||||||
Profile: profile,
|
Profile: profile,
|
||||||
|
Vanilla: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := installation.Validate(ctx); err != nil {
|
if err := installation.Validate(ctx); err != nil {
|
||||||
|
@ -285,16 +287,23 @@ func (i *Installation) WriteLockFile(ctx *GlobalContext, lockfile LockFile) erro
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
marshaledLockfile, err := json.MarshalIndent(lockfile, "", " ")
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrap(err, "failed to serialize lockfile json")
|
|
||||||
}
|
|
||||||
|
|
||||||
d, err := i.GetDisk()
|
d, err := i.GetDisk()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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 {
|
if err := d.Write(lockfilePath, marshaledLockfile); err != nil {
|
||||||
return errors.Wrap(err, "failed writing lockfile")
|
return errors.Wrap(err, "failed writing lockfile")
|
||||||
}
|
}
|
||||||
|
@ -302,6 +311,31 @@ func (i *Installation) WriteLockFile(ctx *GlobalContext, lockfile LockFile) erro
|
||||||
return nil
|
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 {
|
type InstallUpdate struct {
|
||||||
ModName string
|
ModName string
|
||||||
OverallProgress float64
|
OverallProgress float64
|
||||||
|
@ -314,21 +348,14 @@ func (i *Installation) Install(ctx *GlobalContext, updates chan InstallUpdate) e
|
||||||
return errors.Wrap(err, "failed to validate installation")
|
return errors.Wrap(err, "failed to validate installation")
|
||||||
}
|
}
|
||||||
|
|
||||||
lockFile, err := i.LockFile(ctx)
|
lockfile := make(LockFile)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
resolver := NewDependencyResolver(ctx.APIClient)
|
if !i.Vanilla {
|
||||||
|
var err error
|
||||||
gameVersion, err := i.GetGameVersion(ctx)
|
lockfile, err = i.ResolveProfile(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to detect game version")
|
return errors.Wrap(err, "failed to resolve lockfile")
|
||||||
}
|
}
|
||||||
|
|
||||||
lockfile, err := ctx.Profiles.Profiles[i.Profile].Resolve(resolver, lockFile, gameVersion)
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrap(err, "could not resolve mods")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
d, err := i.GetDisk()
|
d, err := i.GetDisk()
|
||||||
|
@ -435,7 +462,7 @@ func (i *Installation) Install(ctx *GlobalContext, updates chan InstallUpdate) e
|
||||||
completed++
|
completed++
|
||||||
}
|
}
|
||||||
|
|
||||||
return i.WriteLockFile(ctx, lockfile)
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Installation) SetProfile(ctx *GlobalContext, profile string) error {
|
func (i *Installation) SetProfile(ctx *GlobalContext, profile string) error {
|
||||||
|
|
|
@ -37,5 +37,9 @@ func TestAddInstallation(t *testing.T) {
|
||||||
|
|
||||||
err = installation.Install(ctx, nil)
|
err = installation.Install(ctx, nil)
|
||||||
testza.AssertNoError(t, err)
|
testza.AssertNoError(t, err)
|
||||||
|
|
||||||
|
installation.Vanilla = true
|
||||||
|
err = installation.Install(ctx, nil)
|
||||||
|
testza.AssertNoError(t, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
46
cmd/installation/set-vanilla.go
Normal file
46
cmd/installation/set-vanilla.go
Normal file
|
@ -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 <path>",
|
||||||
|
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()
|
||||||
|
},
|
||||||
|
}
|
|
@ -44,6 +44,18 @@ func (h headerComponent) View() string {
|
||||||
} else {
|
} else {
|
||||||
out += "None"
|
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)
|
return lipgloss.NewStyle().Margin(1, 0).Render(out)
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,6 +73,13 @@ func NewMainMenu(root components.RootModel) tea.Model {
|
||||||
return newModel, newModel.Init()
|
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]{
|
utils.SimpleItem[mainMenu]{
|
||||||
ItemTitle: "Profiles",
|
ItemTitle: "Profiles",
|
||||||
Activate: func(msg tea.Msg, currentModel mainMenu) (tea.Model, tea.Cmd) {
|
Activate: func(msg tea.Msg, currentModel mainMenu) (tea.Model, tea.Cmd) {
|
||||||
|
|
Loading…
Reference in a new issue