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

Plug gazelle_cabal.ImportData in Resolve to allow both gazelle extensions to run in the same gazelle_binary #41

Closed
wants to merge 17 commits into from
Closed
Show file tree
Hide file tree
Changes from 6 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
20 changes: 20 additions & 0 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,26 @@ load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies")

gazelle_dependencies()

####################
# Gazelle Cabal
####################

# QUESTION: When the pull request adding the 2 missing library functions in gazelle_cabal is merged,
# should we refer to an explicit commit of gazelle_cabal or to `main`?

http_archive(
name = "io_tweag_gazelle_cabal",
sha256 = "853acd38dc69284c915c0d30fe6e051593bf4e7f900e6be13ef306fc7ffa74c0",
strip_prefix = "gazelle_cabal-240ad1af8d0d0ca5c3fd3ff7afcdb2f0fe0dbbe2",
urls = [
"https://github.com/tweag/gazelle_cabal/archive/240ad1af8d0d0ca5c3fd3ff7afcdb2f0fe0dbbe2.zip",
],
)

load("@io_tweag_gazelle_cabal//:defs.bzl", "gazelle_cabal_dependencies")

gazelle_cabal_dependencies()

#######################
# Buildifier preamble
#######################
Expand Down
20 changes: 20 additions & 0 deletions example/WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -141,3 +141,23 @@ http_archive(
load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies")

gazelle_dependencies()

####################
# Gazelle Cabal
####################

# QUESTION: When the pull request adding the 2 missing library functions in gazelle_cabal is merged,
# should we refer to an explicit commit of gazelle_cabal or to `main`?

http_archive(
name = "io_tweag_gazelle_cabal",
sha256 = "853acd38dc69284c915c0d30fe6e051593bf4e7f900e6be13ef306fc7ffa74c0",
strip_prefix = "gazelle_cabal-240ad1af8d0d0ca5c3fd3ff7afcdb2f0fe0dbbe2",
urls = [
"https://github.com/tweag/gazelle_cabal/archive/240ad1af8d0d0ca5c3fd3ff7afcdb2f0fe0dbbe2.zip",
],
)

load("@io_tweag_gazelle_cabal//:defs.bzl", "gazelle_cabal_dependencies")

gazelle_cabal_dependencies()
1 change: 1 addition & 0 deletions gazelle_haskell_modules/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ go_library(
"@bazel_gazelle//rule:go_default_library",
"@com_github_bazelbuild_buildtools//build:go_default_library",
"@io_bazel_rules_go//go/tools/bazel:go_default_library",
"@io_tweag_gazelle_cabal//gazelle_cabal",
],
)

Expand Down
29 changes: 22 additions & 7 deletions gazelle_haskell_modules/lang.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import (
"github.com/bazelbuild/bazel-gazelle/resolve"
"github.com/bazelbuild/bazel-gazelle/rule"

gazelle_cabal "github.com/tweag/gazelle_cabal/gazelle_cabal"

"log"
"path"
"path/filepath"
Expand Down Expand Up @@ -171,10 +173,20 @@ func (*gazelleHaskellModulesLang) Embeds(r *rule.Rule, from label.Label) []label

func (*gazelleHaskellModulesLang) Resolve(c *config.Config, ix *resolve.RuleIndex, rc *repo.RemoteCache, r *rule.Rule, imports interface{}, from label.Label) {
hmc := c.Exts[gazelleHaskellModulesName].(Config)
if isNonHaskellModule(r.Kind()) {
setNonHaskellModuleDeps(&hmc, c.RepoRoot, ix, r, imports.(*HRuleImportData), from)
} else {
setHaskellModuleDeps(ix, r, imports.(*HModuleImportData), from)
switch expr := imports.(type) {
// This happens only when one run gazelle_cabal and gazelle_haskell_modules in one pass as the the gazelle_binary.
case gazelle_cabal.ImportData:
// We fully generate the rule that gazele_cabal would have produced.
gazelle_cabal.RunResolve(c, ix, rc, r, expr, from)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need some help understanding the flow. Is this case entered anytime a haskell_binary/library/test rule is updated or created by gazelle_cabal?

If so, how are haskell_module rules generated from this rule?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This case is entered whenever the Resolve function is called on rules that come from the same gazelle run (so rules where the imports where constructed by gazelle_cabal and not by the haskell lib himportscan included in gazelle_haskell_modules).
Regarding the construction of haskell_modules rules, it is performed just like for other rules by setNonHaskellModuleDeps.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code is calling RunResolve, which apparently is a duplicate of the Resolve callback of gazelle_cabal. Isn't that callback invoked by gazelle implicitly?

// We then create an HRuleImportData from the generated rule.
newr, newImports := addOneNonHaskellModuleRule(c.RepoRoot, from.Repo, from.Pkg, r)
setNonHaskellModuleDeps(&hmc, c.RepoRoot, ix, newr, newImports, from)
default:
if isNonHaskellModule(r.Kind()) {
setNonHaskellModuleDeps(&hmc, c.RepoRoot, ix, r, imports.(*HRuleImportData), from)
} else {
setHaskellModuleDeps(ix, r, imports.(*HModuleImportData), from)
}
}
}

Expand All @@ -186,13 +198,16 @@ func (*gazelleHaskellModulesLang) GenerateRules(args language.GenerateArgs) lang
}
}

ruleInfos := rulesToRuleInfos(args.Dir, args.File.Rules, args.Config.RepoName, args.File.Pkg)
// The list of rules should contain both the rules already present in the build file (args.File.Rules)
// and the one that previous extensions of gazelle generated in this run (args.OtherGen...).
// This second argument contains the rule generated by gazelle_cabal when both extensions are ran in the same gazelle_binary.
rulesList := append(args.File.Rules, args.OtherGen...)
ruleInfos := rulesToRuleInfos(args.Dir, rulesList, args.Config.RepoName, args.File.Pkg)
facundominguez marked this conversation as resolved.
Show resolved Hide resolved
generateResult := infoToRules(args.Dir, ruleInfos)

setVisibilities(args.File, generateResult.Gen)

c := args.Config.Exts[gazelleHaskellModulesName].(Config)
return addNonHaskellModuleRules(&c, args.Dir, args.Config.RepoName, args.File.Pkg, generateResult, args.File.Rules)
return addNonHaskellModuleRules(args.Dir, args.Config.RepoName, args.File.Pkg, generateResult, args.File.Rules)
}

func (*gazelleHaskellModulesLang) Fix(c *config.Config, f *rule.File) {
Expand Down
63 changes: 38 additions & 25 deletions gazelle_haskell_modules/rule_generation.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,6 @@ func infoToRules(pkgRoot string, ruleInfos []*RuleInfo) language.GenerateResult
}

func addNonHaskellModuleRules(
c *Config,
pkgRoot string,
repo string,
pkg string,
Expand All @@ -239,32 +238,10 @@ func addNonHaskellModuleRules(
continue
}
if isNonHaskellModule(r.Kind()) {
newr := rule.NewRule(r.Kind(), r.Name())
for _, k := range r.AttrKeys() {
if k != "srcs" && k != "modules" && k != "deps" && k != "narrowed_deps" && k != "main_file" {
newr.SetAttr(k, r.Attr(k))
}
}
newr, importData := addOneNonHaskellModuleRule(pkgRoot, repo, pkg, r)

srcs, err := getSrcs(pkgRoot, r)
handleRuleError(err, r, "srcs")
modules, err := depsFromRule(r.Attr("modules"), repo, pkg)
handleRuleError(err, r, "modules")
deps, err := depsFromRule(r.Attr("deps"), repo, pkg)
handleRuleError(err, r, "deps")
narrowedDeps, err := depsFromRule(r.Attr("narrowed_deps"), repo, pkg)
handleRuleError(err, r, "narrowed_deps")
appendLabelMaps(deps, narrowedDeps)
imports = append(imports, &HRuleImportData{
Deps: deps,
Modules: modules,
Srcs: srcs,
})
imports = append(imports, importData)
haskellRules = append(haskellRules, newr)

r.SetPrivateAttr(PRIVATE_ATTR_DEP_LABELS, deps)
newr.SetPrivateAttr(PRIVATE_ATTR_DEP_LABELS, deps)
newr.SetPrivateAttr(PRIVATE_ATTR_MODULE_LABELS, r.PrivateAttr(PRIVATE_ATTR_MODULE_LABELS))
}
}
return language.GenerateResult{
Expand All @@ -273,6 +250,42 @@ func addNonHaskellModuleRules(
}
}

func addOneNonHaskellModuleRule(
pkgRoot string,
repo string,
pkg string,
r *rule.Rule,
) (*rule.Rule, *HRuleImportData) {
newr := rule.NewRule(r.Kind(), r.Name())
for _, k := range r.AttrKeys() {
if k != "srcs" && k != "modules" && k != "deps" && k != "narrowed_deps" && k != "main_file" {
newr.SetAttr(k, r.Attr(k))
}
}

srcs, err := getSrcs(pkgRoot, r)
handleRuleError(err, r, "srcs")
modules, err := depsFromRule(r.Attr("modules"), repo, pkg)
handleRuleError(err, r, "modules")
deps, err := depsFromRule(r.Attr("deps"), repo, pkg)
handleRuleError(err, r, "deps")
narrowedDeps, err := depsFromRule(r.Attr("narrowed_deps"), repo, pkg)
handleRuleError(err, r, "narrowed_deps")
appendLabelMaps(deps, narrowedDeps)

r.SetPrivateAttr(PRIVATE_ATTR_DEP_LABELS, deps)
newr.SetPrivateAttr(PRIVATE_ATTR_DEP_LABELS, deps)
newr.SetPrivateAttr(PRIVATE_ATTR_MODULE_LABELS, r.PrivateAttr(PRIVATE_ATTR_MODULE_LABELS))

importData := &HRuleImportData{
Deps: deps,
Modules: modules,
Srcs: srcs,
}

return newr, importData
}

func appendLabelMaps(a map[label.Label]bool, b map[label.Label]bool) {
for k, v := range b {
a[k] = v
Expand Down
21 changes: 21 additions & 0 deletions tests/alternative-deps/WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ stack_snapshot(
"Cabal",
"base",
"inspection-testing",
"json",
"tasty",
"tasty-discover",
"tasty-hunit",
Expand Down Expand Up @@ -162,3 +163,23 @@ http_archive(
load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies")

gazelle_dependencies()

####################
# Gazelle Cabal
####################

# QUESTION: When the pull request adding the 2 missing library functions in gazelle_cabal is merged,
# should we refer to an explicit commit of gazelle_cabal or to `main`?
facundominguez marked this conversation as resolved.
Show resolved Hide resolved

http_archive(
name = "io_tweag_gazelle_cabal",
sha256 = "853acd38dc69284c915c0d30fe6e051593bf4e7f900e6be13ef306fc7ffa74c0",
strip_prefix = "gazelle_cabal-240ad1af8d0d0ca5c3fd3ff7afcdb2f0fe0dbbe2",
urls = [
"https://github.com/tweag/gazelle_cabal/archive/240ad1af8d0d0ca5c3fd3ff7afcdb2f0fe0dbbe2.zip",
],
)

load("@io_tweag_gazelle_cabal//:defs.bzl", "gazelle_cabal_dependencies")

gazelle_cabal_dependencies()