diff --git a/.gitignore b/.gitignore index 3575102..bf8b345 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ .linguist benchmarks/output +.ci +Makefile.main diff --git a/Makefile b/Makefile index 238674f..d17633b 100644 --- a/Makefile +++ b/Makefile @@ -1,32 +1,36 @@ -COVERAGE_REPORT := coverage.txt -COVERAGE_PROFILE := profile.out -COVERAGE_MODE := atomic +# Package configuration +PROJECT = enry +COMMANDS = cli/enry + +# Including ci Makefile +MAKEFILE = Makefile.main +CI_REPOSITORY = https://github.com/src-d/ci.git +CI_FOLDER = .ci + +# If you need to build more than one dockerfile, you can do so like this: +# DOCKERFILES = Dockerfile_filename1:repositoryname1 Dockerfile_filename2:repositoryname2 ... + +$(MAKEFILE): + @git clone --quiet $(CI_REPOSITORY) $(CI_FOLDER); \ + cp $(CI_FOLDER)/$(MAKEFILE) .; + +-include $(MAKEFILE) LINGUIST_PATH = .linguist # build CLI -VERSION := $(shell git describe --tags --abbrev=0) -COMMIT := $(shell git rev-parse --short HEAD) -LDFLAGS = -s -X main.Version=$(VERSION) -X main.GitHash=$(COMMIT) +LOCAL_TAG := $(shell git describe --tags --abbrev=0) +LOCAL_COMMIT := $(shell git rev-parse --short HEAD) +LOCAL_BUILD := $(shell date +"%m-%d-%Y_%H_%M_%S") +LOCAL_LDFLAGS = -s -X main.version=$(LOCAL_TAG) -X main.build=$(LOCAL_BUILD) -X main.commit=$(LOCAL_COMMIT) $(LINGUIST_PATH): git clone https://github.com/github/linguist.git $@ -test: $(LINGUIST_PATH) - go test -v ./... +clean-linguist: + rm -rf $(LINGUIST_PATH) -test-coverage: $(LINGUIST_PATH) - @echo "mode: $(COVERAGE_MODE)" > $(COVERAGE_REPORT); \ - for dir in `find . -name "*.go" | grep -o '.*/' | sort -u | grep -v './fixtures/' | grep -v './.linguist/'`; do \ - go test $$dir -coverprofile=$(COVERAGE_PROFILE) -covermode=$(COVERAGE_MODE); \ - if [ $$? != 0 ]; then \ - exit 2; \ - fi; \ - if [ -f $(COVERAGE_PROFILE) ]; then \ - tail -n +2 $(COVERAGE_PROFILE) >> $(COVERAGE_REPORT); \ - rm $(COVERAGE_PROFILE); \ - fi; \ - done; +clean: clean-linguist code-generate: $(LINGUIST_PATH) mkdir -p data @@ -42,8 +46,5 @@ benchmarks-slow: $(LINGUST_PATH) mkdir -p benchmarks/output && go test -run=NONE -bench=. -slow -benchtime=100ms -timeout=100h >benchmarks/output/enry_samples.bench && \ benchmarks/linguist-samples.rb 5 >benchmarks/output/linguist_samples.bench -clean: - rm -rf $(LINGUIST_PATH) - build-cli: - go build -o enry -ldflags "$(LDFLAGS)" cli/enry/main.go + go build -o enry -ldflags "$(LOCAL_LDFLAGS)" cli/enry/main.go diff --git a/benchmark_test.go b/benchmark_test.go index 451b2ef..9ad8289 100644 --- a/benchmark_test.go +++ b/benchmark_test.go @@ -5,11 +5,12 @@ import ( "io/ioutil" "log" "os" + "os/exec" "path/filepath" "testing" -) -const samplesDir = ".linguist/samples" + "gopkg.in/src-d/enry.v1/data" +) type sample struct { filename string @@ -21,18 +22,62 @@ var ( overcomeLanguage string overcomeLanguages []string samples []*sample + samplesDir string ) func TestMain(m *testing.M) { + var exitCode int + defer os.Exit(exitCode) + flag.BoolVar(&slow, "slow", false, "run benchmarks per sample for strategies too") flag.Parse() + + if err := cloneLinguist(linguistURL); err != nil { + log.Fatal(err) + } + defer os.RemoveAll(filepath.Dir(samplesDir)) + var err error samples, err = getSamples(samplesDir) if err != nil { log.Fatal(err) } - os.Exit(m.Run()) + exitCode = m.Run() +} + +func cloneLinguist(linguistURL string) error { + repoLinguist, err := ioutil.TempDir("", "linguist-") + if err != nil { + return err + } + + samplesDir = filepath.Join(repoLinguist, "samples") + + cmd := exec.Command("git", "clone", linguistURL, repoLinguist) + if err := cmd.Run(); err != nil { + return err + } + + cwd, err := os.Getwd() + if err != nil { + return err + } + + if err = os.Chdir(repoLinguist); err != nil { + return err + } + + cmd = exec.Command("git", "checkout", data.LinguistCommit) + if err := cmd.Run(); err != nil { + return err + } + + if err = os.Chdir(cwd); err != nil { + return err + } + + return nil } func getSamples(dir string) ([]*sample, error) { diff --git a/cli/enry/main.go b/cli/enry/main.go index b48b27c..ec40af6 100644 --- a/cli/enry/main.go +++ b/cli/enry/main.go @@ -14,8 +14,9 @@ import ( ) var ( - Version = "undefined" - GitHash = "undefined" + version = "undefined" + build = "undefined" + commit = "undefined" ) func main() { @@ -111,13 +112,13 @@ func main() { func usage() { fmt.Fprintf( os.Stderr, - ` %[1]s %[2]s commit: %[3]s - enry, A simple (and faster) implementation of github/linguist + ` %[1]s %[2]s build: %[3]s commit: %[4]s + %[1]s, A simple (and faster) implementation of github/linguist usage: %[1]s %[1]s [-json] [-breakdown] %[1]s [-json] [-breakdown] `, - os.Args[0], Version, GitHash, + os.Args[0], version, build, commit, ) } diff --git a/common_test.go b/common_test.go index 208767d..6e83115 100644 --- a/common_test.go +++ b/common_test.go @@ -19,6 +19,7 @@ const linguistURL = "https://github.com/github/linguist.git" type EnryTestSuite struct { suite.Suite repoLinguist string + samplesDir string } func TestEnryTestSuite(t *testing.T) { @@ -30,6 +31,8 @@ func (s *EnryTestSuite) SetupSuite() { s.repoLinguist, err = ioutil.TempDir("", "linguist-") assert.NoError(s.T(), err) + s.samplesDir = filepath.Join(s.repoLinguist, "samples") + cmd := exec.Command("git", "clone", linguistURL, s.repoLinguist) err = cmd.Run() assert.NoError(s.T(), err) @@ -74,10 +77,7 @@ func (s *EnryTestSuite) TestGetLanguage() { } func (s *EnryTestSuite) TestGetLanguagesByModelineLinguist() { - const ( - modelinesDir = ".linguist/test/fixtures/Data/Modelines" - samplesDir = ".linguist/samples" - ) + var modelinesDir = filepath.Join(s.repoLinguist, "test/fixtures/Data/Modelines") tests := []struct { name string @@ -118,7 +118,7 @@ func (s *EnryTestSuite) TestGetLanguagesByModelineLinguist() { {name: "TestGetLanguagesByModelineLinguist_28", filename: filepath.Join(modelinesDir, "ruby10"), expected: []string{"Ruby"}}, {name: "TestGetLanguagesByModelineLinguist_29", filename: filepath.Join(modelinesDir, "ruby11"), expected: []string{"Ruby"}}, {name: "TestGetLanguagesByModelineLinguist_30", filename: filepath.Join(modelinesDir, "ruby12"), expected: []string{"Ruby"}}, - {name: "TestGetLanguagesByModelineLinguist_31", filename: filepath.Join(samplesDir, "C/main.c"), expected: nil}, + {name: "TestGetLanguagesByModelineLinguist_31", filename: filepath.Join(s.samplesDir, "C/main.c"), expected: nil}, } for _, test := range tests { @@ -240,19 +240,18 @@ func (s *EnryTestSuite) TestGetLanguagesByExtension() { } func (s *EnryTestSuite) TestGetLanguagesByClassifier() { - const samples = `.linguist/samples/` test := []struct { name string filename string candidates []string expected string }{ - {name: "TestGetLanguagesByClassifier_1", filename: filepath.Join(samples, "C/blob.c"), candidates: []string{"python", "ruby", "c", "c++"}, expected: "C"}, - {name: "TestGetLanguagesByClassifier_2", filename: filepath.Join(samples, "C/blob.c"), candidates: nil, expected: OtherLanguage}, - {name: "TestGetLanguagesByClassifier_3", filename: filepath.Join(samples, "C/main.c"), candidates: []string{}, expected: OtherLanguage}, - {name: "TestGetLanguagesByClassifier_4", filename: filepath.Join(samples, "C/blob.c"), candidates: []string{"python", "ruby", "c++"}, expected: "C++"}, - {name: "TestGetLanguagesByClassifier_5", filename: filepath.Join(samples, "C/blob.c"), candidates: []string{"ruby"}, expected: "Ruby"}, - {name: "TestGetLanguagesByClassifier_6", filename: filepath.Join(samples, "Python/django-models-base.py"), candidates: []string{"python", "ruby", "c", "c++"}, expected: "Python"}, + {name: "TestGetLanguagesByClassifier_1", filename: filepath.Join(s.samplesDir, "C/blob.c"), candidates: []string{"python", "ruby", "c", "c++"}, expected: "C"}, + {name: "TestGetLanguagesByClassifier_2", filename: filepath.Join(s.samplesDir, "C/blob.c"), candidates: nil, expected: OtherLanguage}, + {name: "TestGetLanguagesByClassifier_3", filename: filepath.Join(s.samplesDir, "C/main.c"), candidates: []string{}, expected: OtherLanguage}, + {name: "TestGetLanguagesByClassifier_4", filename: filepath.Join(s.samplesDir, "C/blob.c"), candidates: []string{"python", "ruby", "c++"}, expected: "C++"}, + {name: "TestGetLanguagesByClassifier_5", filename: filepath.Join(s.samplesDir, "C/blob.c"), candidates: []string{"ruby"}, expected: "Ruby"}, + {name: "TestGetLanguagesByClassifier_6", filename: filepath.Join(s.samplesDir, "Python/django-models-base.py"), candidates: []string{"python", "ruby", "c", "c++"}, expected: "Python"}, } for _, test := range test { @@ -272,7 +271,6 @@ func (s *EnryTestSuite) TestGetLanguagesByClassifier() { } func (s *EnryTestSuite) TestGetLanguagesBySpecificClassifier() { - const samples = `.linguist/samples/` test := []struct { name string filename string @@ -280,12 +278,12 @@ func (s *EnryTestSuite) TestGetLanguagesBySpecificClassifier() { classifier Classifier expected string }{ - {name: "TestGetLanguagesByClassifier_1", filename: filepath.Join(samples, "C/blob.c"), candidates: []string{"python", "ruby", "c", "c++"}, classifier: DefaultClassifier, expected: "C"}, - {name: "TestGetLanguagesByClassifier_2", filename: filepath.Join(samples, "C/blob.c"), candidates: nil, classifier: DefaultClassifier, expected: "C"}, - {name: "TestGetLanguagesByClassifier_3", filename: filepath.Join(samples, "C/main.c"), candidates: []string{}, classifier: DefaultClassifier, expected: "C"}, - {name: "TestGetLanguagesByClassifier_4", filename: filepath.Join(samples, "C/blob.c"), candidates: []string{"python", "ruby", "c++"}, classifier: DefaultClassifier, expected: "C++"}, - {name: "TestGetLanguagesByClassifier_5", filename: filepath.Join(samples, "C/blob.c"), candidates: []string{"ruby"}, classifier: DefaultClassifier, expected: "Ruby"}, - {name: "TestGetLanguagesByClassifier_6", filename: filepath.Join(samples, "Python/django-models-base.py"), candidates: []string{"python", "ruby", "c", "c++"}, classifier: DefaultClassifier, expected: "Python"}, + {name: "TestGetLanguagesByClassifier_1", filename: filepath.Join(s.samplesDir, "C/blob.c"), candidates: []string{"python", "ruby", "c", "c++"}, classifier: DefaultClassifier, expected: "C"}, + {name: "TestGetLanguagesByClassifier_2", filename: filepath.Join(s.samplesDir, "C/blob.c"), candidates: nil, classifier: DefaultClassifier, expected: "C"}, + {name: "TestGetLanguagesByClassifier_3", filename: filepath.Join(s.samplesDir, "C/main.c"), candidates: []string{}, classifier: DefaultClassifier, expected: "C"}, + {name: "TestGetLanguagesByClassifier_4", filename: filepath.Join(s.samplesDir, "C/blob.c"), candidates: []string{"python", "ruby", "c++"}, classifier: DefaultClassifier, expected: "C++"}, + {name: "TestGetLanguagesByClassifier_5", filename: filepath.Join(s.samplesDir, "C/blob.c"), candidates: []string{"ruby"}, classifier: DefaultClassifier, expected: "Ruby"}, + {name: "TestGetLanguagesByClassifier_6", filename: filepath.Join(s.samplesDir, "Python/django-models-base.py"), candidates: []string{"python", "ruby", "c", "c++"}, classifier: DefaultClassifier, expected: "Python"}, {name: "TestGetLanguagesByClassifier_6", filename: os.DevNull, candidates: nil, classifier: DefaultClassifier, expected: OtherLanguage}, } @@ -373,14 +371,13 @@ func (s *EnryTestSuite) TestGetLanguageByAlias() { func (s *EnryTestSuite) TestLinguistCorpus() { const filenamesDir = "filenames" - var samplesDir = filepath.Join(s.repoLinguist, "samples") var cornerCases = map[string]bool{ "hello.ms": true, } var total, failed, ok, other int var expected string - filepath.Walk(samplesDir, func(path string, f os.FileInfo, err error) error { + filepath.Walk(s.samplesDir, func(path string, f os.FileInfo, err error) error { if f.IsDir() { if f.Name() != filenamesDir { expected = f.Name()