Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix up --verbose #83

Merged
merged 1 commit into from
Feb 28, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 55 additions & 50 deletions pkg/hash_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func (thc *TargetHashCache) Hash(labelAndConfiguration LabelAndConfiguration) ([
if !ok {
if thc.frozen {
thc.cacheLock.Unlock()
return nil, notComputedBeforeFrozen
return nil, fmt.Errorf("didn't have cache entry for label %s: %w", labelAndConfiguration.Label, notComputedBeforeFrozen)
}
thc.cache[labelAndConfiguration.Label] = make(map[Configuration]*cacheEntry)
}
Expand All @@ -110,7 +110,7 @@ func (thc *TargetHashCache) Hash(labelAndConfiguration LabelAndConfiguration) ([
defer entry.hashLock.Unlock()
if entry.hash == nil {
if thc.frozen {
return nil, notComputedBeforeFrozen
return nil, fmt.Errorf("didn't have cache value for label %s in configuration %s: %w", labelAndConfiguration.Label, labelAndConfiguration.Configuration, notComputedBeforeFrozen)
}
hash, err := hashTarget(thc, labelAndConfiguration)
if err != nil {
Expand Down Expand Up @@ -294,17 +294,21 @@ func WalkDiffs(before *TargetHashCache, after *TargetHashCache, labelAndConfigur
}
}

ruleInputLabelsBefore, labelsToKnownConfigurationsBefore, err := indexRuleInputs(before, ruleBefore)
ruleInputLabelsAndConfigurationsBefore, err := getConfiguredRuleInputs(before, ruleBefore, labelAndConfiguration.Configuration)
if err != nil {
return nil, err
}
ruleInputLabelsAfter, labelsToKnownConfigurationsAfter, err := indexRuleInputs(after, ruleAfter)
ruleInputLabelsToConfigurationsBefore := indexByLabel(ruleInputLabelsAndConfigurationsBefore)

ruleInputLabelsAndConfigurationsAfter, err := getConfiguredRuleInputs(after, ruleAfter, labelAndConfiguration.Configuration)
if err != nil {
return nil, err
}
ruleInputLabelsToConfigurationsAfter := indexByLabel(ruleInputLabelsAndConfigurationsAfter)

for _, ruleInputLabel := range ruleInputLabelsAfter.SortedSlice() {
if !ruleInputLabelsBefore.Contains(ruleInputLabel) {
for _, ruleInputLabelAndConfigurations := range ruleInputLabelsAndConfigurationsAfter {
ruleInputLabel := ruleInputLabelAndConfigurations.Label
if _, ok := ruleInputLabelsToConfigurationsBefore[ruleInputLabel]; !ok {
differences = append(differences, Difference{
Category: "RuleInputAdded",
Key: ruleInputLabel.String(),
Expand All @@ -314,8 +318,8 @@ func WalkDiffs(before *TargetHashCache, after *TargetHashCache, labelAndConfigur
// query information, so we could filter away e.g. host changes when we only have a target dep.
// Unfortunately, Bazel doesn't currently expose this.
// See https://github.com/bazelbuild/bazel/issues/14610#issuecomment-1024460141
knownConfigurationsBefore := labelsToKnownConfigurationsBefore[ruleInputLabel]
knownConfigurationsAfter := labelsToKnownConfigurationsAfter[ruleInputLabel]
knownConfigurationsBefore := ruleInputLabelsToConfigurationsBefore[ruleInputLabel]
knownConfigurationsAfter := ruleInputLabelsToConfigurationsAfter[ruleInputLabel]

for _, knownConfigurationAfter := range knownConfigurationsAfter.SortedSlice() {
if knownConfigurationsBefore.Contains(knownConfigurationAfter) {
Expand Down Expand Up @@ -352,8 +356,9 @@ func WalkDiffs(before *TargetHashCache, after *TargetHashCache, labelAndConfigur
}
}
}
for _, ruleInputLabel := range ruleInputLabelsBefore.SortedSlice() {
if !ruleInputLabelsAfter.Contains(ruleInputLabel) {
for _, ruleInputLabelAndConfigurations := range ruleInputLabelsAndConfigurationsBefore {
ruleInputLabel := ruleInputLabelAndConfigurations.Label
if _, ok := ruleInputLabelsToConfigurationsAfter[ruleInputLabel]; !ok {
differences = append(differences, Difference{
Category: "RuleInputRemoved",
Key: ruleInputLabel.String(),
Expand All @@ -364,32 +369,12 @@ func WalkDiffs(before *TargetHashCache, after *TargetHashCache, labelAndConfigur
return differences, nil
}

func indexRuleInputs(index *TargetHashCache, rule *build.Rule) (*ss.SortedSet[gazelle_label.Label], map[gazelle_label.Label]*ss.SortedSet[Configuration], error) {
ruleInputs := ss.NewSortedSetFn([]gazelle_label.Label{}, CompareLabels)
labelsToConfigurations := make(map[gazelle_label.Label]*ss.SortedSet[Configuration])
if index.bazelVersionSupportsConfiguredRuleInputs {
for _, configuredRuleInput := range rule.GetConfiguredRuleInput() {
ruleInputLabel, err := ParseCanonicalLabel(configuredRuleInput.GetLabel())
if err != nil {
return nil, nil, fmt.Errorf("failed to parse configuredRuleInput label %s: %w", configuredRuleInput.GetLabel(), err)
}
ruleInputs.Add(ruleInputLabel)
if _, ok := labelsToConfigurations[ruleInputLabel]; !ok {
labelsToConfigurations[ruleInputLabel] = ss.NewSortedSetFn([]Configuration{}, ConfigurationLess)
}
labelsToConfigurations[ruleInputLabel].Add(NormalizeConfiguration(configuredRuleInput.GetConfigurationChecksum()))
}
} else {
for _, ruleInputString := range rule.GetRuleInput() {
ruleInputLabel, err := ParseCanonicalLabel(ruleInputString)
if err != nil {
return nil, nil, fmt.Errorf("failed to parse ruleInput label %s: %w", ruleInputString, err)
}
ruleInputs.Add(ruleInputLabel)
labelsToConfigurations[ruleInputLabel] = index.KnownConfigurations(ruleInputLabel)
}
func indexByLabel(labelsAndConfigurations []LabelAndConfigurations) map[gazelle_label.Label]*ss.SortedSet[Configuration] {
m := make(map[gazelle_label.Label]*ss.SortedSet[Configuration], len(labelsAndConfigurations))
for _, labelAndConfigurations := range labelsAndConfigurations {
m[labelAndConfigurations.Label] = ss.NewSortedSetFn(labelAndConfigurations.Configurations, ConfigurationLess)
}
return ruleInputs, labelsToConfigurations, nil
return m
}

func formatLabelWithConfiguration(label gazelle_label.Label, configuration Configuration) string {
Expand Down Expand Up @@ -502,6 +487,29 @@ func hashRule(thc *TargetHashCache, rule *build.Rule, configuration *analysis.Co
ownConfiguration := NormalizeConfiguration(configuration.GetChecksum())

// Hash rule inputs
labelsAndConfigurations, err := getConfiguredRuleInputs(thc, rule, ownConfiguration)
if err != nil {
return nil, err
}
for _, ruleInputLabelAndConfigurations := range labelsAndConfigurations {
for _, ruleInputConfiguration := range ruleInputLabelAndConfigurations.Configurations {
ruleInputLabel := ruleInputLabelAndConfigurations.Label
ruleInputHash, err := thc.Hash(LabelAndConfiguration{Label: ruleInputLabel, Configuration: ruleInputConfiguration})
if err != nil {
return nil, fmt.Errorf("failed to hash configuredRuleInput %s %s which is a dependency of %s %s: %w", ruleInputLabel, ruleInputConfiguration, rule.GetName(), configuration.GetChecksum(), err)
}

writeLabel(hasher, ruleInputLabel)
hasher.Write(ruleInputConfiguration.ForHashing())
hasher.Write(ruleInputHash)
sitaktif marked this conversation as resolved.
Show resolved Hide resolved
}
}

return hasher.Sum(nil), nil
}

func getConfiguredRuleInputs(thc *TargetHashCache, rule *build.Rule, ownConfiguration Configuration) ([]LabelAndConfigurations, error) {
labelsAndConfigurations := make([]LabelAndConfigurations, 0)
if thc.bazelVersionSupportsConfiguredRuleInputs {
for _, configuredRuleInput := range rule.ConfiguredRuleInput {
ruleInputLabel, err := ParseCanonicalLabel(configuredRuleInput.GetLabel())
Expand All @@ -519,20 +527,20 @@ func hashRule(thc *TargetHashCache, rule *build.Rule, configuration *analysis.Co
return nil, fmt.Errorf("configuredRuleInputs for %s included %s in configuration %s but it couldn't be found either unconfigured or in the depending target's configuration %s. This probably indicates a bug in Bazel - please report it with a git repo that reproduces at https://github.com/bazel-contrib/target-determinator/issues so we can investigate", rule.GetName(), ruleInputLabel, ruleInputConfiguration, ownConfiguration)
}
}
ruleInputHash, err := thc.Hash(LabelAndConfiguration{Label: ruleInputLabel, Configuration: ruleInputConfiguration})
if err != nil {
return nil, fmt.Errorf("failed to hash configuredRuleInput %s %s which is a dependency of %s %s: %w", ruleInputLabel, ruleInputConfiguration, rule.GetName(), configuration.GetChecksum(), err)
}
writeLabel(hasher, ruleInputLabel)
hasher.Write(ruleInputConfiguration.ForHashing())
hasher.Write(ruleInputHash)
labelsAndConfigurations = append(labelsAndConfigurations, LabelAndConfigurations{
Label: ruleInputLabel,
Configurations: []Configuration{ruleInputConfiguration},
sitaktif marked this conversation as resolved.
Show resolved Hide resolved
})
}
} else {
for _, ruleInputLabelString := range rule.RuleInput {
ruleInputLabel, err := ParseCanonicalLabel(ruleInputLabelString)
if err != nil {
return nil, fmt.Errorf("failed to parse ruleInput label %s: %w", ruleInputLabelString, err)
}
labelAndConfigurations := LabelAndConfigurations{
Label: ruleInputLabel,
}
var depConfigurations []Configuration
// Aliases don't transition, and we've seen aliases expanding across configurations cause dependency cycles for nogo targets.
if rule.GetRuleClass() == "alias" {
Expand All @@ -550,14 +558,13 @@ func hashRule(thc *TargetHashCache, rule *build.Rule, configuration *analysis.Co
depConfigurations = []Configuration{NormalizeConfiguration("")}
} else {
// If it's not a source file, narrow just to the current configuration - we know there was no transition, so we must be in the same configuration.
depConfigurations = []Configuration{NormalizeConfiguration(configuration.GetChecksum())}
depConfigurations = []Configuration{ownConfiguration}
}
} else {
depConfigurations = thc.KnownConfigurations(ruleInputLabel).SortedSlice()
}
for _, configuration := range depConfigurations {
ruleInputHash, err := thc.Hash(LabelAndConfiguration{Label: ruleInputLabel, Configuration: configuration})
if err != nil {
if _, err := thc.Hash(LabelAndConfiguration{Label: ruleInputLabel, Configuration: configuration}); err != nil {
if errors.Is(err, labelNotFound) {
// Two issues (so far) have been found which lead to targets being listed in
// ruleInputs but not in the output of a deps query:
Expand All @@ -574,14 +581,12 @@ func hashRule(thc *TargetHashCache, rule *build.Rule, configuration *analysis.Co
}
return nil, err
}
writeLabel(hasher, ruleInputLabel)
hasher.Write(configuration.ForHashing())
hasher.Write(ruleInputHash)
labelAndConfigurations.Configurations = append(labelAndConfigurations.Configurations, configuration)
}
labelsAndConfigurations = append(labelsAndConfigurations, labelAndConfigurations)
}
}

return hasher.Sum(nil), nil
return labelsAndConfigurations, nil
}

type fileHashCache struct {
Expand Down
Loading