Skip to content
Static Analysis Library for Containers
Go Makefile
Branch: master
Clone or download
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
analyzer Improves package analysis errors usability (#24) Jul 2, 2019
cache Replace slash with underscore (#14) May 13, 2019
cmd/fanal Add poetry parser (#19) May 21, 2019
extractor Analyze command (#12) May 12, 2019
types add gcr test May 9, 2019
utils add yarn.lock parser (#16) May 16, 2019
.gitignore Initial commit (#1) May 1, 2019
.travis.yml merge ubuntu analyzer into debianbase analyzer (#6) May 6, 2019
LICENSE Initial commit Mar 27, 2019
Makefile Initial commit (#1) May 1, 2019
README.md Add poetry parser (#19) May 21, 2019
go.mod
go.sum change reg version (#25) Jul 6, 2019

README.md

fanal

Static Analysis Library for Containers

GoDoc Build Status Coverage Status Go Report Card MIT License

Feature

  • Detect OS
  • Extract OS packages
  • Extract libraries used by an application
    • Bundler, Composer, npm, Yarn, Pipenv, Poetry, Cargo

Example

See cmd/fanal/

package main

import (
	"context"
	"flag"
	"fmt"
	"log"
	"os"

	"golang.org/x/xerrors"

	"github.com/knqyf263/fanal/cache"

	"github.com/knqyf263/fanal/analyzer"
	_ "github.com/knqyf263/fanal/analyzer/library/bundler"
	_ "github.com/knqyf263/fanal/analyzer/library/composer"
	_ "github.com/knqyf263/fanal/analyzer/library/npm"
	_ "github.com/knqyf263/fanal/analyzer/library/pipenv"
	_ "github.com/knqyf263/fanal/analyzer/library/poetry"
	_ "github.com/knqyf263/fanal/analyzer/library/yarn"
	_ "github.com/knqyf263/fanal/analyzer/library/cargo"
	_ "github.com/knqyf263/fanal/analyzer/os/alpine"
	_ "github.com/knqyf263/fanal/analyzer/os/amazonlinux"
	_ "github.com/knqyf263/fanal/analyzer/os/debianbase"
	_ "github.com/knqyf263/fanal/analyzer/os/opensuse"
	_ "github.com/knqyf263/fanal/analyzer/os/redhatbase"
	_ "github.com/knqyf263/fanal/analyzer/pkg/apk"
	_ "github.com/knqyf263/fanal/analyzer/pkg/dpkg"
	_ "github.com/knqyf263/fanal/analyzer/pkg/rpm"
	"github.com/knqyf263/fanal/extractor"
	"golang.org/x/crypto/ssh/terminal"
)

func main() {
	if err := run(); err != nil {
		log.Fatal(err)
	}
}

func run() (err error) {
	ctx := context.Background()
	tarPath := flag.String("f", "-", "layer.tar path")
	clearCache := flag.Bool("clear", false, "clear cache")
	flag.Parse()

	if *clearCache {
		if err = cache.Clear(); err != nil {
			return xerrors.Errorf("error in cache clear: %w", err)
		}
	}

	args := flag.Args()

	var files extractor.FileMap
	if len(args) > 0 {
		files, err = analyzer.Analyze(ctx, args[0])
		if err != nil {
			return err
		}
	} else {
		rc, err := openStream(*tarPath)
		if err != nil {
			return err
		}

		files, err = analyzer.AnalyzeFromFile(ctx, rc)
		if err != nil {
			return err
		}
	}

	os, err := analyzer.GetOS(files)
	if err != nil {
		return err
	}
	fmt.Printf("%+v\n", os)

	pkgs, err := analyzer.GetPackages(files)
	if err != nil {
		return err
	}
	fmt.Printf("Packages: %d\n", len(pkgs))

	libs, err := analyzer.GetLibraries(files)
	if err != nil {
		return err
	}
	for filepath, libList := range libs {
		fmt.Printf("%s: %d\n", filepath, len(libList))
	}
	return nil
}

func openStream(path string) (*os.File, error) {
	if path == "-" {
		if terminal.IsTerminal(0) {
			flag.Usage()
			os.Exit(64)
		} else {
			return os.Stdin, nil
		}
	}
	return os.Open(path)
}

Notes

When using latest tag, that image will be cached. After latest tag is updated, you need to clear cache.

You can’t perform that action at this time.