github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/atc/exec/build/repository.go (about) 1 package build 2 3 import ( 4 "sync" 5 6 "github.com/pf-qiu/concourse/v6/atc/runtime" 7 ) 8 9 // ArtifactName is just a string, with its own type to make interfaces using it 10 // more self-documenting. 11 type ArtifactName string 12 13 // Repository is the mapping from a ArtifactName to an Artifact. 14 // Steps will both populate this map with new artifacts (e.g. the resource 15 // fetched by a Get step), and look up required artifacts (e.g. the inputs 16 // configured for a Task step). 17 // 18 // There is only one ArtifactRepository for the duration of a build plan's 19 // execution. 20 // 21 type Repository struct { 22 repo map[ArtifactName]runtime.Artifact 23 repoL sync.RWMutex 24 25 parent *Repository 26 } 27 28 // NewArtifactRepository constructs a new repository. 29 func NewRepository() *Repository { 30 return &Repository{ 31 repo: make(map[ArtifactName]runtime.Artifact), 32 } 33 } 34 35 //go:generate counterfeiter . RegisterableArtifact 36 // A RegisterableArtifact is an Artifact which can be added to the registry 37 type RegisterableArtifact interface { 38 runtime.Artifact 39 } 40 41 // RegisterArtifact inserts an RegisterableArtifact into the map under the given 42 // ArtifactName. Producers of artifacts, e.g. the Get step and the Task step, 43 // will call this after they've successfully produced their artifact(s). 44 func (repo *Repository) RegisterArtifact(name ArtifactName, artifact RegisterableArtifact) { 45 repo.repoL.Lock() 46 repo.repo[name] = artifact 47 repo.repoL.Unlock() 48 } 49 50 // SourceFor looks up a Source for the given ArtifactName. Consumers of 51 // artifacts, e.g. the Task step, will call this to locate their dependencies. 52 func (repo *Repository) ArtifactFor(name ArtifactName) (runtime.Artifact, bool) { 53 repo.repoL.RLock() 54 artifact, found := repo.repo[name] 55 repo.repoL.RUnlock() 56 if !found && repo.parent != nil { 57 artifact, found = repo.parent.ArtifactFor(name) 58 } 59 return artifact, found 60 } 61 62 // AsMap extracts the current contents of the ArtifactRepository into a new map 63 // and returns it. Changes to the returned map or the ArtifactRepository will not 64 // affect each other. 65 func (repo *Repository) AsMap() map[ArtifactName]runtime.Artifact { 66 result := make(map[ArtifactName]runtime.Artifact) 67 68 if repo.parent != nil { 69 for name, artifact := range repo.parent.AsMap() { 70 result[name] = artifact 71 } 72 } 73 74 repo.repoL.RLock() 75 for name, artifact := range repo.repo { 76 result[name] = artifact 77 } 78 repo.repoL.RUnlock() 79 80 return result 81 } 82 83 func (repo *Repository) NewLocalScope() *Repository { 84 child := NewRepository() 85 child.parent = repo 86 return child 87 } 88 89 func (repo *Repository) Parent() *Repository { 90 return repo.parent 91 }