Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package syft for openSUSE:Factory checked in 
at 2023-02-01 16:39:05
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/syft (Old)
 and      /work/SRC/openSUSE:Factory/.syft.new.32243 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "syft"

Wed Feb  1 16:39:05 2023 rev:24 rq:1062288 version:0.69.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/syft/syft.changes        2023-01-26 
14:10:58.968433840 +0100
+++ /work/SRC/openSUSE:Factory/.syft.new.32243/syft.changes     2023-02-01 
16:39:08.773633704 +0100
@@ -1,0 +2,8 @@
+Tue Jan 31 15:04:23 UTC 2023 - ka...@b1-systems.de
+
+- Update to version 0.69.0:
+  * Allow scanning unpacked container filesystems (#1485)
+  * fix: allow template for syft convert (#1521)
+  * 1465 attestation with private key (#1502)
+
+-------------------------------------------------------------------

Old:
----
  syft-0.68.1.tar.gz

New:
----
  syft-0.69.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ syft.spec ++++++
--- /var/tmp/diff_new_pack.JZ1pKS/_old  2023-02-01 16:39:10.485644870 +0100
+++ /var/tmp/diff_new_pack.JZ1pKS/_new  2023-02-01 16:39:10.489644896 +0100
@@ -19,7 +19,7 @@
 %define __arch_install_post export NO_BRP_STRIP_DEBUG=true
 
 Name:           syft
-Version:        0.68.1
+Version:        0.69.0
 Release:        0
 Summary:        CLI tool and library for generating a Software Bill of 
Materials
 License:        Apache-2.0

++++++ _service ++++++
--- /var/tmp/diff_new_pack.JZ1pKS/_old  2023-02-01 16:39:10.553645313 +0100
+++ /var/tmp/diff_new_pack.JZ1pKS/_new  2023-02-01 16:39:10.557645339 +0100
@@ -3,7 +3,7 @@
     <param name="url">https://github.com/anchore/syft</param>
     <param name="scm">git</param>
     <param name="exclude">.git</param>
-    <param name="revision">v0.68.1</param>
+    <param name="revision">v0.69.0</param>
     <param name="versionformat">@PARENT_TAG@</param>
     <param name="changesgenerate">enable</param>
     <param name="versionrewrite-pattern">v(.*)</param>
@@ -16,7 +16,7 @@
     <param name="compression">gz</param>
   </service>
   <service name="go_modules" mode="disabled">
-    <param name="archive">syft-0.68.1.tar.gz</param>
+    <param name="archive">syft-0.69.0.tar.gz</param>
   </service>
 </services>
 

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.JZ1pKS/_old  2023-02-01 16:39:10.577645469 +0100
+++ /var/tmp/diff_new_pack.JZ1pKS/_new  2023-02-01 16:39:10.585645522 +0100
@@ -1,6 +1,6 @@
 <servicedata>
 <service name="tar_scm">
                 <param name="url">https://github.com/anchore/syft</param>
-              <param 
name="changesrevision">4c0aef09b8d7fb78200b04416f474b90b79370de</param></service></servicedata>
+              <param 
name="changesrevision">b81c9805dcc9bf25dad7659fd9c2bbf7dd3f3d90</param></service></servicedata>
 (No newline at EOF)
 

++++++ syft-0.68.1.tar.gz -> syft-0.69.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/syft-0.68.1/cmd/syft/cli/attest/attest.go 
new/syft-0.69.0/cmd/syft/cli/attest/attest.go
--- old/syft-0.68.1/cmd/syft/cli/attest/attest.go       2023-01-25 
18:18:24.000000000 +0100
+++ new/syft-0.69.0/cmd/syft/cli/attest/attest.go       2023-01-30 
19:47:24.000000000 +0100
@@ -97,6 +97,7 @@
        return sBytes, nil
 }
 
+//nolint:funlen
 func execWorker(app *config.Application, si source.Input, writer sbom.Writer) 
<-chan error {
        errs := make(chan error)
        go func() {
@@ -131,9 +132,18 @@
                        }
 
                        args := []string{"attest", si.UserInput, "--type", 
"custom", "--predicate", f.Name()}
+                       if app.Attest.Key != "" {
+                               args = append(args, "--key", app.Attest.Key)
+                       }
+
                        execCmd := exec.Command(cmd, args...)
                        execCmd.Env = os.Environ()
-                       execCmd.Env = append(execCmd.Env, 
"COSIGN_EXPERIMENTAL=1")
+                       if app.Attest.Key != "" {
+                               execCmd.Env = append(execCmd.Env, 
fmt.Sprintf("COSIGN_PASSWORD=%s", app.Attest.Password))
+                       } else {
+                               // no key provided, use cosign's keyless mode
+                               execCmd.Env = append(execCmd.Env, 
"COSIGN_EXPERIMENTAL=1")
+                       }
 
                        // bus adapter for ui to hook into stdout via an os pipe
                        r, w, err := os.Pipe()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/syft-0.68.1/cmd/syft/cli/attest.go 
new/syft-0.69.0/cmd/syft/cli/attest.go
--- old/syft-0.68.1/cmd/syft/cli/attest.go      2023-01-25 18:18:24.000000000 
+0100
+++ new/syft-0.69.0/cmd/syft/cli/attest.go      2023-01-30 19:47:24.000000000 
+0100
@@ -20,8 +20,7 @@
        attestHelp       = attestExample + attestSchemeHelp
 )
 
-//nolint:dupl
-func Attest(v *viper.Viper, app *config.Application, ro *options.RootOptions, 
po *options.PackagesOptions) *cobra.Command {
+func Attest(v *viper.Viper, app *config.Application, ro *options.RootOptions, 
po *options.PackagesOptions, ao *options.AttestOptions) *cobra.Command {
        cmd := &cobra.Command{
                Use:   "attest --output [FORMAT] <IMAGE>",
                Short: "Generate an SBOM as an attestation for the given 
[SOURCE] container image",
@@ -50,11 +49,17 @@
                },
        }
 
-       // syft attest is an enhancment of the packages command, so it should 
have the same flags
+       // syft attest is an enhancement of the packages command, so it should 
have the same flags
        err := po.AddFlags(cmd, v)
        if err != nil {
                log.Fatal(err)
        }
+
+       // syft attest has its own options not included as part of the packages 
command
+       err = ao.AddFlags(cmd, v)
+       if err != nil {
+               log.Fatal(err)
+       }
 
        return cmd
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/syft-0.68.1/cmd/syft/cli/commands.go 
new/syft-0.69.0/cmd/syft/cli/commands.go
--- old/syft-0.68.1/cmd/syft/cli/commands.go    2023-01-25 18:18:24.000000000 
+0100
+++ new/syft-0.69.0/cmd/syft/cli/commands.go    2023-01-30 19:47:24.000000000 
+0100
@@ -45,12 +45,13 @@
        // we also need the command to have information about the `root` 
options because of this alias
        ro := &options.RootOptions{}
        po := &options.PackagesOptions{}
+       ao := &options.AttestOptions{}
        packagesCmd := Packages(v, app, ro, po)
 
        // root options are also passed to the attestCmd so that a user 
provided config location can be discovered
        poweruserCmd := PowerUser(v, app, ro)
        convertCmd := Convert(v, app, ro, po)
-       attestCmd := Attest(v, app, ro, po)
+       attestCmd := Attest(v, app, ro, po, ao)
 
        // rootCmd is currently an alias for the packages command
        rootCmd := &cobra.Command{
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/syft-0.68.1/cmd/syft/cli/convert/convert.go 
new/syft-0.69.0/cmd/syft/cli/convert/convert.go
--- old/syft-0.68.1/cmd/syft/cli/convert/convert.go     2023-01-25 
18:18:24.000000000 +0100
+++ new/syft-0.69.0/cmd/syft/cli/convert/convert.go     2023-01-30 
19:47:24.000000000 +0100
@@ -11,9 +11,9 @@
        "github.com/anchore/syft/syft"
 )
 
-func Run(ctx context.Context, app *config.Application, args []string) error {
+func Run(_ context.Context, app *config.Application, args []string) error {
        log.Warn("convert is an experimental feature, run `syft convert -h` for 
help")
-       writer, err := options.MakeWriter(app.Outputs, app.File, "")
+       writer, err := options.MakeWriter(app.Outputs, app.File, 
app.OutputTemplatePath)
        if err != nil {
                return err
        }
@@ -30,7 +30,9 @@
        if err != nil {
                return fmt.Errorf("failed to open SBOM file: %w", err)
        }
-       defer f.Close()
+       defer func() {
+               _ = f.Close()
+       }()
 
        sbom, _, err := syft.Decode(f)
        if err != nil {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/syft-0.68.1/cmd/syft/cli/options/attest.go 
new/syft-0.69.0/cmd/syft/cli/options/attest.go
--- old/syft-0.68.1/cmd/syft/cli/options/attest.go      1970-01-01 
01:00:00.000000000 +0100
+++ new/syft-0.69.0/cmd/syft/cli/options/attest.go      2023-01-30 
19:47:24.000000000 +0100
@@ -0,0 +1,25 @@
+package options
+
+import (
+       "github.com/spf13/cobra"
+       "github.com/spf13/pflag"
+       "github.com/spf13/viper"
+)
+
+type AttestOptions struct {
+       Key string
+}
+
+var _ Interface = (*AttestOptions)(nil)
+
+func (o AttestOptions) AddFlags(cmd *cobra.Command, v *viper.Viper) error {
+       cmd.Flags().StringVarP(&o.Key, "key", "k", "", "the key to use for the 
attestation")
+       return bindAttestConfigOptions(cmd.Flags(), v)
+}
+
+func bindAttestConfigOptions(flags *pflag.FlagSet, v *viper.Viper) error {
+       if err := v.BindPFlag("attest.key", flags.Lookup("key")); err != nil {
+               return err
+       }
+       return nil
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/syft-0.68.1/internal/config/application.go 
new/syft-0.69.0/internal/config/application.go
--- old/syft-0.68.1/internal/config/application.go      2023-01-25 
18:18:24.000000000 +0100
+++ new/syft-0.69.0/internal/config/application.go      2023-01-30 
19:47:24.000000000 +0100
@@ -47,6 +47,7 @@
        Log                logging            `yaml:"log" json:"log" 
mapstructure:"log"` // all logging-related options
        Catalogers         []string           `yaml:"catalogers" 
json:"catalogers" mapstructure:"catalogers"`
        Package            pkg                `yaml:"package" json:"package" 
mapstructure:"package"`
+       Attest             attest             `yaml:"attest" json:"attest" 
mapstructure:"attest"`
        FileMetadata       FileMetadata       `yaml:"file-metadata" 
json:"file-metadata" mapstructure:"file-metadata"`
        FileClassification fileClassification `yaml:"file-classification" 
json:"file-classification" mapstructure:"file-classification"`
        FileContents       fileContents       `yaml:"file-contents" 
json:"file-contents" mapstructure:"file-contents"`
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/syft-0.68.1/internal/config/attest.go 
new/syft-0.69.0/internal/config/attest.go
--- old/syft-0.68.1/internal/config/attest.go   1970-01-01 01:00:00.000000000 
+0100
+++ new/syft-0.69.0/internal/config/attest.go   2023-01-30 19:47:24.000000000 
+0100
@@ -0,0 +1,13 @@
+package config
+
+import "github.com/spf13/viper"
+
+type attest struct {
+       Key      string `yaml:"key" json:"key" mapstructure:"key"`
+       Password string `yaml:"password" json:"password" 
mapstructure:"password"`
+}
+
+func (cfg attest) loadDefaultValues(v *viper.Viper) {
+       v.SetDefault("attest.key", "")
+       v.SetDefault("attest.password", "")
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/syft-0.68.1/syft/source/directory_resolver.go 
new/syft-0.69.0/syft/source/directory_resolver.go
--- old/syft-0.68.1/syft/source/directory_resolver.go   2023-01-25 
18:18:24.000000000 +0100
+++ new/syft-0.69.0/syft/source/directory_resolver.go   2023-01-30 
19:47:24.000000000 +0100
@@ -37,6 +37,7 @@
 // directoryResolver implements path and content access for the directory data 
source.
 type directoryResolver struct {
        path                    string
+       base                    string
        currentWdRelativeToRoot string
        currentWd               string
        fileTree                *filetree.FileTree
@@ -47,7 +48,7 @@
        errPaths       map[string]error
 }
 
-func newDirectoryResolver(root string, pathFilters ...pathFilterFn) 
(*directoryResolver, error) {
+func newDirectoryResolver(root string, base string, pathFilters 
...pathFilterFn) (*directoryResolver, error) {
        currentWD, err := os.Getwd()
        if err != nil {
                return nil, fmt.Errorf("could not get CWD: %w", err)
@@ -64,6 +65,18 @@
                return nil, fmt.Errorf("could not evaluate root=%q symlinks: 
%w", root, err)
        }
 
+       cleanBase := ""
+       if base != "" {
+               cleanBase, err = filepath.EvalSymlinks(base)
+               if err != nil {
+                       return nil, fmt.Errorf("could not evaluate base=%q 
symlinks: %w", base, err)
+               }
+               cleanBase, err = filepath.Abs(cleanBase)
+               if err != nil {
+                       return nil, err
+               }
+       }
+
        var currentWdRelRoot string
        if path.IsAbs(cleanRoot) {
                currentWdRelRoot, err = filepath.Rel(cleanCWD, cleanRoot)
@@ -76,6 +89,7 @@
 
        resolver := directoryResolver{
                path:                    cleanRoot,
+               base:                    cleanBase,
                currentWd:               cleanCWD,
                currentWdRelativeToRoot: currentWdRelRoot,
                fileTree:                filetree.NewFileTree(),
@@ -244,10 +258,25 @@
                return "", fmt.Errorf("unable to readlink for path=%q: %w", p, 
err)
        }
 
-       // note: if the link is not absolute (e.g, /dev/stderr -> fd/2 ) we 
need to resolve it relative to the directory
-       // in question (e.g. resolve to /dev/fd/2)
-       if !filepath.IsAbs(linkTarget) {
-               linkTarget = filepath.Join(filepath.Dir(p), linkTarget)
+       if filepath.IsAbs(linkTarget) {
+               // if the link is absolute (e.g, /bin/ls -> /bin/busybox) we 
need to
+               // resolve relative to the root of the base directory
+               linkTarget = filepath.Join(r.base, filepath.Clean(linkTarget))
+       } else {
+               // if the link is not absolute (e.g, /dev/stderr -> fd/2 ) we 
need to
+               // resolve it relative to the directory in question (e.g. 
resolve to
+               // /dev/fd/2)
+               if r.base == "" {
+                       linkTarget = filepath.Join(filepath.Dir(p), linkTarget)
+               } else {
+                       // if the base is set, then we first need to resolve 
the link,
+                       // before finding it's location in the base
+                       dir, err := filepath.Rel(r.base, filepath.Dir(p))
+                       if err != nil {
+                               return "", fmt.Errorf("unable to resolve 
relative path for path=%q: %w", p, err)
+                       }
+                       linkTarget = filepath.Join(r.base, 
filepath.Clean(filepath.Join("/", dir, linkTarget)))
+               }
        }
 
        ref, err := r.fileTree.AddSymLink(file.Path(p), file.Path(linkTarget))
@@ -336,14 +365,17 @@
                }
 
                // we should be resolving symlinks and preserving this 
information as a VirtualPath to the real file
-               evaluatedPath, err := filepath.EvalSymlinks(userStrPath)
+               exists, ref, err := r.fileTree.File(file.Path(userStrPath), 
filetree.FollowBasenameLinks)
                if err != nil {
                        log.Tracef("unable to evaluate symlink for path=%q : 
%+v", userPath, err)
                        continue
                }
+               if !exists {
+                       continue
+               }
 
                // TODO: why not use stored metadata?
-               fileMeta, err := os.Stat(evaluatedPath)
+               fileMeta, err := os.Stat(string(ref.RealPath))
                if errors.Is(err, os.ErrNotExist) {
                        // note: there are other kinds of errors other than 
os.ErrNotExist that may be given that is platform
                        // specific, but essentially hints at the same overall 
problem (that the path does not exist). Such an
@@ -354,7 +386,7 @@
                        // invalid paths. This logging statement is meant to 
raise IO or permissions related problems.
                        var pathErr *os.PathError
                        if !errors.As(err, &pathErr) {
-                               log.Warnf("path is not valid (%s): %+v", 
evaluatedPath, err)
+                               log.Warnf("path is not valid (%s): %+v", 
ref.RealPath, err)
                        }
                        continue
                }
@@ -368,15 +400,12 @@
                        userStrPath = windowsToPosix(userStrPath)
                }
 
-               exists, ref, err := r.fileTree.File(file.Path(userStrPath), 
filetree.FollowBasenameLinks)
-               if err == nil && exists {
-                       loc := NewVirtualLocationFromDirectory(
-                               r.responsePath(string(ref.RealPath)), // the 
actual path relative to the resolver root
-                               r.responsePath(userStrPath),          // the 
path used to access this file, relative to the resolver root
-                               *ref,
-                       )
-                       references = append(references, loc)
-               }
+               loc := NewVirtualLocationFromDirectory(
+                       r.responsePath(string(ref.RealPath)), // the actual 
path relative to the resolver root
+                       r.responsePath(userStrPath),          // the path used 
to access this file, relative to the resolver root
+                       *ref,
+               )
+               references = append(references, loc)
        }
 
        return references, nil
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/syft-0.68.1/syft/source/directory_resolver_test.go 
new/syft-0.69.0/syft/source/directory_resolver_test.go
--- old/syft-0.68.1/syft/source/directory_resolver_test.go      2023-01-25 
18:18:24.000000000 +0100
+++ new/syft-0.69.0/syft/source/directory_resolver_test.go      2023-01-30 
19:47:24.000000000 +0100
@@ -57,7 +57,7 @@
        }
        for _, c := range cases {
                t.Run(c.name, func(t *testing.T) {
-                       resolver, err := newDirectoryResolver(c.relativeRoot)
+                       resolver, err := newDirectoryResolver(c.relativeRoot, 
"")
                        assert.NoError(t, err)
 
                        refs, err := resolver.FilesByPath(c.input)
@@ -111,7 +111,7 @@
                        absRoot, err := filepath.Abs(c.relativeRoot)
                        require.NoError(t, err)
 
-                       resolver, err := newDirectoryResolver(absRoot)
+                       resolver, err := newDirectoryResolver(absRoot, "")
                        assert.NoError(t, err)
 
                        refs, err := resolver.FilesByPath(c.input)
@@ -172,7 +172,7 @@
        }
        for _, c := range cases {
                t.Run(c.name, func(t *testing.T) {
-                       resolver, err := newDirectoryResolver(c.root)
+                       resolver, err := newDirectoryResolver(c.root, "")
                        assert.NoError(t, err)
 
                        hasPath := resolver.HasPath(c.input)
@@ -220,7 +220,7 @@
        }
        for _, c := range cases {
                t.Run(c.name, func(t *testing.T) {
-                       resolver, err := newDirectoryResolver("./test-fixtures")
+                       resolver, err := 
newDirectoryResolver("./test-fixtures", "")
                        assert.NoError(t, err)
                        refs, err := resolver.FilesByPath(c.input...)
                        assert.NoError(t, err)
@@ -233,7 +233,7 @@
 }
 
 func TestDirectoryResolver_FilesByGlobMultiple(t *testing.T) {
-       resolver, err := newDirectoryResolver("./test-fixtures")
+       resolver, err := newDirectoryResolver("./test-fixtures", "")
        assert.NoError(t, err)
        refs, err := resolver.FilesByGlob("**/image-symlinks/file*")
        assert.NoError(t, err)
@@ -242,7 +242,7 @@
 }
 
 func TestDirectoryResolver_FilesByGlobRecursive(t *testing.T) {
-       resolver, err := newDirectoryResolver("./test-fixtures/image-symlinks")
+       resolver, err := newDirectoryResolver("./test-fixtures/image-symlinks", 
"")
        assert.NoError(t, err)
        refs, err := resolver.FilesByGlob("**/*.txt")
        assert.NoError(t, err)
@@ -250,7 +250,7 @@
 }
 
 func TestDirectoryResolver_FilesByGlobSingle(t *testing.T) {
-       resolver, err := newDirectoryResolver("./test-fixtures")
+       resolver, err := newDirectoryResolver("./test-fixtures", "")
        assert.NoError(t, err)
        refs, err := resolver.FilesByGlob("**/image-symlinks/*1.txt")
        assert.NoError(t, err)
@@ -277,7 +277,7 @@
 
        for _, test := range tests {
                t.Run(test.name, func(t *testing.T) {
-                       resolver, err := 
newDirectoryResolver("./test-fixtures/symlinks-simple")
+                       resolver, err := 
newDirectoryResolver("./test-fixtures/symlinks-simple", "")
                        assert.NoError(t, err)
 
                        refs, err := resolver.FilesByPath(test.fixture)
@@ -300,7 +300,7 @@
 
 func TestDirectoryResolverDoesNotIgnoreRelativeSystemPaths(t *testing.T) {
        // let's make certain that "dev/place" is not ignored, since it is not 
"/dev/place"
-       resolver, err := 
newDirectoryResolver("test-fixtures/system_paths/target")
+       resolver, err := 
newDirectoryResolver("test-fixtures/system_paths/target", "")
        assert.NoError(t, err)
        // ensure the correct filter function is wired up by default
        expectedFn := reflect.ValueOf(isUnallowableFileType)
@@ -431,7 +431,7 @@
 
 func Test_directoryResolver_index(t *testing.T) {
        // note: this test is testing the effects from newDirectoryResolver, 
indexTree, and addPathToIndex
-       r, err := newDirectoryResolver("test-fixtures/system_paths/target")
+       r, err := newDirectoryResolver("test-fixtures/system_paths/target", "")
        if err != nil {
                t.Fatalf("unable to get indexed dir resolver: %+v", err)
        }
@@ -608,7 +608,7 @@
        }
        for _, test := range tests {
                t.Run(test.fixturePath, func(t *testing.T) {
-                       resolver, err := newDirectoryResolver(test.fixturePath)
+                       resolver, err := newDirectoryResolver(test.fixturePath, 
"")
                        assert.NoError(t, err)
                        locations, err := 
resolver.FilesByMIMEType(test.mimeType)
                        assert.NoError(t, err)
@@ -621,7 +621,7 @@
 }
 
 func Test_IndexingNestedSymLinks(t *testing.T) {
-       resolver, err := newDirectoryResolver("./test-fixtures/symlinks-simple")
+       resolver, err := 
newDirectoryResolver("./test-fixtures/symlinks-simple", "")
        require.NoError(t, err)
 
        // check that we can get the real path
@@ -674,7 +674,7 @@
                return strings.HasSuffix(path, 
string(filepath.Separator)+"readme")
        }
 
-       resolver, err := 
newDirectoryResolver("./test-fixtures/symlinks-simple", filterFn)
+       resolver, err := 
newDirectoryResolver("./test-fixtures/symlinks-simple", "", filterFn)
        require.NoError(t, err)
 
        // the path to the real file is PRUNED from the index, so we should NOT 
expect a location returned
@@ -694,7 +694,7 @@
 }
 
 func Test_IndexingNestedSymLinksOutsideOfRoot(t *testing.T) {
-       resolver, err := 
newDirectoryResolver("./test-fixtures/symlinks-multiple-roots/root")
+       resolver, err := 
newDirectoryResolver("./test-fixtures/symlinks-multiple-roots/root", "")
        require.NoError(t, err)
 
        // check that we can get the real path
@@ -712,7 +712,7 @@
 }
 
 func Test_RootViaSymlink(t *testing.T) {
-       resolver, err := 
newDirectoryResolver("./test-fixtures/symlinked-root/nested/link-root")
+       resolver, err := 
newDirectoryResolver("./test-fixtures/symlinked-root/nested/link-root", "")
        require.NoError(t, err)
 
        locations, err := resolver.FilesByPath("./file1.txt")
@@ -753,7 +753,7 @@
        }
        for _, test := range tests {
                t.Run(test.name, func(t *testing.T) {
-                       r, err := newDirectoryResolver(".")
+                       r, err := newDirectoryResolver(".", "")
                        require.NoError(t, err)
 
                        actual, err := r.FileContentsByLocation(test.location)
@@ -819,7 +819,7 @@
 
 func Test_SymlinkLoopWithGlobsShouldResolve(t *testing.T) {
        test := func(t *testing.T) {
-               resolver, err := 
newDirectoryResolver("./test-fixtures/symlinks-loop")
+               resolver, err := 
newDirectoryResolver("./test-fixtures/symlinks-loop", "")
                require.NoError(t, err)
 
                locations, err := resolver.FilesByGlob("**/file.target")
@@ -853,7 +853,7 @@
                return path != "/"
        }
 
-       resolver, err := newDirectoryResolver("/", filterFn)
+       resolver, err := newDirectoryResolver("/", "", filterFn)
        require.NoError(t, err)
 
        exists, ref, err := resolver.fileTree.File(file.Path("/"))
@@ -870,7 +870,7 @@
        tempFile, err := os.CreateTemp("", "")
        require.NoError(t, err)
 
-       resolver, err := newDirectoryResolver(tempFile.Name())
+       resolver, err := newDirectoryResolver(tempFile.Name(), "")
        require.NoError(t, err)
 
        t.Run("filtering path with nil os.FileInfo", func(t *testing.T) {
@@ -885,3 +885,76 @@
                })
        })
 }
+
+func TestDirectoryResolver_FilesByPath_baseRoot(t *testing.T) {
+       cases := []struct {
+               name     string
+               root     string
+               input    string
+               expected []string
+       }{
+               {
+                       name:  "should find the base file",
+                       root:  "./test-fixtures/symlinks-base/",
+                       input: "./base",
+                       expected: []string{
+                               "base",
+                       },
+               },
+               {
+                       name:  "should follow a link with a pivoted root",
+                       root:  "./test-fixtures/symlinks-base/",
+                       input: "./foo",
+                       expected: []string{
+                               "base",
+                       },
+               },
+               {
+                       name:  "should follow a relative link with extra 
parents",
+                       root:  "./test-fixtures/symlinks-base/",
+                       input: "./bar",
+                       expected: []string{
+                               "base",
+                       },
+               },
+               {
+                       name:  "should follow an absolute link with extra 
parents",
+                       root:  "./test-fixtures/symlinks-base/",
+                       input: "./baz",
+                       expected: []string{
+                               "base",
+                       },
+               },
+               {
+                       name:  "should follow an absolute link with extra 
parents",
+                       root:  "./test-fixtures/symlinks-base/",
+                       input: "./sub/link",
+                       expected: []string{
+                               "sub/item",
+                       },
+               },
+               {
+                       name:  "should follow chained pivoted link",
+                       root:  "./test-fixtures/symlinks-base/",
+                       input: "./chain",
+                       expected: []string{
+                               "base",
+                       },
+               },
+       }
+       for _, c := range cases {
+               t.Run(c.name, func(t *testing.T) {
+                       resolver, err := newDirectoryResolver(c.root, c.root)
+                       assert.NoError(t, err)
+
+                       refs, err := resolver.FilesByPath(c.input)
+                       require.NoError(t, err)
+                       assert.Len(t, refs, len(c.expected))
+                       s := strset.New()
+                       for _, actual := range refs {
+                               s.Add(actual.RealPath)
+                       }
+                       assert.ElementsMatch(t, c.expected, s.List())
+               })
+       }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/syft-0.68.1/syft/source/metadata.go 
new/syft-0.69.0/syft/source/metadata.go
--- old/syft-0.68.1/syft/source/metadata.go     2023-01-25 18:18:24.000000000 
+0100
+++ new/syft-0.69.0/syft/source/metadata.go     2023-01-30 19:47:24.000000000 
+0100
@@ -6,5 +6,6 @@
        Scheme        Scheme        // the source data scheme type (directory 
or image)
        ImageMetadata ImageMetadata // all image info (image only)
        Path          string        // the root path to be cataloged (directory 
only)
+       Base          string        // the base path to be cataloged (directory 
only)
        Name          string
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/syft-0.68.1/syft/source/source.go 
new/syft-0.69.0/syft/source/source.go
--- old/syft-0.68.1/syft/source/source.go       2023-01-25 18:18:24.000000000 
+0100
+++ new/syft-0.69.0/syft/source/source.go       2023-01-30 19:47:24.000000000 
+0100
@@ -32,6 +32,7 @@
        Metadata          Metadata
        directoryResolver *directoryResolver `hash:"ignore"`
        path              string
+       base              string
        mutex             *sync.Mutex
        Exclusions        []string `hash:"ignore"`
 }
@@ -252,6 +253,11 @@
        return NewFromDirectoryWithName(path, "")
 }
 
+// NewFromDirectory creates a new source object tailored to catalog a given 
filesystem directory recursively.
+func NewFromDirectoryRoot(path string) (Source, error) {
+       return NewFromDirectoryRootWithName(path, "")
+}
+
 // NewFromDirectoryWithName creates a new source object tailored to catalog a 
given filesystem directory recursively, with an explicitly provided name.
 func NewFromDirectoryWithName(path string, name string) (Source, error) {
        s := Source{
@@ -267,6 +273,23 @@
        return s, nil
 }
 
+// NewFromDirectoryRootWithName creates a new source object tailored to 
catalog a given filesystem directory recursively, with an explicitly provided 
name.
+func NewFromDirectoryRootWithName(path string, name string) (Source, error) {
+       s := Source{
+               mutex: &sync.Mutex{},
+               Metadata: Metadata{
+                       Name:   name,
+                       Scheme: DirectoryScheme,
+                       Path:   path,
+                       Base:   path,
+               },
+               path: path,
+               base: path,
+       }
+       s.SetID()
+       return s, nil
+}
+
 // NewFromFile creates a new source object tailored to catalog a file.
 func NewFromFile(path string) (Source, func()) {
        return NewFromFileWithName(path, "")
@@ -428,7 +451,7 @@
                        if err != nil {
                                return nil, err
                        }
-                       resolver, err := newDirectoryResolver(s.path, 
exclusionFunctions...)
+                       resolver, err := newDirectoryResolver(s.path, s.base, 
exclusionFunctions...)
                        if err != nil {
                                return nil, fmt.Errorf("unable to create 
directory resolver: %w", err)
                        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/syft-0.68.1/syft/source/source_test.go 
new/syft-0.69.0/syft/source/source_test.go
--- old/syft-0.68.1/syft/source/source_test.go  2023-01-25 18:18:24.000000000 
+0100
+++ new/syft-0.69.0/syft/source/source_test.go  2023-01-30 19:47:24.000000000 
+0100
@@ -121,7 +121,7 @@
                                        Path:   "test-fixtures/image-simple",
                                },
                        },
-                       expected: artifact.ID("14b60020c4f9955"),
+                       expected: artifact.ID("1b0dc351e6577b01"),
                },
        }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/syft-0.68.1/syft/source/test-fixtures/symlinks-base/bar 
new/syft-0.69.0/syft/source/test-fixtures/symlinks-base/bar
--- old/syft-0.68.1/syft/source/test-fixtures/symlinks-base/bar 1970-01-01 
01:00:00.000000000 +0100
+++ new/syft-0.69.0/syft/source/test-fixtures/symlinks-base/bar 2023-02-01 
16:39:11.193649487 +0100
@@ -0,0 +1 @@
+symbolic link to ../../base
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/syft-0.68.1/syft/source/test-fixtures/symlinks-base/baz 
new/syft-0.69.0/syft/source/test-fixtures/symlinks-base/baz
--- old/syft-0.68.1/syft/source/test-fixtures/symlinks-base/baz 1970-01-01 
01:00:00.000000000 +0100
+++ new/syft-0.69.0/syft/source/test-fixtures/symlinks-base/baz 2023-02-01 
16:39:11.169649331 +0100
@@ -0,0 +1 @@
+symbolic link to /../../base
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/syft-0.68.1/syft/source/test-fixtures/symlinks-base/chain 
new/syft-0.69.0/syft/source/test-fixtures/symlinks-base/chain
--- old/syft-0.68.1/syft/source/test-fixtures/symlinks-base/chain       
1970-01-01 01:00:00.000000000 +0100
+++ new/syft-0.69.0/syft/source/test-fixtures/symlinks-base/chain       
2023-02-01 16:39:11.161649278 +0100
@@ -0,0 +1 @@
+symbolic link to /foo
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/syft-0.68.1/syft/source/test-fixtures/symlinks-base/foo 
new/syft-0.69.0/syft/source/test-fixtures/symlinks-base/foo
--- old/syft-0.68.1/syft/source/test-fixtures/symlinks-base/foo 1970-01-01 
01:00:00.000000000 +0100
+++ new/syft-0.69.0/syft/source/test-fixtures/symlinks-base/foo 2023-02-01 
16:39:11.181649409 +0100
@@ -0,0 +1 @@
+symbolic link to /base
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/syft-0.68.1/syft/source/test-fixtures/symlinks-base/sub/link 
new/syft-0.69.0/syft/source/test-fixtures/symlinks-base/sub/link
--- old/syft-0.68.1/syft/source/test-fixtures/symlinks-base/sub/link    
1970-01-01 01:00:00.000000000 +0100
+++ new/syft-0.69.0/syft/source/test-fixtures/symlinks-base/sub/link    
2023-02-01 16:39:11.177649383 +0100
@@ -0,0 +1 @@
+symbolic link to ../sub/item
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/syft-0.68.1/test/cli/all_formats_convertible_test.go 
new/syft-0.69.0/test/cli/all_formats_convertible_test.go
--- old/syft-0.68.1/test/cli/all_formats_convertible_test.go    2023-01-25 
18:18:24.000000000 +0100
+++ new/syft-0.69.0/test/cli/all_formats_convertible_test.go    2023-01-30 
19:47:24.000000000 +0100
@@ -1,6 +1,7 @@
 package cli
 
 import (
+       "fmt"
        "os"
        "path/filepath"
        "strings"
@@ -9,13 +10,8 @@
        "github.com/stretchr/testify/require"
 )
 
-type conversion struct {
-       To   string
-       From string
-}
-
 func TestConvertCmdFlags(t *testing.T) {
-       commonAssertions := []traitAssertion{
+       assertions := []traitAssertion{
                func(tb testing.TB, stdout, _ string, _ int) {
                        tb.Helper()
                        if len(stdout) < 1000 {
@@ -26,52 +22,48 @@
        }
 
        tests := []struct {
-               name        string
-               conversions []conversion
-               env         map[string]string
-               assertions  []traitAssertion
+               to       string
+               from     string
+               template string
+               env      map[string]string
        }{
-               {
-                       name: "syft-format convertable to spdx-json",
-                       conversions: []conversion{
-                               {To: "syft-json", From: "spdx-json"},
-                               {To: "syft-json", From: "cyclonedx-json"},
-                               {To: "spdx-json", From: "syft-json"},
-                               {To: "spdx-json", From: "cyclonedx-json"},
-                               {To: "cyclonedx-json", From: "syft-json"},
-                               {To: "cyclonedx-json", From: "spdx-json"},
-                       },
-                       assertions: commonAssertions,
-               },
+               {to: "syft-json", from: "spdx-json"},
+               {to: "syft-json", from: "cyclonedx-json"},
+               {to: "spdx-json", from: "syft-json"},
+               {to: "template", from: "syft-json", template: 
"test-fixtures/csv.template"},
+               {to: "spdx-json", from: "cyclonedx-json"},
+               {to: "cyclonedx-json", from: "syft-json"},
+               {to: "cyclonedx-json", from: "spdx-json"},
        }
 
        for _, test := range tests {
-               t.Run(test.name, func(t *testing.T) {
-                       for _, c := range test.conversions {
-                               sbomArgs := 
[]string{"dir:./test-fixtures/image-pkg-coverage", "-o", c.From}
-                               cmd, stdout, stderr := runSyft(t, test.env, 
sbomArgs...)
-                               if cmd.ProcessState.ExitCode() != 0 {
-                                       t.Fatalf("failure executing syft 
creating an sbom")
-                                       t.Log("STDOUT:\n", stdout)
-                                       t.Log("STDERR:\n", stderr)
-                                       t.Log("COMMAND:", 
strings.Join(cmd.Args, " "))
-                                       return
-                               }
-
-                               tempDir := t.TempDir()
-                               sbomFile := filepath.Join(tempDir, "sbom.json")
-                               require.NoError(t, os.WriteFile(sbomFile, 
[]byte(stdout), 0666))
-
-                               convertArgs := []string{"convert", sbomFile, 
"-o", c.To}
-                               cmd, stdout, stderr = runSyft(t, test.env, 
convertArgs...)
-                               for _, traitFn := range test.assertions {
-                                       traitFn(t, stdout, stderr, 
cmd.ProcessState.ExitCode())
-                               }
-                               if t.Failed() {
-                                       t.Log("STDOUT:\n", stdout)
-                                       t.Log("STDERR:\n", stderr)
-                                       t.Log("COMMAND:", 
strings.Join(cmd.Args, " "))
-                               }
+               t.Run(fmt.Sprintf("from %s to %s", test.from, test.to), func(t 
*testing.T) {
+                       sbomArgs := 
[]string{"dir:./test-fixtures/image-pkg-coverage", "-o", test.from}
+                       cmd, stdout, stderr := runSyft(t, test.env, sbomArgs...)
+                       if cmd.ProcessState.ExitCode() != 0 {
+                               t.Log("STDOUT:\n", stdout)
+                               t.Log("STDERR:\n", stderr)
+                               t.Log("COMMAND:", strings.Join(cmd.Args, " "))
+                               t.Fatalf("failure executing syft creating an 
sbom")
+                               return
+                       }
+
+                       tempDir := t.TempDir()
+                       sbomFile := filepath.Join(tempDir, "sbom.json")
+                       require.NoError(t, os.WriteFile(sbomFile, 
[]byte(stdout), 0666))
+
+                       convertArgs := []string{"convert", sbomFile, "-o", 
test.to}
+                       if test.template != "" {
+                               convertArgs = append(convertArgs, "--template", 
test.template)
+                       }
+                       cmd, stdout, stderr = runSyft(t, test.env, 
convertArgs...)
+                       for _, traitFn := range assertions {
+                               traitFn(t, stdout, stderr, 
cmd.ProcessState.ExitCode())
+                       }
+                       if t.Failed() {
+                               t.Log("STDOUT:\n", stdout)
+                               t.Log("STDERR:\n", stderr)
+                               t.Log("COMMAND:", strings.Join(cmd.Args, " "))
                        }
                })
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/syft-0.68.1/ui/event_handlers.go 
new/syft-0.69.0/ui/event_handlers.go
--- old/syft-0.68.1/ui/event_handlers.go        2023-01-25 18:18:24.000000000 
+0100
+++ new/syft-0.69.0/ui/event_handlers.go        2023-01-30 19:47:24.000000000 
+0100
@@ -618,6 +618,9 @@
                        text := s.Text()
                        if strings.Contains(text, "tlog entry created with 
index") {
                                tlogEntry = text
+                       } else {
+                               // no tlog entry create so user used personal 
PKI
+                               tlogEntry = "signed attestation using provided 
key"
                        }
                        _, err = line.Write([]byte(fmt.Sprintf("     %s %s", 
auxInfoFormat.Sprintf("░░"), text)))
                        if err != nil {

++++++ vendor.tar.gz ++++++
/work/SRC/openSUSE:Factory/syft/vendor.tar.gz 
/work/SRC/openSUSE:Factory/.syft.new.32243/vendor.tar.gz differ: char 5, line 1

Reply via email to