{"id":13839402,"url":"https://github.com/aquasecurity/fanal","last_synced_at":"2025-07-11T03:32:24.749Z","repository":{"id":35386252,"uuid":"177951669","full_name":"aquasecurity/fanal","owner":"aquasecurity","description":"Static Analysis Library for Containers","archived":true,"fork":false,"pushed_at":"2023-06-14T01:18:25.000Z","size":64979,"stargazers_count":198,"open_issues_count":31,"forks_count":100,"subscribers_count":18,"default_branch":"main","last_synced_at":"2025-07-04T19:51:15.161Z","etag":null,"topics":["hacktoberfest"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aquasecurity.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2019-03-27T08:33:38.000Z","updated_at":"2025-04-27T00:12:57.000Z","dependencies_parsed_at":"2024-01-20T21:58:14.950Z","dependency_job_id":null,"html_url":"https://github.com/aquasecurity/fanal","commit_stats":null,"previous_names":["knqyf263/fanal"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/aquasecurity/fanal","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aquasecurity%2Ffanal","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aquasecurity%2Ffanal/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aquasecurity%2Ffanal/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aquasecurity%2Ffanal/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aquasecurity","download_url":"https://codeload.github.com/aquasecurity/fanal/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aquasecurity%2Ffanal/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264721361,"owners_count":23653926,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hacktoberfest"],"created_at":"2024-08-04T17:00:21.954Z","updated_at":"2025-07-11T03:32:19.739Z","avatar_url":"https://github.com/aquasecurity.png","language":"Go","funding_links":[],"categories":["Security"],"sub_categories":[],"readme":"\u003e **This project has been moved into [github.com/aquasecurity/trivy](https://github.com/aquasecurity/trivy) - all packages or their equivalents can be found there instead**\n\n# fanal\nStatic Analysis Library for Containers\n\n[![GoDoc](https://godoc.org/github.com/aquasecurity/fanal?status.svg)](https://godoc.org/github.com/aquasecurity/fanal)\n![Test](https://github.com/aquasecurity/fanal/workflows/Test/badge.svg)\n[![Go Report Card](https://goreportcard.com/badge/github.com/aquasecurity/fanal)](https://goreportcard.com/report/github.com/aquasecurity/fanal)\n[![License: Apache-2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/aquasecurity/fanal/blob/main/LICENSE)\n\n## Feature\n- Detect OS\n- Extract OS packages\n- Extract libraries used by an application\n  - Bundler, Composer, npm, Yarn, Pipenv, Poetry, Cargo, Go Binary, Java Archive (JAR/WAR/EAR), NuGet\n\n## Example\nSee [`cmd/fanal/`](cmd/fanal)\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"flag\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\t\"golang.org/x/xerrors\"\n\n\t\"github.com/aquasecurity/fanal/cache\"\n\n\t\"github.com/aquasecurity/fanal/analyzer\"\n\t_ \"github.com/aquasecurity/fanal/analyzer/library/bundler\"\n\t_ \"github.com/aquasecurity/fanal/analyzer/library/composer\"\n\t_ \"github.com/aquasecurity/fanal/analyzer/library/npm\"\n\t_ \"github.com/aquasecurity/fanal/analyzer/library/pipenv\"\n\t_ \"github.com/aquasecurity/fanal/analyzer/library/poetry\"\n\t_ \"github.com/aquasecurity/fanal/analyzer/library/yarn\"\n\t_ \"github.com/aquasecurity/fanal/analyzer/library/cargo\"\n\t_ \"github.com/aquasecurity/fanal/analyzer/os/alpine\"\n\t_ \"github.com/aquasecurity/fanal/analyzer/os/amazonlinux\"\n\t_ \"github.com/aquasecurity/fanal/analyzer/os/debianbase\"\n\t_ \"github.com/aquasecurity/fanal/analyzer/os/suse\"\n\t_ \"github.com/aquasecurity/fanal/analyzer/os/redhatbase\"\n\t_ \"github.com/aquasecurity/fanal/analyzer/pkg/apk\"\n\t_ \"github.com/aquasecurity/fanal/analyzer/pkg/dpkg\"\n\t_ \"github.com/aquasecurity/fanal/analyzer/pkg/rpm\"\n\t\"github.com/aquasecurity/fanal/extractor\"\n\t\"golang.org/x/crypto/ssh/terminal\"\n)\n\nfunc main() {\n\tif err := run(); err != nil {\n\t\tlog.Fatal(err)\n\t}\n}\n\nfunc run() (err error) {\n\tctx := context.Background()\n\ttarPath := flag.String(\"f\", \"-\", \"layer.tar path\")\n\tclearCache := flag.Bool(\"clear\", false, \"clear cache\")\n\tflag.Parse()\n\n\tif *clearCache {\n\t\tif err = cache.Clear(); err != nil {\n\t\t\treturn xerrors.Errorf(\"error in cache clear: %w\", err)\n\t\t}\n\t}\n\n\targs := flag.Args()\n\n\tvar files extractor.FileMap\n\tif len(args) \u003e 0 {\n\t\tfiles, err = analyzer.Analyze(ctx, args[0])\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t} else {\n\t\trc, err := openStream(*tarPath)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tfiles, err = analyzer.AnalyzeFromFile(ctx, rc)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tos, err := analyzer.GetOS(files)\n\tif err != nil {\n\t\treturn err\n\t}\n\tfmt.Printf(\"%+v\\n\", os)\n\n\tpkgs, err := analyzer.GetPackages(files)\n\tif err != nil {\n\t\treturn err\n\t}\n\tfmt.Printf(\"Packages: %d\\n\", len(pkgs))\n\n\tlibs, err := analyzer.GetLibraries(files)\n\tif err != nil {\n\t\treturn err\n\t}\n\tfor filepath, libList := range libs {\n\t\tfmt.Printf(\"%s: %d\\n\", filepath, len(libList))\n\t}\n\treturn nil\n}\n\nfunc openStream(path string) (*os.File, error) {\n\tif path == \"-\" {\n\t\tif terminal.IsTerminal(0) {\n\t\t\tflag.Usage()\n\t\t\tos.Exit(64)\n\t\t} else {\n\t\t\treturn os.Stdin, nil\n\t\t}\n\t}\n\treturn os.Open(path)\n}\n\n```\n\n\n## Notes\nWhen using `latest` tag, that image will be cached. After `latest` tag is updated, you need to clear cache.\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faquasecurity%2Ffanal","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faquasecurity%2Ffanal","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faquasecurity%2Ffanal/lists"}