| 174 | } |
| 175 | |
| 176 | func (p Port) Installed() (bool, error) { |
| 177 | // Packages like autoconf, m4, automake, libtool cannot be build in windows. |
| 178 | if !p.IsHostSupported() { |
| 179 | return true, nil |
| 180 | } |
| 181 | |
| 182 | // No trace file means not installed. |
| 183 | if !fileio.PathExists(p.traceFile) { |
| 184 | return false, nil |
| 185 | } |
| 186 | |
| 187 | // nobuild is already regard as installed. |
| 188 | if p.MatchedConfig.BuildSystem == "nobuild" { |
| 189 | return true, nil |
| 190 | } |
| 191 | |
| 192 | // Check if meta file exists. |
| 193 | if !fileio.PathExists(p.metaFile) { |
| 194 | return false, nil |
| 195 | } |
| 196 | |
| 197 | // Check if meta data matches. |
| 198 | metaBytes, err := os.ReadFile(p.metaFile) |
| 199 | if err != nil { |
| 200 | return false, err |
| 201 | } |
| 202 | newMeta, err := p.buildMeta() |
| 203 | if err != nil { |
| 204 | // Repo not exist is not error. |
| 205 | if errors.Is(err, errors.ErrRepoNotExit) { |
| 206 | return false, nil |
| 207 | } |
| 208 | return false, err |
| 209 | } |
| 210 | |
| 211 | // Remove installed package if build config changed. |
| 212 | localMeta := string(metaBytes) |
| 213 | if localMeta != newMeta { |
| 214 | options := RemoveOptions{ |
| 215 | Purge: true, |
| 216 | Recursive: false, |
| 217 | BuildCache: false, |
| 218 | } |
| 219 | if err := p.Remove(options); err != nil { |
| 220 | return false, fmt.Errorf("failed to remove installed package -> %w", err) |
| 221 | } |
| 222 | return false, nil |
| 223 | } |
| 224 | |
| 225 | // Verify that all dependencies are also installed. |
| 226 | // If a dependency was removed the parent's trace/meta still exist but the artifact is gone. |
| 227 | depsInstalled, err := p.checkDepsInstalled() |
| 228 | if err != nil { |
| 229 | return false, fmt.Errorf("failed to check depts installed for %s -> %w", p.NameVersion(), err) |
| 230 | } |
| 231 | |
| 232 | return depsInstalled, nil |
| 233 | } |