github.com/joey-fossa/fossa-cli@v0.7.34-0.20190708193710-569f1e8679f0/testing/fixtures/fixtures.go (about) 1 package fixtures 2 3 import ( 4 "os" 5 "path/filepath" 6 "sync" 7 8 "github.com/apex/log" 9 git "gopkg.in/src-d/go-git.v4" 10 "gopkg.in/src-d/go-git.v4/plumbing" 11 12 "github.com/fossas/fossa-cli/files" 13 ) 14 15 // Project describes how to download, build, and analyse a fixture. 16 type Project struct { 17 Name string 18 URL string 19 Commit string 20 // Ref points to a particular reference. It will always be preferred over Commit 21 Ref string 22 ModuleOptions map[string]interface{} 23 Env map[string]string 24 } 25 26 // Directory returns the path to test fixtures. 27 func Directory() string { 28 return filepath.Join(os.TempDir(), "fossa-cli-fixtures") 29 } 30 31 // ProjectInitializer defines how a single project should be initialized after 32 // it has been cloned. 33 type ProjectInitializer func(p Project, projectDir string) error 34 35 // Initialize clones and initializes a fixture into a directory. 36 func Initialize(baseDir string, projects []Project, initializer ProjectInitializer) { 37 // Exit early when fixtures already exist. 38 // This is a bit scary since we don't validate whether the fixtures are 39 // correct, but corrupted fixtures should cause erratic test failures. If we 40 // wanted to validate fixtures, we might want to store e.g. a hash of the 41 // fixture contents and verify against that (or validate the commit of the Git 42 // repositories). 43 baseDirExists, err := files.ExistsFolder(baseDir) 44 if err == nil && baseDirExists { 45 log.Debug(baseDir + " already exists, assuming fixtures OK") 46 return 47 } 48 49 // Make the fixtures directory. 50 err = os.MkdirAll(baseDir, os.FileMode(0700)) 51 if err != nil { 52 panic(err) 53 } 54 55 // Clone and initialize in parallel. 56 var waitGroup sync.WaitGroup 57 waitGroup.Add(len(projects)) 58 for _, p := range projects { 59 go func(project Project) { 60 defer waitGroup.Done() 61 62 projectDir := filepath.Join(baseDir, project.Name) 63 if project.Ref != "" { 64 _, err := git.PlainClone(projectDir, false, &git.CloneOptions{ 65 URL: project.URL, 66 Depth: 1, 67 RecurseSubmodules: 1, 68 ReferenceName: plumbing.ReferenceName(project.Ref), 69 SingleBranch: true, 70 }) 71 if err != nil { 72 panic(err) 73 } 74 } else { 75 repo, err := git.PlainClone(projectDir, false, &git.CloneOptions{ 76 URL: project.URL, 77 RecurseSubmodules: 1, 78 }) 79 if err != nil { 80 panic(err) 81 } 82 83 worktree, err := repo.Worktree() 84 if err != nil { 85 panic(err) 86 } 87 err = worktree.Checkout(&git.CheckoutOptions{ 88 Hash: plumbing.NewHash(project.Commit), 89 }) 90 if err != nil { 91 panic(err) 92 } 93 } 94 95 err = initializer(project, projectDir) 96 if err != nil { 97 panic(err) 98 } 99 }(p) 100 } 101 102 waitGroup.Wait() 103 }