Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
elldritch committed Jun 7, 2018
1 parent e8bfc5c commit 1c6c5e8
Show file tree
Hide file tree
Showing 68 changed files with 1,250 additions and 936 deletions.
File renamed without changes.
30 changes: 14 additions & 16 deletions builders/builder.go → .builders/builder.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package builders

import (
"github.com/fossas/fossa-cli/module"

"github.com/fossas/fossa-cli/builders/ant"
"github.com/fossas/fossa-cli/builders/archive"
"github.com/fossas/fossa-cli/builders/bower"
Expand All @@ -19,33 +17,33 @@ import (
)

// New instantiates a Builder given a ModuleType
func New(moduleType module.Type) module.Builder {
func New(moduleType pkg.Type) pkg.Builder {
switch moduleType {
case module.Ant:
case pkg.Ant:
return &ant.AntBuilder{}
case module.Bower:
case pkg.Bower:
return &bower.BowerBuilder{}
case module.Cocoapods:
case pkg.Cocoapods:
return &cocoapods.CocoapodsBuilder{}
case module.Composer:
case pkg.Composer:
return &php.ComposerBuilder{}
case module.Golang:
case pkg.Golang:
return &golang.GoBuilder{}
case module.Gradle:
case pkg.Gradle:
return &gradle.GradleBuilder{}
case module.Maven:
case pkg.Maven:
return &maven.MavenBuilder{}
case module.Nodejs:
case pkg.Nodejs:
return &nodejs.NodeJSBuilder{}
case module.NuGet:
case pkg.NuGet:
return &nuget.NuGetBuilder{}
case module.Pip:
case pkg.Pip:
return &python.PipBuilder{}
case module.Ruby:
case pkg.Ruby:
return &ruby.RubyBuilder{}
case module.SBT:
case pkg.SBT:
return &scala.SBTBuilder{}
case module.VendoredArchives:
case pkg.VendoredArchives:
return &archive.VendoredArchiveBuilder{}
}
return nil
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
166 changes: 166 additions & 0 deletions .config/file.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
package config

import (
"fmt"
"io/ioutil"
"os"
"strings"

"github.com/fossas/fossa-cli/module"
git "gopkg.in/src-d/go-git.v4"
yaml "gopkg.in/yaml.v2"
)

type configFileV1 struct {
Version int `yaml:"version"`

CLI configFileCLIV1
Analyze configFileAnalyzeV1
}

type configFileCLIV1 struct {
// Upload configuration.
APIKey string `yaml:"api_key,omitempty"`
Server string `yaml:"server,omitempty"`
Fetcher string `yaml:"fetcher,omitempty"` // Defaults to custom
Project string `yaml:"project,omitempty"`
Revision string `yaml:"revision,omitempty"`
Branch string `yaml:"branch,omitempty"` // Only used with custom fetcher
}

type configFileAnalyzeV1 struct {
Modules []module.Config `yaml:"modules,omitempty"`
}

func readConfigFile(path string) (string, configFileV1, error) {
if _, err := os.Stat(path); path != "" && err != nil && os.IsNotExist(err) {
return path, configFileV1{}, fmt.Errorf("invalid config file specified")
} else if _, err := os.Stat(".fossa.yml"); err == nil {
path = ".fossa.yml"
} else if _, err = os.Stat(".fossa.yaml"); err == nil {
path = ".fossa.yaml"
}

if path == "" {
conf, err := setDefaultValues(configFileV1{})
return path, conf, err
}
conf, err := parseConfigFile(path)
return path, conf, err
}

func parseConfigFile(filename string) (configFileV1, error) {
// Read configuration file.
var config configFileV1

bytes, err := ioutil.ReadFile(filename)
if err != nil {
return config, err
}

err = yaml.Unmarshal(bytes, &config)
if err != nil {
return config, err
}

config, err = setDefaultValues(config)
if err != nil {
return config, err
}

return config, nil
}

func setDefaultValues(c configFileV1) (configFileV1, error) {
// Set config version
c.Version = 1

// Set default endpoint.
endpoint := os.Getenv("FOSSA_ENDPOINT")
if endpoint != "" {
c.CLI.Server = endpoint
}
if c.CLI.Server == "" {
c.CLI.Server = "https://app.fossa.io"
}

// Load API key from environment variable.
apiKey := os.Getenv("FOSSA_API_KEY")
if apiKey != "" {
c.CLI.APIKey = apiKey
}

// Default to custom.
if c.CLI.Fetcher == "" {
c.CLI.Fetcher = "custom"
}

// Infer default locator and project from `git`.
if c.CLI.Project == "" || c.CLI.Revision == "" || c.CLI.Branch == "" {
// TODO: this needs to happen in the module directory, not the working
// directory
repo, err := git.PlainOpen(".")
if err == nil {
if c.CLI.Project == "" {
origin, err := repo.Remote("origin")
if err == nil && origin != nil {
c.CLI.Project = origin.Config().URLs[0]
}
}
if c.CLI.Revision == "" {
revision, err := repo.Head()
if err == nil {
c.CLI.Revision = revision.Hash().String()
}
}
if c.CLI.Branch == "" {
revision, err := repo.Head()
if err == nil {
c.CLI.Revision = revision.Hash().String()
}
c.CLI.Branch = revision.Name().String()
}
}
}

return c, nil
}

// WriteConfigFile writes a config state to yaml
func WriteConfigFile(conf *CLIConfig) error {
if conf.ConfigFilePath == "" {
conf.ConfigFilePath = ".fossa.yml"
}

keyToWrite := ""
if os.Getenv("FOSSA_API_KEY") == "" {
keyToWrite = conf.APIKey
}

writeConfig := configFileV1{
Version: 1,
CLI: configFileCLIV1{
APIKey: keyToWrite,
Server: conf.Endpoint,
Project: conf.Project,
Fetcher: conf.Fetcher,
},
Analyze: configFileAnalyzeV1{
Modules: conf.Modules,
},
}
yamlConfig, err := yaml.Marshal(writeConfig)
if err != nil {
return err
}

configHeader := []byte(
strings.Join([]string{
"# Generated by FOSSA CLI (https://github.com/fossas/fossa-cli)",
"# Visit https://fossa.io to learn more",
"",
"",
}, "\n"))

return ioutil.WriteFile(conf.ConfigFilePath, append(configHeader, yamlConfig...), 0777)
}
File renamed without changes.
File renamed without changes.
5 changes: 3 additions & 2 deletions .fossa.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
# Generated by FOSSA CLI (https://github.com/fossas/fossa-cli)
# Visit https://fossa.io to learn more

version: 1
cli:
server: https://app.fossa.io
project: git@github.com:fossas/fossa-cli.git
fetcher: git
project: git@github.com:fossas/fossa-cli.git
analyze:
modules:
- name: fossa
path: cmd/fossa
type: go
type: Go
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
105 changes: 105 additions & 0 deletions .module/module.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package module

import (
"os"
"path/filepath"
"strings"
)

// A Module is a unit of buildable code within a project.
type Module struct {
Name string
Type Type

// Target is the entry point or manifest path for the build system. The exact
// meaning is Type-dependent.
Target string
// Dir is the absolute path to the module's working directory (the directory
// you would normally run the build command from).
Dir string

// Different modules in a monolith may correspond to different FOSSA projects
// or revisions.
// TODO: use these values.
Project string
Revision string

// A catch-all for builders to add metadata (a la Context.Value).
Context interface{}
}

// New instantiates and sets up a Module for a given ModuleType
func New(moduleType Type, conf Config) (Module, error) {
var manifestName string
var moduleTarget string

// Find root dir of module
modulePath, err := filepath.Abs(conf.Path)
if err != nil {
return Module{}, err
}

// infer default module settings from type
switch moduleType {
case Ant:
manifestName = "build.xml"
break
case Bower:
manifestName = "bower.json"
break
case Cocoapods:
manifestName = "Podfile"
break
case Composer:
manifestName = "composer.json"
break
case Golang:
manifestName = ""
moduleTarget = strings.TrimPrefix(modulePath, filepath.Join(os.Getenv("GOPATH"), "src")+"/")
break
case Maven:
manifestName = "pom.xml"
break
case Nodejs:
manifestName = "package.json"
break
case NuGet:
moduleTarget = modulePath
modulePath = filepath.Dir(modulePath)
break
case Pip:
manifestName = "requirements.txt"
break
case Ruby:
manifestName = "Gemfile"
break
case SBT:
manifestName = "build.sbt"
break
case VendoredArchives:
manifestName = ""
break
}

// trim manifest from path
if filepath.Base(modulePath) == manifestName {
modulePath = filepath.Dir(modulePath)
}

moduleName := conf.Name
if moduleName == "" {
moduleName = conf.Path
}

if moduleTarget == "" {
moduleTarget = filepath.Join(modulePath, manifestName)
}

return Module{
Name: moduleName,
Type: moduleType,
Target: moduleTarget,
Dir: modulePath,
Context: conf.Options,
}, nil
}
File renamed without changes.
9 changes: 4 additions & 5 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
{
"files.watcherExclude": {
"**/.git/objects/**": true,
"**/.git/subtree-cache/**": true,
"**/node_modules/**": true,
"text/fixtures/*/**": true,
"**/.git/**": true,
"**/.git/": true,
"testdata/fixtures/**": true,
"vendor/**": true
}
}
}
15 changes: 9 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
BIN="$(shell go env GOPATH)/bin"
DEP="$(BIN)/dep"
GO_BINDATA="$(BIN)/go-bindata"
STRINGER="$(BIN)/stringer"
PREFIX?=/usr/local/bin
LDFLAGS:=-ldflags '-X github.com/fossas/fossa-cli/cmd/fossa/version.version=$(shell git rev-parse --abbrev-ref HEAD) -X github.com/fossas/fossa-cli/cmd/fossa/version.commit=$(shell git rev-parse HEAD) -X "github.com/fossas/fossa-cli/cmd/fossa/version.goversion=$(shell go version)" -X github.com/fossas/fossa-cli/cmd/fossa/version.buildType=development'

all: build

$(DEP): ## Grab golang/dep utility
$(DEP):
go get github.com/golang/dep/cmd/dep

$(GO_BINDATA):
go get -u github.com/go-bindata/go-bindata/...
go get github.com/go-bindata/go-bindata/...

$(STRINGER):
go get golang.org/x/tools/cmd/stringer

.PHONY: build
build: $(BIN)/fossa

$(BIN)/fossa: $(GO_BINDATA)
mkdir -p $$(dirname $@)
$< -pkg bindata -o builders/python/bindata/bindata.go builders/python/bindata/pipdeptree.py
$(BIN)/fossa: $(GO_BINDATA) $(STRINGER)
go generate ./...
go build -o $@ $(LDFLAGS) github.com/fossas/fossa-cli/cmd/fossa

$(PREFIX)/fossa: $(BIN)/fossa
Expand All @@ -38,4 +41,4 @@ clean:
rm -f $(BIN)/fossa

# TODO: release task that builds and deploys in the Dockerfile?
# TODO: test task that runs in Dockerfile?
# TODO: test task that runs in Dockerfile?

0 comments on commit 1c6c5e8

Please sign in to comment.