Package org.ek9lang.cli
Class DependencyManager
java.lang.Object
org.ek9lang.cli.DependencyManager
Designed to deal with managing dependencies of ek9 modules.
So when an ek9 module is defined and packaged it can reference dependencies and
development dependencies. These are basically a mix of both the module name and a version number.
Note that the module scope package IS public interface to your package, if you want internal,
implementations constructs put them in a module under the module you are packaging.
For example if publishing/packaging ek9open.google.tools.networking, and you want to have
internal stuff that can only be used inside the package then use:
ek9open.google.tools.networking.internal or ek9open.google.tools.networking.utils etc.
Full vector could be 'ek9open.google.tools.networking.utils-1.0.8-5'
module '-' MAJOR '.' MINOR '.' PATCH '-' BUILD
For feature branch builds it might be 'ek9open.google.tools.networking.utils-1.0.8-VSTS9889-5'
module '-' MAJOR '.' MINOR '.' PATCH ('-' FEATURE)? '-' BUILD
The actual artefact would have a suffix of '.zip'
So what's the big issue here, well we need to:
1. Prohibit and detect circular dependencies.
2. Remove dependencies that the developer does not want to include that other dependencies
might pull in.
3. Ensure only a single version (highest based on version numbering) is included.
4. For semanticVersioning - fail build if major version gets pulled up when other dependencies
need lower version.
For semantic versioning major > minor > patch > build and patch without feature is higher.
Features are ordered by alpha. i.e. Alpha > Beta for example.
This is done with a directed graph with back pointers back up the graph tree.
The main Nodes in the graph hold both the moduleName and the Version separately and have a flag
to denote rejection. They also hold a list of other Nodes that they depend on.
Once you have checked for circular dependencies (and there are none)
You can then use or reject exclude modules.
Then use this method so that modules that are the same but different version numbers can be
rationalised. This means finding the module of the same name but the highest version
(that has not already been rejected). Only keep the highest none rejected version, mark others
as rejected.
BUT NOTE this sometimes means additional dependencies get included because we might have
rejected a module that had a number of dependencies that only that version of the module used!
At the end it is possible the developer excluded a set of dependencies that were needed.
The compiler will let the developer know because there will be missing symbols.
-
Constructor Summary
-
Method Summary
Modifier and TypeMethodDescription(package private) List
<DependencyNode> findByModuleName
(String moduleName) Search for a particular moduleName, can return multiple matches if there are multiple versions of the same dependency.Traverse the tree graph to find all the distinct module names in use ignoring the version numbers.(package private) boolean
optimise
(int numberOfOptimiseCalls) Marks dependencies that fall along a reject path as rejected.(package private) void
Mark modules as rejected if there is a higher version of the same module (that is not marked as rejected).(package private) void
Reject a moduleName dependency if is has been pulled in when is it a dependency of another module.(package private) List
<DependencyNode> Provide a list of all accepted dependencies.Reports all the dependencies there are from root.reportCircularDependencies
(boolean includeVersion) Check if there are any circular references and report back up on the path the dependency was found in.(package private) List
<DependencyNode> Provide a list of all rejected dependencies.(package private) List
<DependencyNode> Any situation where the top selected dependency has one or more, lower version numbers where the major version is less that that selected.
-
Constructor Details
-
DependencyManager
DependencyManager(DependencyNode root)
-
-
Method Details
-
rationalise
void rationalise()Mark modules as rejected if there is a higher version of the same module (that is not marked as rejected). -
optimise
boolean optimise(int numberOfOptimiseCalls) Marks dependencies that fall along a reject path as rejected. Can and probably should be called in a loop until returns false. Because you might process nodes in an order where a lower level tree node has a viable path back to parent and so is not marked as rejected. But then a little later in the processing a critical node in the path is marked as rejected. Now the lower level one does not have path back. So call in a loop until fully optimised.- Returns:
- true is optimisation took place, false if there was nothing to optimise.
-
reportStrictSemanticVersionBreaches
List<DependencyNode> reportStrictSemanticVersionBreaches()Any situation where the top selected dependency has one or more, lower version numbers where the major version is less that that selected. Basically this means you cannot continue with this set of dependencies - it just won't work at all for you. Unlike Java, we do actually get the packages and recompile them, so public interfaces in packages must match.- Returns:
- The list of offending nodes.
-
reportRejectedDependencies
List<DependencyNode> reportRejectedDependencies()Provide a list of all rejected dependencies.- Returns:
- The list.
-
reportAcceptedDependencies
List<DependencyNode> reportAcceptedDependencies()Provide a list of all accepted dependencies.- Returns:
- The list.
-
reject
Reject a moduleName dependency if is has been pulled in when is it a dependency of another module. -
listAllModuleNames
Traverse the tree graph to find all the distinct module names in use ignoring the version numbers.- Returns:
- The list of unique module names.
-
findByModuleName
Search for a particular moduleName, can return multiple matches if there are multiple versions of the same dependency. The highest version number is returned first.- Parameters:
moduleName
- The module name to search for.- Returns:
- The list of modules that match (i.e. same module name but maybe multiple versions).
-
reportAllDependencies
Reports all the dependencies there are from root. If root is not set then this is an empty list.- Returns:
- The list of all the dependencies.
-
reportCircularDependencies
Check if there are any circular references and report back up on the path the dependency was found in.- Returns:
- One or more circular paths in the graph/tree.
-
reportCircularDependencies
-