@@ -45,76 +45,79 @@ func GetFile(project devboxProject) (*File, error) {
45
45
return lockFile , nil
46
46
}
47
47
48
- func (l * File ) Add (pkgs ... string ) error {
48
+ func (f * File ) Add (pkgs ... string ) error {
49
49
for _ , p := range pkgs {
50
- if _ , err := l .Resolve (p ); err != nil {
50
+ if _ , err := f .Resolve (p ); err != nil {
51
51
return err
52
52
}
53
53
}
54
- return l .Save ()
54
+ return f .Save ()
55
55
}
56
56
57
- func (l * File ) Remove (pkgs ... string ) error {
57
+ func (f * File ) Remove (pkgs ... string ) error {
58
58
for _ , p := range pkgs {
59
- delete (l .Packages , p )
59
+ delete (f .Packages , p )
60
60
}
61
- return l .Save ()
61
+ return f .Save ()
62
62
}
63
63
64
64
// Resolve updates the in memory copy for performance but does not write to disk
65
65
// This avoids writing values that may need to be removed in case of error.
66
- func (l * File ) Resolve (pkg string ) (* Package , error ) {
67
- entry , hasEntry := l .Packages [pkg ]
66
+ func (f * File ) Resolve (pkg string ) (* Package , error ) {
67
+ entry , hasEntry := f .Packages [pkg ]
68
68
69
69
if ! hasEntry || entry .Resolved == "" {
70
70
locked := & Package {}
71
71
var err error
72
72
if _ , _ , versioned := searcher .ParseVersionedPackage (pkg ); versioned {
73
- locked , err = l .FetchResolvedPackage (pkg )
73
+ locked , err = f .FetchResolvedPackage (pkg )
74
74
if err != nil {
75
75
return nil , err
76
76
}
77
77
} else if IsLegacyPackage (pkg ) {
78
78
// These are legacy packages without a version. Resolve to nixpkgs with
79
79
// whatever hash is in the devbox.json
80
80
locked = & Package {
81
- Resolved : l .LegacyNixpkgsPath (pkg ),
81
+ Resolved : f .LegacyNixpkgsPath (pkg ),
82
82
Source : nixpkgSource ,
83
83
}
84
84
}
85
- l .Packages [pkg ] = locked
85
+ f .Packages [pkg ] = locked
86
86
}
87
87
88
- return l .Packages [pkg ], nil
88
+ return f .Packages [pkg ], nil
89
89
}
90
90
91
- func (l * File ) ForceResolve (pkg string ) (* Package , error ) {
92
- delete (l .Packages , pkg )
93
- return l .Resolve (pkg )
91
+ func (f * File ) ForceResolve (pkg string ) (* Package , error ) {
92
+ delete (f .Packages , pkg )
93
+ return f .Resolve (pkg )
94
94
}
95
95
96
- func (l * File ) Save () error {
97
- return cuecfg .WriteFile (lockFilePath (l .devboxProject ), l )
96
+ func (f * File ) Save () error {
97
+ if err := cuecfg .WriteFile (lockFilePath (f .devboxProject ), f ); err != nil {
98
+ return err
99
+ }
100
+ return updateLocal (f .devboxProject )
98
101
}
99
102
100
- func (l * File ) LegacyNixpkgsPath (pkg string ) string {
103
+ func (f * File ) LegacyNixpkgsPath (pkg string ) string {
101
104
return fmt .Sprintf (
102
105
"github:NixOS/nixpkgs/%s#%s" ,
103
- l .NixPkgsCommitHash (),
106
+ f .NixPkgsCommitHash (),
104
107
pkg ,
105
108
)
106
109
}
107
110
108
- func (l * File ) Get (pkg string ) * Package {
109
- entry , hasEntry := l .Packages [pkg ]
111
+ func (f * File ) Get (pkg string ) * Package {
112
+ entry , hasEntry := f .Packages [pkg ]
110
113
if ! hasEntry || entry .Resolved == "" {
111
114
return nil
112
115
}
113
116
return entry
114
117
}
115
118
116
- func (l * File ) HasAllowInsecurePackages () bool {
117
- for _ , pkg := range l .Packages {
119
+ func (f * File ) HasAllowInsecurePackages () bool {
120
+ for _ , pkg := range f .Packages {
118
121
if pkg .AllowInsecure {
119
122
return true
120
123
}
@@ -137,8 +140,36 @@ func IsLegacyPackage(pkg string) bool {
137
140
138
141
// Tidy ensures that the lockfile has the set of packages corresponding to the devbox.json config.
139
142
// It gets rid of older packages that are no longer needed.
140
- func (l * File ) Tidy () {
141
- l .Packages = lo .PickByKeys (l .Packages , l .devboxProject .Packages ())
143
+ func (f * File ) Tidy () {
144
+ f .Packages = lo .PickByKeys (f .Packages , f .devboxProject .Packages ())
145
+ }
146
+
147
+ // IsUpToDateAndInstalled returns true if the lockfile is up to date and the
148
+ // local hashes match, which generally indicates all packages are correctly
149
+ // installed and print-dev-env has been computed and cached.
150
+ func (f * File ) IsUpToDateAndInstalled () (bool , error ) {
151
+ if dirty , err := f .isDirty (); err != nil {
152
+ return false , err
153
+ } else if dirty {
154
+ return false , nil
155
+ }
156
+ return isLocalUpToDate (f .devboxProject )
157
+ }
158
+
159
+ func (f * File ) isDirty () (bool , error ) {
160
+ currentHash , err := cuecfg .Hash (f )
161
+ if err != nil {
162
+ return false , err
163
+ }
164
+ fileSystemLockFile , err := GetFile (f .devboxProject )
165
+ if err != nil {
166
+ return false , err
167
+ }
168
+ filesystemHash , err := cuecfg .Hash (fileSystemLockFile )
169
+ if err != nil {
170
+ return false , err
171
+ }
172
+ return currentHash != filesystemHash , nil
142
173
}
143
174
144
175
func lockFilePath (project devboxProject ) string {
0 commit comments