TODO: Consider a design change to have the File struct match disk to make this system easier to reason about, and have isDirty() compare the in-memory struct to the on-disk struct. Proposal: 1. Have an OutputsRaw field and a method called Outputs() to access it. Outputs() will check if OutputsRaw i
()
| 116 | // 2. Then, in Save(), we can check if OutputsRaw is zero and fill it in prior to writing |
| 117 | // to disk. |
| 118 | func (f *File) Save() error { |
| 119 | isDirty, err := f.isDirty() |
| 120 | if err != nil { |
| 121 | return err |
| 122 | } |
| 123 | if !isDirty { |
| 124 | return nil |
| 125 | } |
| 126 | |
| 127 | // In SystemInfo, preserve legacy StorePath field and clear out modern Outputs before writing |
| 128 | // Reason: We want to update `devbox.lock` file only upon a user action |
| 129 | // such as `devbox update` or `devbox add` or `devbox remove`. |
| 130 | for pkgName, pkg := range f.Packages { |
| 131 | for sys, sysInfo := range pkg.Systems { |
| 132 | if sysInfo.outputIsFromStorePath { |
| 133 | f.Packages[pkgName].Systems[sys].Outputs = nil |
| 134 | } |
| 135 | } |
| 136 | } |
| 137 | // We set back the Outputs, if needed, after writing the file, so that future |
| 138 | // users of the `lock.File` struct will have the correct data. |
| 139 | defer ensurePackagesHaveOutputs(f.Packages) |
| 140 | |
| 141 | return cuecfg.WriteFile(lockFilePath(f.devboxProject.ProjectDir()), f) |
| 142 | } |
| 143 | |
| 144 | func (f *File) UpdateStdenv() error { |
| 145 | if err := nix.ClearFlakeCache(f.devboxProject.Stdenv()); err != nil { |
no test coverage detected