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  }