Skip to content

Commit 4fa150a

Browse files
rucoderclaude
andcommitted
pkg: add update-hashes subcommand; pkg build reads build-yml from hash file
update-hashes: - New cobra subcommand 'linuxkit pkg update-hashes --hash-dir <dir> [path[:build-yml]]...' - Parses all package specs (with explicit build-yml for versioned packages) - Builds dep graph from @lkt:pkg:/pkgs: build args filtered by Dockerfile ARGs - Topological sort (Kahn's algorithm) ensures deps processed before consumers - Calls NewFromConfig per package in topo order; writes HashManifest with tag, build-yml, and deps: [{path, tag}] populated - --strict-deps flag errors when a dep package is missing from the list pkg build: - When --hash-dir is set and --build-yml was not explicitly provided, reads effective build-yml from the package's hash file automatically; simplifies EVE Makefile (no per-package --build-yml needed in eve-% rule) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: Mikhail Malyshev <mike.malyshev@gmail.com>
1 parent af1bdbd commit 4fa150a

4 files changed

Lines changed: 381 additions & 3 deletions

File tree

src/cmd/linuxkit/pkg.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ func pkgCmd() *cobra.Command {
9999
cmd.AddCommand(pkgShowTagCmd())
100100
cmd.AddCommand(pkgManifestCmd())
101101
cmd.AddCommand(pkgRemoteTagCmd())
102+
cmd.AddCommand(pkgUpdateHashesCmd())
102103

103104
// These override fields in pkgInfo default below, bools are in both forms to allow user overrides in either direction.
104105
// These will apply to all packages built.

src/cmd/linuxkit/pkg_build.go

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ import (
55
"errors"
66
"fmt"
77
"os"
8+
"path/filepath"
89
"strings"
10+
"time"
911

1012
"github.com/linuxkit/linuxkit/src/cmd/linuxkit/pkglib"
1113
"github.com/linuxkit/linuxkit/src/cmd/linuxkit/spec"
@@ -70,9 +72,35 @@ func pkgBuildCmd() *cobra.Command {
7072
Example: ` linuxkit pkg build [options] pkg/dir/`,
7173
Args: cobra.MinimumNArgs(1),
7274
RunE: func(cmd *cobra.Command, args []string) error {
73-
pkgs, err := pkglib.NewFromConfig(pkglibConfig, args...)
74-
if err != nil {
75-
return err
75+
// When --hash-dir is set and --build-yml was not explicitly provided,
76+
// read the effective build-yml from each package's hash file. This
77+
// allows `pkg build --hash-dir .gen-deps pkg/zfs` to work without
78+
// needing `--build-yml build-2.3.yml` on the command line.
79+
var (
80+
pkgs []pkglib.Pkg
81+
err error
82+
)
83+
// When --hash-dir is set and --build-yml was not explicitly provided,
84+
// read the effective build-yml from each package's hash file. This
85+
// allows `pkg build --hash-dir .gen-deps pkg/zfs` to work without
86+
// needing `--build-yml build-2.3.yml` on the command line.
87+
if pkglibConfig.HashDir != "" && !cmd.Parent().PersistentFlags().Changed("build-yml") {
88+
for _, arg := range args {
89+
cfg := pkglibConfig
90+
if m, _ := pkglib.ReadHashManifest(cfg.HashDir, arg); m != nil && m.BuildYML != "" {
91+
cfg.BuildYML = m.BuildYML
92+
}
93+
p, err2 := pkglib.NewFromConfig(cfg, arg)
94+
if err2 != nil {
95+
return err2
96+
}
97+
pkgs = append(pkgs, p...)
98+
}
99+
} else {
100+
pkgs, err = pkglib.NewFromConfig(pkglibConfig, args...)
101+
if err != nil {
102+
return err
103+
}
76104
}
77105

78106
if nobuild && force {
@@ -300,6 +328,13 @@ func pkgBuildCmd() *cobra.Command {
300328
if err := p.Build(pkgOpts...); err != nil {
301329
return fmt.Errorf("error %s %q: %w", action, p.Tag(), err)
302330
}
331+
// After a successful build, touch the hash file to set a
332+
// real mtime. update-hashes wrote it with epoch-0 to signal
333+
// "needs building"; now that the build succeeded we stamp it
334+
// so make considers this package up-to-date.
335+
if pkglibConfig.HashDir != "" {
336+
touchHashFile(pkglibConfig.HashDir, p)
337+
}
303338
}
304339
return nil
305340
},
@@ -349,3 +384,17 @@ func buildPlatformBuildersMap(inputs string, existing map[string]string) (map[st
349384
}
350385
return existing, nil
351386
}
387+
388+
389+
// touchHashFile updates the mtime of the package's hash file to "now" after a
390+
// successful build. update-hashes wrote the file with epoch-0 mtime to signal
391+
// "needs building"; this function stamps it with the current time so make
392+
// considers this package up-to-date on the next run.
393+
func touchHashFile(hashDir string, p pkglib.Pkg) {
394+
name := filepath.Base(p.Path())
395+
hashFile := filepath.Join(hashDir, name+".hash")
396+
now := time.Now()
397+
// Ignore errors: the hash file may not exist (e.g. no update-hashes run),
398+
// and a missing touch is not fatal.
399+
_ = os.Chtimes(hashFile, now, now)
400+
}

0 commit comments

Comments
 (0)