-
Notifications
You must be signed in to change notification settings - Fork 116
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
[Feature Request] Dependency graph introspection #230
Comments
Hey @Epigene we actually do a version of this in our CI suite using There are two important things to note here:
I think to do this, we just need to do a breadth first search of a package's ancestors. Our implementation actually doesn't yet look at violations Here's our implementation: require 'parse_packwerk'
class AffectedPackagesHelper
def initialize(modified_packs)
@packs = modified_packs
@memo = {}
end
def dependent_packs
@packs.each do |pack|
inbound_dependencies_traversal(pack)
end
return @memo.keys
end
# Using BFS traversal, finds list of explicitly dependent packages defined
# by each pack's `package.yml` and adds it to the memoized traversed packages
# array @memo.
#
# @param String the name of a pack in `packs/some_pack` format
def inbound_dependencies_traversal(package_name)
return if @memo.key?(package_name)
queue = [package_name]
while !queue.empty?
curr_package = queue.pop
# Our implementation doesn't yet look at violations, but it should look at
# ParsePackwerk.all.select { |package| ParsePackwerk::DeprecatedReferences.for(package).violations.any?{|v| v.to_package_name == curr_package }
inbound_dependencies = @memo[curr_package] ||
ParsePackwerk.all.select { |package| package.dependencies.include?(curr_package) }.map(&:name)
if !@memo.key?(curr_package)
@memo[curr_package] = inbound_dependencies
end
inbound_dependencies.each do |dependency|
if !@memo.key?(dependency)
queue << dependency
end
end
end
end
end Want to let me know if this technique works for you locally? I'd love to be able to support more CI tools like this in the packwerk ecosystem and want to work out the kinks and figure out what/where the API should live. |
@alexevanczuk Thanks for the quick reply, I'll give |
Awesome, let me know what you come up with @Epigene ! I love this effort because allowing packwerk to open doors to conditional builds (as we refer to them) for fast (and thus cheaper) builds is a huge opportunity. Long-term, we hope that the same concept can allow for conditional deployments – that is, deploying a package separately once we've ascertained programmatically that it can stand in its own application (i.e. all dependencies fully specified) and all consumers are talking with it via a network-boundary-agnostic API (this is one of many reasons why we feel privacy enforcement is so important). |
Hi, we have a use-case for packwerk that could significantly cut down on CI work needed for monolithic apps.
If we could tell which pack a changed file in a merge request belongs to and which packs depend on the changed pack,
it would be possible to run CI for only the affected part of the code, not necessarily all domain.
For example, changes in front-end code would not necessitate running DB querier specs, because there's no
way queriers were affected.
Let's consider this example app:
The root pack lists both
app/domain
andapp/io
as dependencies, because we need both for the app to function.app/domain
has no dependencies, it is the core of our business.app/io
depends onapp/domain
- contains front-end stuff etc.Given a list of changed files in a merge request, we would love to be able to ask packwerk two things:
So for example if we have an MR that changes
app/domain/thing.rb
:['app/domain']
['.', 'app/io']
Whereas if
app/io/thing_reader.rb
gets changed:['app/io']
['.']
# root pack will always be downstreamPerhaps to answer the question "which pack specs need to be ran?" merging both of these lists is preferable,
so here's a proposed API:
The text was updated successfully, but these errors were encountered: