github.com/google/osv-scalibr@v0.4.1/extractor/filesystem/list/list.go (about)

     1  // Copyright 2025 Google LLC
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // Package list provides a public list of SCALIBR-internal extraction plugins.
    16  package list
    17  
    18  import (
    19  	"fmt"
    20  	"maps"
    21  	"slices"
    22  
    23  	"github.com/google/osv-scalibr/extractor/filesystem"
    24  	"github.com/google/osv-scalibr/extractor/filesystem/containers/containerd"
    25  	"github.com/google/osv-scalibr/extractor/filesystem/containers/dockerbaseimage"
    26  	"github.com/google/osv-scalibr/extractor/filesystem/containers/dockercomposeimage"
    27  	"github.com/google/osv-scalibr/extractor/filesystem/containers/k8simage"
    28  	"github.com/google/osv-scalibr/extractor/filesystem/containers/podman"
    29  	"github.com/google/osv-scalibr/extractor/filesystem/embeddedfs/archive"
    30  	"github.com/google/osv-scalibr/extractor/filesystem/embeddedfs/ova"
    31  	"github.com/google/osv-scalibr/extractor/filesystem/embeddedfs/vdi"
    32  	"github.com/google/osv-scalibr/extractor/filesystem/embeddedfs/vmdk"
    33  	"github.com/google/osv-scalibr/extractor/filesystem/language/cpp/conanlock"
    34  	"github.com/google/osv-scalibr/extractor/filesystem/language/dart/pubspec"
    35  	"github.com/google/osv-scalibr/extractor/filesystem/language/dotnet/depsjson"
    36  	"github.com/google/osv-scalibr/extractor/filesystem/language/dotnet/dotnetpe"
    37  	"github.com/google/osv-scalibr/extractor/filesystem/language/dotnet/packagesconfig"
    38  	"github.com/google/osv-scalibr/extractor/filesystem/language/dotnet/packageslockjson"
    39  	elixir "github.com/google/osv-scalibr/extractor/filesystem/language/elixir/mixlock"
    40  	"github.com/google/osv-scalibr/extractor/filesystem/language/erlang/mixlock"
    41  	"github.com/google/osv-scalibr/extractor/filesystem/language/golang/gobinary"
    42  	"github.com/google/osv-scalibr/extractor/filesystem/language/golang/gomod"
    43  	"github.com/google/osv-scalibr/extractor/filesystem/language/haskell/cabal"
    44  	"github.com/google/osv-scalibr/extractor/filesystem/language/haskell/stacklock"
    45  	javaarchive "github.com/google/osv-scalibr/extractor/filesystem/language/java/archive"
    46  	"github.com/google/osv-scalibr/extractor/filesystem/language/java/gradlelockfile"
    47  	"github.com/google/osv-scalibr/extractor/filesystem/language/java/gradleverificationmetadataxml"
    48  	"github.com/google/osv-scalibr/extractor/filesystem/language/java/pomxml"
    49  	"github.com/google/osv-scalibr/extractor/filesystem/language/java/pomxmlnet"
    50  	"github.com/google/osv-scalibr/extractor/filesystem/language/javascript/bunlock"
    51  	"github.com/google/osv-scalibr/extractor/filesystem/language/javascript/packagejson"
    52  	"github.com/google/osv-scalibr/extractor/filesystem/language/javascript/packagelockjson"
    53  	"github.com/google/osv-scalibr/extractor/filesystem/language/javascript/pnpmlock"
    54  	"github.com/google/osv-scalibr/extractor/filesystem/language/javascript/yarnlock"
    55  	"github.com/google/osv-scalibr/extractor/filesystem/language/lua/luarocks"
    56  	"github.com/google/osv-scalibr/extractor/filesystem/language/nim/nimble"
    57  	"github.com/google/osv-scalibr/extractor/filesystem/language/php/composerlock"
    58  	"github.com/google/osv-scalibr/extractor/filesystem/language/python/condameta"
    59  	"github.com/google/osv-scalibr/extractor/filesystem/language/python/pdmlock"
    60  	"github.com/google/osv-scalibr/extractor/filesystem/language/python/pipfilelock"
    61  	"github.com/google/osv-scalibr/extractor/filesystem/language/python/poetrylock"
    62  	"github.com/google/osv-scalibr/extractor/filesystem/language/python/pylock"
    63  	"github.com/google/osv-scalibr/extractor/filesystem/language/python/requirements"
    64  	"github.com/google/osv-scalibr/extractor/filesystem/language/python/setup"
    65  	"github.com/google/osv-scalibr/extractor/filesystem/language/python/uvlock"
    66  	"github.com/google/osv-scalibr/extractor/filesystem/language/python/wheelegg"
    67  	"github.com/google/osv-scalibr/extractor/filesystem/language/r/renvlock"
    68  	"github.com/google/osv-scalibr/extractor/filesystem/language/ruby/gemfilelock"
    69  	"github.com/google/osv-scalibr/extractor/filesystem/language/ruby/gemspec"
    70  	"github.com/google/osv-scalibr/extractor/filesystem/language/rust/cargoauditable"
    71  	"github.com/google/osv-scalibr/extractor/filesystem/language/rust/cargolock"
    72  	"github.com/google/osv-scalibr/extractor/filesystem/language/rust/cargotoml"
    73  	"github.com/google/osv-scalibr/extractor/filesystem/language/swift/packageresolved"
    74  	"github.com/google/osv-scalibr/extractor/filesystem/language/swift/podfilelock"
    75  	chromeextensions "github.com/google/osv-scalibr/extractor/filesystem/misc/chrome/extensions"
    76  	"github.com/google/osv-scalibr/extractor/filesystem/misc/vscodeextensions"
    77  	wordpressplugins "github.com/google/osv-scalibr/extractor/filesystem/misc/wordpress/plugins"
    78  	"github.com/google/osv-scalibr/extractor/filesystem/os/apk"
    79  	"github.com/google/osv-scalibr/extractor/filesystem/os/cos"
    80  	"github.com/google/osv-scalibr/extractor/filesystem/os/dpkg"
    81  	"github.com/google/osv-scalibr/extractor/filesystem/os/flatpak"
    82  	"github.com/google/osv-scalibr/extractor/filesystem/os/homebrew"
    83  	"github.com/google/osv-scalibr/extractor/filesystem/os/kernel/module"
    84  	"github.com/google/osv-scalibr/extractor/filesystem/os/kernel/vmlinuz"
    85  	"github.com/google/osv-scalibr/extractor/filesystem/os/macapps"
    86  	"github.com/google/osv-scalibr/extractor/filesystem/os/macports"
    87  	"github.com/google/osv-scalibr/extractor/filesystem/os/nix"
    88  	"github.com/google/osv-scalibr/extractor/filesystem/os/pacman"
    89  	"github.com/google/osv-scalibr/extractor/filesystem/os/portage"
    90  	"github.com/google/osv-scalibr/extractor/filesystem/os/rpm"
    91  	"github.com/google/osv-scalibr/extractor/filesystem/os/snap"
    92  	"github.com/google/osv-scalibr/extractor/filesystem/os/winget"
    93  	"github.com/google/osv-scalibr/extractor/filesystem/runtime/asdf"
    94  	"github.com/google/osv-scalibr/extractor/filesystem/runtime/nodejs/nodeversion"
    95  	"github.com/google/osv-scalibr/extractor/filesystem/runtime/nodejs/nvm"
    96  	"github.com/google/osv-scalibr/extractor/filesystem/sbom/cdx"
    97  	"github.com/google/osv-scalibr/extractor/filesystem/sbom/spdx"
    98  	"github.com/google/osv-scalibr/extractor/filesystem/secrets/awsaccesskey"
    99  	"github.com/google/osv-scalibr/extractor/filesystem/secrets/convert"
   100  	"github.com/google/osv-scalibr/extractor/filesystem/secrets/gitbasicauth/codecatalyst"
   101  	"github.com/google/osv-scalibr/extractor/filesystem/secrets/mariadb"
   102  	"github.com/google/osv-scalibr/extractor/filesystem/secrets/mysqlmylogin"
   103  	"github.com/google/osv-scalibr/extractor/filesystem/secrets/onepasswordconnecttoken"
   104  	"github.com/google/osv-scalibr/extractor/filesystem/secrets/pgpass"
   105  	"github.com/google/osv-scalibr/veles"
   106  	"github.com/google/osv-scalibr/veles/secrets/anthropicapikey"
   107  	"github.com/google/osv-scalibr/veles/secrets/azurestorageaccountaccesskey"
   108  	"github.com/google/osv-scalibr/veles/secrets/azuretoken"
   109  	"github.com/google/osv-scalibr/veles/secrets/cratesioapitoken"
   110  	"github.com/google/osv-scalibr/veles/secrets/digitaloceanapikey"
   111  	"github.com/google/osv-scalibr/veles/secrets/dockerhubpat"
   112  	"github.com/google/osv-scalibr/veles/secrets/gcpapikey"
   113  	"github.com/google/osv-scalibr/veles/secrets/gcpexpressmode"
   114  	"github.com/google/osv-scalibr/veles/secrets/gcpoauth2access"
   115  	"github.com/google/osv-scalibr/veles/secrets/gcpoauth2client"
   116  	"github.com/google/osv-scalibr/veles/secrets/gcpsak"
   117  	"github.com/google/osv-scalibr/veles/secrets/gcshmackey"
   118  	"github.com/google/osv-scalibr/veles/secrets/github"
   119  	"github.com/google/osv-scalibr/veles/secrets/gitlabpat"
   120  	"github.com/google/osv-scalibr/veles/secrets/grokxaiapikey"
   121  	"github.com/google/osv-scalibr/veles/secrets/hashicorpvault"
   122  	"github.com/google/osv-scalibr/veles/secrets/hcp"
   123  	"github.com/google/osv-scalibr/veles/secrets/huggingfaceapikey"
   124  	"github.com/google/osv-scalibr/veles/secrets/jwt"
   125  	"github.com/google/osv-scalibr/veles/secrets/onepasswordkeys"
   126  	"github.com/google/osv-scalibr/veles/secrets/openai"
   127  	"github.com/google/osv-scalibr/veles/secrets/perplexityapikey"
   128  	"github.com/google/osv-scalibr/veles/secrets/postmanapikey"
   129  	"github.com/google/osv-scalibr/veles/secrets/privatekey"
   130  	"github.com/google/osv-scalibr/veles/secrets/pypiapitoken"
   131  	"github.com/google/osv-scalibr/veles/secrets/pyxkeyv1"
   132  	"github.com/google/osv-scalibr/veles/secrets/pyxkeyv2"
   133  	"github.com/google/osv-scalibr/veles/secrets/recaptchakey"
   134  	"github.com/google/osv-scalibr/veles/secrets/rubygemsapikey"
   135  	"github.com/google/osv-scalibr/veles/secrets/slacktoken"
   136  	"github.com/google/osv-scalibr/veles/secrets/stripeapikeys"
   137  	"github.com/google/osv-scalibr/veles/secrets/tinkkeyset"
   138  	"github.com/google/osv-scalibr/veles/secrets/vapid"
   139  
   140  	cpb "github.com/google/osv-scalibr/binary/proto/config_go_proto"
   141  )
   142  
   143  // InitFn is the extractor initializer function.
   144  type InitFn func(cfg *cpb.PluginConfig) filesystem.Extractor
   145  
   146  // InitMap is a map of extractor names to their initers.
   147  type InitMap map[string][]InitFn
   148  
   149  // LINT.IfChange
   150  var (
   151  	// Language extractors.
   152  
   153  	// CppSource extractors for C++.
   154  	CppSource = InitMap{conanlock.Name: {noCFG(conanlock.New)}}
   155  	// JavaSource extractors for Java.
   156  	JavaSource = InitMap{
   157  		gradlelockfile.Name:                {noCFG(gradlelockfile.New)},
   158  		gradleverificationmetadataxml.Name: {noCFG(gradleverificationmetadataxml.New)},
   159  		// pom.xml extraction for environments with and without network access.
   160  		pomxml.Name:    {noCFG(pomxml.New)},
   161  		pomxmlnet.Name: {pomxmlnet.New},
   162  	}
   163  	// JavaArtifact extractors for Java.
   164  	JavaArtifact = InitMap{
   165  		javaarchive.Name: {noCFG(javaarchive.NewDefault)},
   166  	}
   167  	// JavascriptSource extractors for Javascript.
   168  	JavascriptSource = InitMap{
   169  		packagejson.Name:     {noCFG(packagejson.NewDefault)},
   170  		packagelockjson.Name: {noCFG(packagelockjson.NewDefault)},
   171  		pnpmlock.Name:        {noCFG(pnpmlock.New)},
   172  		yarnlock.Name:        {noCFG(yarnlock.New)},
   173  		bunlock.Name:         {noCFG(bunlock.New)},
   174  	}
   175  	// JavascriptArtifact extractors for Javascript.
   176  	JavascriptArtifact = InitMap{
   177  		packagejson.Name: {noCFG(packagejson.NewDefault)},
   178  	}
   179  	// PythonSource extractors for Python.
   180  	PythonSource = InitMap{
   181  		// requirements extraction for environments with and without network access.
   182  		requirements.Name: {noCFG(requirements.NewDefault)},
   183  		setup.Name:        {noCFG(setup.NewDefault)},
   184  		pipfilelock.Name:  {noCFG(pipfilelock.New)},
   185  		pdmlock.Name:      {noCFG(pdmlock.New)},
   186  		poetrylock.Name:   {noCFG(poetrylock.New)},
   187  		pylock.Name:       {noCFG(pylock.New)},
   188  		condameta.Name:    {noCFG(condameta.NewDefault)},
   189  		uvlock.Name:       {noCFG(uvlock.New)},
   190  	}
   191  	// PythonArtifact extractors for Python.
   192  	PythonArtifact = InitMap{
   193  		wheelegg.Name: {noCFG(wheelegg.NewDefault)},
   194  	}
   195  	// GoSource extractors for Go.
   196  	GoSource = InitMap{
   197  		gomod.Name: {noCFG(gomod.New)},
   198  	}
   199  	// GoArtifact extractors for Go.
   200  	GoArtifact = InitMap{
   201  		gobinary.Name: {gobinary.New},
   202  	}
   203  	// DartSource extractors for Dart.
   204  	DartSource = InitMap{pubspec.Name: {noCFG(pubspec.New)}}
   205  	// ErlangSource extractors for Erlang.
   206  	ErlangSource = InitMap{mixlock.Name: {noCFG(mixlock.New)}}
   207  	// NimSource extractors for Nim.
   208  	NimSource = InitMap{nimble.Name: {noCFG(nimble.New)}}
   209  	// LuaSource extractors for Lua.
   210  	LuaSource = InitMap{luarocks.Name: {noCFG(luarocks.New)}}
   211  	// ElixirSource extractors for Elixir.
   212  	ElixirSource = InitMap{elixir.Name: {noCFG(elixir.NewDefault)}}
   213  	// HaskellSource extractors for Haskell.
   214  	HaskellSource = InitMap{
   215  		stacklock.Name: {noCFG(stacklock.NewDefault)},
   216  		cabal.Name:     {noCFG(cabal.NewDefault)},
   217  	}
   218  	// RSource extractors for R source extractors
   219  	RSource = InitMap{renvlock.Name: {noCFG(renvlock.New)}}
   220  	// RubySource extractors for Ruby.
   221  	RubySource = InitMap{
   222  		gemspec.Name:     {noCFG(gemspec.NewDefault)},
   223  		gemfilelock.Name: {noCFG(gemfilelock.New)},
   224  	}
   225  	// RustSource extractors for Rust.
   226  	RustSource = InitMap{
   227  		cargolock.Name: {noCFG(cargolock.New)},
   228  		cargotoml.Name: {noCFG(cargotoml.New)},
   229  	}
   230  	// RustArtifact extractors for Rust.
   231  	RustArtifact = InitMap{
   232  		cargoauditable.Name: {noCFG(cargoauditable.NewDefault)},
   233  	}
   234  	// SBOM extractors.
   235  	SBOM = InitMap{
   236  		cdx.Name:  {noCFG(cdx.New)},
   237  		spdx.Name: {noCFG(spdx.New)},
   238  	}
   239  	// DotnetSource extractors for Dotnet (.NET).
   240  	DotnetSource = InitMap{
   241  		depsjson.Name:         {noCFG(depsjson.NewDefault)},
   242  		packagesconfig.Name:   {noCFG(packagesconfig.NewDefault)},
   243  		packageslockjson.Name: {noCFG(packageslockjson.NewDefault)},
   244  	}
   245  	// DotnetArtifact extractors for Dotnet (.NET).
   246  	DotnetArtifact = InitMap{
   247  		dotnetpe.Name: {noCFG(dotnetpe.NewDefault)},
   248  	}
   249  	// PHPSource extractors for PHP Source extractors.
   250  	PHPSource = InitMap{composerlock.Name: {noCFG(composerlock.New)}}
   251  	// SwiftSource extractors for Swift.
   252  	SwiftSource = InitMap{
   253  		packageresolved.Name: {noCFG(packageresolved.NewDefault)},
   254  		podfilelock.Name:     {noCFG(podfilelock.NewDefault)},
   255  	}
   256  
   257  	// Containers extractors.
   258  	Containers = InitMap{
   259  		containerd.Name:         {noCFG(containerd.NewDefault)},
   260  		k8simage.Name:           {noCFG(k8simage.NewDefault)},
   261  		podman.Name:             {noCFG(podman.NewDefault)},
   262  		dockerbaseimage.Name:    {noCFG(dockerbaseimage.NewDefault)},
   263  		dockercomposeimage.Name: {noCFG(dockercomposeimage.NewDefault)},
   264  	}
   265  
   266  	// OS extractors.
   267  	OS = InitMap{
   268  		dpkg.Name:     {noCFG(dpkg.NewDefault)},
   269  		apk.Name:      {noCFG(apk.NewDefault)},
   270  		rpm.Name:      {noCFG(rpm.NewDefault)},
   271  		cos.Name:      {noCFG(cos.NewDefault)},
   272  		snap.Name:     {noCFG(snap.NewDefault)},
   273  		nix.Name:      {noCFG(nix.New)},
   274  		module.Name:   {noCFG(module.NewDefault)},
   275  		vmlinuz.Name:  {noCFG(vmlinuz.NewDefault)},
   276  		pacman.Name:   {noCFG(pacman.NewDefault)},
   277  		portage.Name:  {noCFG(portage.NewDefault)},
   278  		flatpak.Name:  {noCFG(flatpak.NewDefault)},
   279  		homebrew.Name: {noCFG(homebrew.New)},
   280  		macapps.Name:  {noCFG(macapps.NewDefault)},
   281  		macports.Name: {noCFG(macports.New)},
   282  		winget.Name:   {noCFG(winget.NewDefault)},
   283  	}
   284  
   285  	// SecretExtractors for Extractor interface.
   286  	SecretExtractors = InitMap{
   287  		mysqlmylogin.Name:            {noCFG(mysqlmylogin.New)},
   288  		pgpass.Name:                  {noCFG(pgpass.New)},
   289  		onepasswordconnecttoken.Name: {noCFG(onepasswordconnecttoken.New)},
   290  		mariadb.Name:                 {noCFG(mariadb.NewDefault)},
   291  		awsaccesskey.Name:            {noCFG(awsaccesskey.New)},
   292  		codecatalyst.Name:            {noCFG(codecatalyst.New)},
   293  	}
   294  
   295  	// SecretDetectors for Detector interface.
   296  	SecretDetectors = initMapFromVelesPlugins([]velesPlugin{
   297  		{anthropicapikey.NewDetector(), "secrets/anthropicapikey", 0},
   298  		{azuretoken.NewDetector(), "secrets/azuretoken", 0},
   299  		{azurestorageaccountaccesskey.NewDetector(), "secrets/azurestorageaccountaccesskey", 0},
   300  		{digitaloceanapikey.NewDetector(), "secrets/digitaloceanapikey", 0},
   301  		{pypiapitoken.NewDetector(), "secrets/pypiapitoken", 0},
   302  		{cratesioapitoken.NewDetector(), "secrets/cratesioapitoken", 0},
   303  		{slacktoken.NewAppConfigAccessTokenDetector(), "secrets/slackappconfigaccesstoken", 0},
   304  		{slacktoken.NewAppConfigRefreshTokenDetector(), "secrets/slackappconfigrefreshtoken", 0},
   305  		{slacktoken.NewAppLevelTokenDetector(), "secrets/slackappleveltoken", 0},
   306  		{dockerhubpat.NewDetector(), "secrets/dockerhubpat", 0},
   307  		{gcpapikey.NewDetector(), "secrets/gcpapikey", 0},
   308  		{gcpexpressmode.NewDetector(), "secrets/gcpexpressmode", 0},
   309  		{gcpsak.NewDetector(), "secrets/gcpsak", 0},
   310  		{gitlabpat.NewDetector(), "secrets/gitlabpat", 0},
   311  		{grokxaiapikey.NewAPIKeyDetector(), "secrets/grokxaiapikey", 0},
   312  		{grokxaiapikey.NewManagementKeyDetector(), "secrets/grokxaimanagementkey", 0},
   313  		{hashicorpvault.NewTokenDetector(), "secrets/hashicorpvaulttoken", 0},
   314  		{hashicorpvault.NewAppRoleDetector(), "secrets/hashicorpvaultapprole", 0},
   315  		{hcp.NewPairDetector(), "secrets/hcpclientcredentials", 0},
   316  		{hcp.NewAccessTokenDetector(), "secrets/hcpaccesstoken", 0},
   317  		{huggingfaceapikey.NewDetector(), "secrets/huggingfaceapikey", 0},
   318  		{openai.NewDetector(), "secrets/openai", 0},
   319  		{perplexityapikey.NewDetector(), "secrets/perplexityapikey", 0},
   320  		{postmanapikey.NewAPIKeyDetector(), "secrets/postmanapikey", 0},
   321  		{postmanapikey.NewCollectionTokenDetector(), "secrets/postmancollectiontoken", 0},
   322  		{privatekey.NewDetector(), "secrets/privatekey", 0},
   323  		{rubygemsapikey.NewDetector(), "secrets/rubygemsapikey", 0},
   324  		{tinkkeyset.NewDetector(), "secrets/tinkkeyset", 0},
   325  		{github.NewAppRefreshTokenDetector(), "secrets/githubapprefreshtoken", 0},
   326  		{github.NewAppS2STokenDetector(), "secrets/githubapps2stoken", 0},
   327  		{github.NewAppU2SDetector(), "secrets/githubappu2stoken", 0},
   328  		{github.NewClassicPATDetector(), "secrets/githubclassicpat", 0},
   329  		{github.NewFineGrainedPATDetector(), "secrets/githubfinegrainedpat", 0},
   330  		{github.NewOAuthTokenDetector(), "secrets/githuboauthtoken", 0},
   331  		{stripeapikeys.NewSecretKeyDetector(), "secrets/stripesecretkey", 0},
   332  		{stripeapikeys.NewRestrictedKeyDetector(), "secrets/striperestrictedkey", 0},
   333  		{stripeapikeys.NewWebhookSecretDetector(), "secrets/stripewebhooksecret", 0},
   334  		{gcpoauth2client.NewDetector(), "secrets/gcpoauth2clientcredentials", 0},
   335  		{gcpoauth2access.NewDetector(), "secrets/gcpoauth2accesstoken", 0},
   336  		{onepasswordkeys.NewSecretKeyDetector(), "secrets/onepasswordsecretkey", 0},
   337  		{onepasswordkeys.NewServiceTokenDetector(), "secrets/onepasswordservicetoken", 0},
   338  		{onepasswordkeys.NewRecoveryTokenDetector(), "secrets/onepasswordrecoverycode", 0},
   339  		{gcshmackey.NewDetector(), "secrets/gcshmackey", 0},
   340  		{vapid.NewDetector(), "secrets/vapidkey", 0},
   341  		{recaptchakey.NewDetector(), "secrets/recaptchakey", 0},
   342  		{jwt.NewDetector(), "secrets/jwttoken", 0},
   343  		{pyxkeyv1.NewDetector(), "secrets/pyxkeyv1", 0},
   344  		{pyxkeyv2.NewDetector(), "secrets/pyxkeyv2", 0},
   345  	})
   346  
   347  	// Secrets contains both secret extractors and detectors.
   348  	Secrets = concat(
   349  		SecretDetectors,
   350  		SecretExtractors,
   351  	)
   352  
   353  	// Misc artifact extractors.
   354  	Misc = InitMap{
   355  		vscodeextensions.Name: {noCFG(vscodeextensions.New)},
   356  		wordpressplugins.Name: {noCFG(wordpressplugins.NewDefault)},
   357  		chromeextensions.Name: {noCFG(chromeextensions.New)},
   358  	}
   359  
   360  	// MiscSource extractors for miscellaneous purposes.
   361  	MiscSource = InitMap{
   362  		asdf.Name:        {noCFG(asdf.New)},
   363  		nvm.Name:         {noCFG(nvm.New)},
   364  		nodeversion.Name: {noCFG(nodeversion.New)},
   365  	}
   366  
   367  	// EmbeddedFS extractors.
   368  	EmbeddedFS = InitMap{
   369  		archive.Name: {archive.New},
   370  		vdi.Name:     {vdi.New},
   371  		vmdk.Name:    {vmdk.New},
   372  		ova.Name:     {ova.New},
   373  	}
   374  
   375  	// Collections of extractors.
   376  
   377  	// SourceCode extractors find packages in source code contexts (e.g. lockfiles).
   378  	SourceCode = concat(
   379  		CppSource,
   380  		JavaSource,
   381  		JavascriptSource,
   382  		PythonSource,
   383  		GoSource,
   384  		DartSource,
   385  		ErlangSource,
   386  		ElixirSource,
   387  		HaskellSource,
   388  		PHPSource,
   389  		RSource,
   390  		RubySource,
   391  		RustSource,
   392  		DotnetSource,
   393  		SwiftSource,
   394  		NimSource,
   395  		LuaSource,
   396  		Secrets,
   397  		MiscSource,
   398  	)
   399  
   400  	// Artifact extractors find packages on built systems (e.g. parsing
   401  	// descriptors of installed packages).
   402  	Artifact = concat(
   403  		JavaArtifact,
   404  		JavascriptArtifact,
   405  		PythonArtifact,
   406  		GoArtifact,
   407  		DotnetArtifact,
   408  		RustArtifact,
   409  		SBOM,
   410  		OS,
   411  		Misc,
   412  		EmbeddedFS,
   413  		Containers,
   414  		Secrets,
   415  	)
   416  
   417  	// Default extractors that are recommended to be enabled.
   418  	Default = concat(
   419  		JavaSource, JavaArtifact,
   420  		JavascriptSource, JavascriptArtifact,
   421  		PythonSource, PythonArtifact,
   422  		GoSource, GoArtifact,
   423  		OS,
   424  	)
   425  
   426  	// All extractors available from SCALIBR.
   427  	All = concat(
   428  		SourceCode,
   429  		Artifact,
   430  	)
   431  
   432  	extractorNames = concat(All, InitMap{
   433  		// Languages.
   434  		"cpp":        vals(CppSource),
   435  		"java":       vals(concat(JavaSource, JavaArtifact)),
   436  		"javascript": vals(concat(JavascriptSource, JavascriptArtifact)),
   437  		"python":     vals(concat(PythonSource, PythonArtifact)),
   438  		"go":         vals(concat(GoSource, GoArtifact)),
   439  		"dart":       vals(DartSource),
   440  		"erlang":     vals(ErlangSource),
   441  		"lua":        vals(LuaSource),
   442  		"nim":        vals(NimSource),
   443  		"elixir":     vals(ElixirSource),
   444  		"haskell":    vals(HaskellSource),
   445  		"r":          vals(RSource),
   446  		"ruby":       vals(RubySource),
   447  		"dotnet":     vals(concat(DotnetSource, DotnetArtifact)),
   448  		"php":        vals(PHPSource),
   449  		"rust":       vals(concat(RustSource, RustArtifact)),
   450  		"swift":      vals(SwiftSource),
   451  
   452  		"sbom":       vals(SBOM),
   453  		"os":         vals(OS),
   454  		"embeddedfs": vals(EmbeddedFS),
   455  		"containers": vals(Containers),
   456  		"secrets":    vals(Secrets),
   457  		"misc":       vals(Misc),
   458  		"miscsource": vals(MiscSource),
   459  
   460  		// Collections.
   461  		"artifact":           vals(Artifact),
   462  		"sourcecode":         vals(SourceCode),
   463  		"default":            vals(Default),
   464  		"extractors/default": vals(Default),
   465  		"all":                vals(All),
   466  		"extractors/all":     vals(All),
   467  	})
   468  )
   469  
   470  // LINT.ThenChange(/docs/supported_inventory_types.md)
   471  
   472  func concat(initMaps ...InitMap) InitMap {
   473  	result := InitMap{}
   474  	for _, m := range initMaps {
   475  		maps.Copy(result, m)
   476  	}
   477  	return result
   478  }
   479  
   480  func vals(initMap InitMap) []InitFn {
   481  	return slices.Concat(slices.Collect(maps.Values(initMap))...)
   482  }
   483  
   484  // Wraps initer functions that don't take any config value to initer functions that do.
   485  // TODO(b/400910349): Remove once all plugins take config values.
   486  func noCFG(f func() filesystem.Extractor) InitFn {
   487  	return func(_ *cpb.PluginConfig) filesystem.Extractor { return f() }
   488  }
   489  
   490  // ExtractorsFromName returns a list of extractors from a name.
   491  func ExtractorsFromName(name string, cfg *cpb.PluginConfig) ([]filesystem.Extractor, error) {
   492  	if initers, ok := extractorNames[name]; ok {
   493  		result := []filesystem.Extractor{}
   494  		for _, initer := range initers {
   495  			result = append(result, initer(cfg))
   496  		}
   497  		return result, nil
   498  	}
   499  	return nil, fmt.Errorf("unknown extractor %q", name)
   500  }
   501  
   502  type velesPlugin struct {
   503  	detector veles.Detector
   504  	name     string
   505  	version  int
   506  }
   507  
   508  func initMapFromVelesPlugins(plugins []velesPlugin) InitMap {
   509  	result := InitMap{}
   510  	for _, p := range plugins {
   511  		result[p.name] = []InitFn{noCFG(convert.FromVelesDetector(p.detector, p.name, p.version))}
   512  	}
   513  	return result
   514  }