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

     1  package nuget
     2  
     3  import (
     4  	"path/filepath"
     5  
     6  	"github.com/apex/log"
     7  
     8  	"github.com/fossas/fossa-cli/buildtools/dotnet"
     9  	"github.com/fossas/fossa-cli/buildtools/paket"
    10  	"github.com/fossas/fossa-cli/files"
    11  	"github.com/fossas/fossa-cli/graph"
    12  )
    13  
    14  // Analyze determines the best way to analyze a .NET project by first looking for
    15  // a pre set strategy and then falling back through a number of methods.
    16  func (a *Analyzer) Analyze() (graph.Deps, error) {
    17  	log.WithField("module", a.Module).Debug("analyzing module")
    18  	dir := Dir(a.Module)
    19  
    20  	// 1. Check for a set strategy.
    21  	switch a.Options.Strategy {
    22  	case "paket":
    23  		return paket.DependencyGraph(a.Module.BuildTarget)
    24  	case "package-reference":
    25  		return dotnet.PackageReferenceGraph(a.Module.BuildTarget)
    26  	case "nuspec":
    27  		return dotnet.NuspecGraph(a.Module.BuildTarget)
    28  	case "package-config":
    29  		return dotnet.ProjectGraph(filepath.Join(dir, "packages.config"))
    30  	case "project-json":
    31  		return dotnet.ProjectGraph(filepath.Join(dir, "project.json"))
    32  	}
    33  
    34  	// 2. Check for Paket.
    35  	// https://fsprojects.github.io/Paket/
    36  	if exists, err := files.Exists(filepath.Join(dir, "paket.lock")); exists && err == nil {
    37  		return paket.DependencyGraph(filepath.Join(dir, "paket.lock"))
    38  	}
    39  
    40  	// 3. Check for `project.assets.json` which is the nuget lockfile.
    41  	// https://docs.microsoft.com/en-us/nuget/consume-packages/dependency-resolution
    42  	if exists, err := files.Exists(filepath.Join(dir, "obj", "project.assets.json")); exists && err == nil {
    43  		depGraph, err := dotnet.ResolveStrategy(a.Module.BuildTarget, a.Module.Dir)
    44  		if returnGraph(a.Module.BuildTarget, err, len(depGraph.Transitive)) {
    45  			return depGraph, nil
    46  		}
    47  	}
    48  
    49  	// 4. Check for a Package Reference file used by NuGet 4.0+.
    50  	// https://docs.microsoft.com/en-us/nuget/consume-packages/package-references-in-project-files
    51  	if dotnet.IsPackageReferenceFile(a.Module.BuildTarget) {
    52  		exists, err := files.Exists(a.Module.BuildTarget)
    53  		if !exists || err != nil {
    54  			log.Warnf("`%s` cannot be read. File exists: %b. Error: %s", a.Module.BuildTarget, exists, err)
    55  		} else {
    56  			depGraph, err := dotnet.PackageReferenceGraph(a.Module.BuildTarget)
    57  			if returnGraph(a.Module.BuildTarget, err, len(depGraph.Transitive)) {
    58  				return depGraph, nil
    59  			}
    60  		}
    61  	}
    62  
    63  	// 5. Check if a nuspec file exists and if it contains dependency information.
    64  	// https://docs.microsoft.com/en-us/nuget/reference/nuspec
    65  	pattern := filepath.Join(a.Module.Dir, "*nuspec")
    66  	fileMatches, err := filepath.Glob(pattern)
    67  	if err == nil && len(fileMatches) > 0 {
    68  		file := fileMatches[0]
    69  		depGraph, err := dotnet.NuspecGraph(file)
    70  		if returnGraph(file, err, len(depGraph.Transitive)) {
    71  			return depGraph, nil
    72  		}
    73  	}
    74  
    75  	// 6. Check for a `packages.config` file.
    76  	// https://docs.microsoft.com/en-us/nuget/reference/packages-config
    77  	if exists, err := files.Exists(filepath.Join(dir, "packages.config")); exists && err == nil {
    78  		file := filepath.Join(dir, "packages.config")
    79  		depGraph, err := dotnet.PackageConfigGraph(file)
    80  		if returnGraph(file, err, len(depGraph.Transitive)) {
    81  			return depGraph, nil
    82  		}
    83  	}
    84  
    85  	// 7. Check for a `project.json` file which was used until NuGet 4.0.
    86  	// https://docs.microsoft.com/en-us/nuget/archive/project-json
    87  	if exists, err := files.Exists(filepath.Join(dir, "project.json")); exists && err == nil {
    88  		file := filepath.Join(dir, "project.json")
    89  		depGraph, err := dotnet.ProjectGraph(file)
    90  		if returnGraph(file, err, len(depGraph.Transitive)) {
    91  			return depGraph, nil
    92  		}
    93  	}
    94  
    95  	return graph.Deps{}, nil
    96  }
    97  
    98  func returnGraph(file string, err error, dependencyCount int) bool {
    99  	if err != nil {
   100  		log.Warnf("Error reading dependencies from `%s`: %s", file, err)
   101  		return false
   102  	}
   103  
   104  	if dependencyCount == 0 {
   105  		log.Warnf("No dependencies were found in `%s`", file)
   106  		return false
   107  	}
   108  	return true
   109  }