From 5d484e27706937b51bd66d533d5c8f752a98c1c3 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Thu, 4 Jun 2015 12:32:23 -0700 Subject: [PATCH] Implement custom date command for cross platform portability --- Makefile | 2 +- buildscripts/date.go | 26 +++++ buildscripts/verifier.go | 247 --------------------------------------- 3 files changed, 27 insertions(+), 248 deletions(-) create mode 100644 buildscripts/date.go delete mode 100644 buildscripts/verifier.go diff --git a/Makefile b/Makefile index 55b110fdf..6e656d46c 100644 --- a/Makefile +++ b/Makefile @@ -49,7 +49,7 @@ minio: pre-build build-all test-all install: minio @echo "Installing minio:" - @godep go install -a -ldflags "-X main.BuildDate `date -u '+%FT%T.%N%:z'`" github.com/minio/minio + @godep go install -a -ldflags "-X main.BuildDate `go run buildscripts/date.go`" github.com/minio/minio save: restore @godep save ./... diff --git a/buildscripts/date.go b/buildscripts/date.go new file mode 100644 index 000000000..d10a5d19e --- /dev/null +++ b/buildscripts/date.go @@ -0,0 +1,26 @@ +/* + * Minio Client (C) 2014, 2015 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package main + +import ( + "fmt" + "time" +) + +func main() { + fmt.Println(time.Now().UTC().Format(time.RFC3339Nano)) +} diff --git a/buildscripts/verifier.go b/buildscripts/verifier.go deleted file mode 100644 index fb730d936..000000000 --- a/buildscripts/verifier.go +++ /dev/null @@ -1,247 +0,0 @@ -package main - -import ( - "flag" - "fmt" - "go/ast" - "go/parser" - "go/token" - "os" - "path/filepath" - "sort" - "strings" -) - -var exitCode int -var dirs []string - -func appendUniq(slice []string, i string) []string { - for _, ele := range slice { - if ele == i { - return slice - } - } - return append(slice, i) -} - -// error formats the error to standard error, adding program -// identification and a newline -func errorf(format string, args ...interface{}) { - fmt.Fprintf(os.Stderr, "verifier: "+format+"\n", args...) - exitCode = 2 -} - -type goPackage struct { - p *ast.Package - fs *token.FileSet - decl map[string]ast.Node - missingcomments map[string]ast.Node - used map[string]bool -} - -type usedWalker goPackage - -// Walks through the AST marking used identifiers. -func (p *usedWalker) Visit(node ast.Node) ast.Visitor { - // just be stupid and mark all *ast.Ident - switch n := node.(type) { - case *ast.Ident: - p.used[n.Name] = true - } - return p -} - -type report struct { - pos token.Pos - name string -} -type reports []report - -// Len -func (l reports) Len() int { return len(l) } - -// Less -func (l reports) Less(i, j int) bool { return l[i].pos < l[j].pos } - -// Swap -func (l reports) Swap(i, j int) { l[i], l[j] = l[j], l[i] } - -// Visits files for used nodes. -func (p *goPackage) Visit(node ast.Node) ast.Visitor { - u := usedWalker(*p) // hopefully p fields are references. - switch n := node.(type) { - // don't walk whole file, but only: - case *ast.ValueSpec: - // - variable initializers - for _, value := range n.Values { - ast.Walk(&u, value) - } - // variable types. - if n.Type != nil { - ast.Walk(&u, n.Type) - } - case *ast.BlockStmt: - // - function bodies - for _, stmt := range n.List { - ast.Walk(&u, stmt) - } - case *ast.FuncDecl: - // - function signatures - ast.Walk(&u, n.Type) - case *ast.TypeSpec: - // - type declarations - ast.Walk(&u, n.Type) - } - return p -} - -func getAllMinioPkgs(path string, fl os.FileInfo, err error) error { - if err != nil { - return err - } - if fl.IsDir() { - // Skip godeps - if strings.Contains(path, "Godeps") { - return nil - } - dirs = appendUniq(dirs, path) - } - return nil -} - -func doDir(name string) { - notests := func(info os.FileInfo) bool { - if !info.IsDir() && strings.HasSuffix(info.Name(), ".go") && - !strings.HasSuffix(info.Name(), "_test.go") { - return true - } - return false - } - fs := token.NewFileSet() - pkgs, err := parser.ParseDir(fs, name, notests, parser.ParseComments|parser.Mode(0)) - if err != nil { - errorf("%s", err) - return - } - for _, pkg := range pkgs { - doPackage(fs, pkg) - } -} - -func doDecl(p *goPackage, decl interface{}, cmap ast.CommentMap) bool { - switch n := decl.(type) { - case *ast.GenDecl: - // var, const, types - for _, spec := range n.Specs { - switch s := spec.(type) { - case *ast.ValueSpec: - // constants and variables. - for _, name := range s.Names { - p.decl[name.Name] = n - } - case *ast.TypeSpec: - // type definitions. - p.decl[s.Name.Name] = n - } - } - case *ast.FuncDecl: - // if function is 'main', never check - if n.Name.Name == "main" { - return true - } - // Do not be strict on non-exported functions - if !ast.IsExported(n.Name.Name) { - return true - } - // Do not be strict for field list functions - // if n.Recv != nil { - // continue - //} - // Be strict for global functions - _, ok := cmap[n] - if ok == false { - p.missingcomments[n.Name.Name] = n - } - - // function declarations - // TODO(remy): do methods - if n.Recv == nil { - p.decl[n.Name.Name] = n - } - } - return false -} - -func doPackage(fs *token.FileSet, pkg *ast.Package) { - p := &goPackage{ - p: pkg, - fs: fs, - decl: make(map[string]ast.Node), - missingcomments: make(map[string]ast.Node), - used: make(map[string]bool), - } - for _, file := range pkg.Files { - cmap := ast.NewCommentMap(fs, file, file.Comments) - for _, decl := range file.Decls { - if doDecl(p, decl, cmap) { - continue - } - } - } - // init() is always used - p.used["init"] = true - if pkg.Name != "main" { - // exported names are marked used for non-main packages. - for name := range p.decl { - if ast.IsExported(name) { - p.used[name] = true - } - } - } else { - // in main programs, main() is called. - p.used["main"] = true - } - for _, file := range pkg.Files { - // walk file looking for used nodes. - ast.Walk(p, file) - } - - // reports. - reports := reports(nil) - for name, node := range p.decl { - if !p.used[name] { - reports = append(reports, report{node.Pos(), name}) - } - } - sort.Sort(reports) - for _, report := range reports { - errorf("%s: %s is unused", fs.Position(report.pos), report.name) - } - - for name, node := range p.missingcomments { - errorf("%s: comment is missing for 'func %s'", fs.Position(node.Pos()), name) - } -} - -func main() { - flag.Parse() - if flag.NArg() == 0 { - doDir(".") - } else { - for _, name := range flag.Args() { - // Is it a directory? - if fi, err := os.Stat(name); err == nil && fi.IsDir() { - err := filepath.Walk(name, getAllMinioPkgs) - if err != nil { - errorf(err.Error()) - } - for _, dir := range dirs { - doDir(dir) - } - } else { - errorf("not a directory: %s", name) - } - } - } - os.Exit(exitCode) -}