github.com/joey-fossa/fossa-cli@v0.7.34-0.20190708193710-569f1e8679f0/analyzers/okbuck/okbuck.go (about)

     1  // Package okbuck implements the analyzer for OkBuck. https://github.com/uber/okbuck.
     2  //
     3  // A `BuildTarget` in OkBuck is defined as a Build Target by OkBuck which is in
     4  // in the format of `//src/build:target`. OkBuck defines this as a string used to
     5  // identify a Build Rule.
     6  //
     7  // This package is implemented by externally calling the `okbuck` build tool.
     8  //
     9  // FAQ
    10  //
    11  // 1. Why is analyzing manifest files not a supported strategy as it is for other tools?
    12  //
    13  // `.buckconfig` can be used to discover cells but the `repository` field which
    14  // defines cells is not required .
    15  // `BUCK` files are written in Skylark (a dialect of Python) and are impossible to statically analyze.
    16  // `buck audit` provides json formatted data for dependency and input information.
    17  package okbuck
    18  
    19  import (
    20  	"os"
    21  	"path/filepath"
    22  
    23  	"github.com/apex/log"
    24  	"github.com/mitchellh/mapstructure"
    25  
    26  	"github.com/fossas/fossa-cli/buildtools/okbuck"
    27  	"github.com/fossas/fossa-cli/files"
    28  	"github.com/fossas/fossa-cli/graph"
    29  	"github.com/fossas/fossa-cli/module"
    30  	"github.com/fossas/fossa-cli/pkg"
    31  )
    32  
    33  // Analyzer defines a OkBuck analyzer.
    34  type Analyzer struct {
    35  	Module  module.Module
    36  	Setup   okbuck.OkBuck
    37  	Options Options
    38  }
    39  
    40  // Options sets analyzer options for Go modules.
    41  type Options struct {
    42  	ClassPath string `mapstructure:"classpath"` // Specify the classpath to target for a specific configurations dependencies.
    43  }
    44  
    45  // New constructs a new OkBuck analyzer from a module.
    46  func New(module module.Module) (*Analyzer, error) {
    47  	log.Debugf("%#v", module)
    48  
    49  	// Parse and validate options.
    50  	var options Options
    51  	err := mapstructure.Decode(module.Options, &options)
    52  	if err != nil {
    53  		return nil, err
    54  	}
    55  	log.WithField("options", options).Debug("parsed analyzer options")
    56  
    57  	analyzer := Analyzer{
    58  		Module:  module,
    59  		Setup:   okbuck.New(module.BuildTarget),
    60  		Options: options,
    61  	}
    62  	return &analyzer, nil
    63  }
    64  
    65  // Clean is not implemented.
    66  func (a *Analyzer) Clean() error {
    67  	return nil
    68  }
    69  
    70  // Build is not implemented.
    71  func (a *Analyzer) Build() error {
    72  	return nil
    73  }
    74  
    75  // IsBuilt is not implemented.
    76  func (a *Analyzer) IsBuilt() (bool, error) {
    77  	return true, nil
    78  }
    79  
    80  // Analyze analyzes an OkBuck build target and its dependencies.
    81  func (a *Analyzer) Analyze() (graph.Deps, error) {
    82  	return a.Setup.Deps(a.Options.ClassPath)
    83  }
    84  
    85  // Discover searches for `buckw` executables in the present directory.
    86  func Discover(dir string, opts map[string]interface{}) ([]module.Module, error) {
    87  	var moduleList []module.Module
    88  
    89  	buckWrapper, err := files.Exists(dir, "buckw")
    90  	if err != nil {
    91  		return moduleList, err
    92  	}
    93  	if buckWrapper {
    94  		wd, err := os.Getwd()
    95  		if err != nil {
    96  			return moduleList, err
    97  		}
    98  		moduleList = append(moduleList, newModule(filepath.Base(wd), "//...", "."))
    99  	}
   100  
   101  	return moduleList, nil
   102  }
   103  
   104  func newModule(name, target, dir string) module.Module {
   105  	log.WithFields(log.Fields{
   106  		"path": dir,
   107  		"name": name,
   108  	}).Debug("constructing OkBuck module")
   109  
   110  	return module.Module{
   111  		Name:        name,
   112  		Type:        pkg.OkBuck,
   113  		BuildTarget: target,
   114  		Dir:         dir,
   115  	}
   116  }