-
Notifications
You must be signed in to change notification settings - Fork 252
[Spec] Managing dependency package assets
This spec covers the design for including and excluding parts of dependency packages.
Include flags are defined on dependency edges, not on the packages themselves. Projects and packages are treated the same with the exception that direct project references will include content by default. Packages receive an intersection of the edge flags when walking down the dependency graph. The set of flags for each package target id is the union of the flags applied from the walk. Flags for direct project dependencies will override all other flags. This is explained further in the examples.
Flag | Description |
---|---|
contentFiles | Content v2 items |
runtime | Includes the Runtime, Resources, and FrameworkAssemblies sections of the target |
compile | Lock file compile section of the target |
build | MSBuild targets and properties in the build folder |
native | Native folder |
none | Empty |
all | All flags |
Excluding content files from a package
{
"dependencies": {
"packageA": {
"version": "1.0.0",
"exclude": "contentFiles"
}
}
}
Including only runtime components for a package:
{
"dependencies": {
"packageA": {
"version": "1.0.0",
"include": "runtime"
}
}
}
Content v2 is turned off for transitive dependencies by default. Packages must opt in to allowing content to flow up from dependency packages. By specifying all as the include flag contentFiles will be turned on.
<dependencies>
<group>
<dependency id="packageB" version="1.0.0" include="all" />
</group>
</dependencies>
Dependency items may also provide an exclude property instead of listing out each part of the package to include. By defining exclude="build"
the dependency packageB will not add msbuild targets and prop files to the project.
<dependencies>
<group>
<dependency id="packageB" version="1.0.0" exclude="build" />
</group>
</dependencies>
The include and exclude properties for both project.json and nuspec dependencies support comma delimited flags.
"build,native,runtime"
Exclude takes precedence over include.
"include": "runtime,compile", "exclude": "compile"
is equivalent to "include": "runtime"
Content v2 is disabled by default for all package dependencies except for those referenced directly by the project in project.json. Transitive packages coming from other packages and from other projects will not bring in content unless the package or project has opted into it using the needed include.
Projects may have dependencies that are not needed by consumers of the project. For example if ProjectA depends on a package X which has content files, ProjectB should not transitively depend on package X since the content was compiled into ProjectA and will come from that assembly.
To solve this the includes on dependency edges can be thought of in two ways.
- Behavior that applies to myself (for consumers of this project)
- Behavior that applies to my dependencies (for this project)
To define additional excludes for consumers of the project the suppressParent
property is used. In the below example the content only package is used by the project, but consumers of the project do not get the dependency.
{
"dependencies": {
"contentOnlyPackage": {
"version": "1.0.0",
"suppressParent": "all"
}
}
}
A build time only dependency can be created by excluding the dependency for the consumers of the project. When this project is packed packageA will not be included as a dependency.
{
"dependencies": {
"packageA": {
"version": "1.0.0",
"suppressParent": "all"
}
}
}
A private dependency can be created by excluding the compile section for consumers of the project.
{
"dependencies": {
"packageA": {
"version": "1.0.0",
"suppressParent": "compile"
}
}
}
Project
|-(all)-> A -(default)-> B -(default)-> C
|-(all)-> C
In the above example the project will reference content included in packages A and C. Content will not be included from B since A does not declare it in the dependency reference.
Project
|-(all)-> A -(+contentFiles)-> B -(+contentFiles)-> C
When include="contentFiles" is used on all dependency edges in the nuspec content will flow transitively for packages A, B, and C.
Project
|-(all)-> A -(-build)-> B -(-compile)-> C
C will have both build and compile excluded since both of these were blocked by parent packages.
Project
|-(all)-> A -(-build)-> B
|-(all)-> B
A does not use the build targets from B and excludes it, however the project has a direct reference to B which brings in all parts of B including the build folder. The exclude defined in A has no effect here since it would block B from being used.
Project
|-(all)-> A -(+build)-> B
|-(-build)-> B
In the reverse of the previous example, if the project excludes the build folder from B it will override the other flags and B will exclude the build section from the target. This allows users to force package behaviors when needed.
Check out the proposals in the accepted
& proposed
folders on the repository, and active PRs for proposals being discussed today.