Skip to content

Add support for ignored dependencies #51

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

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
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
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ jobs:
test-sbt:
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macOS-latest]
jvm: ['adopt:1.8', 'adopt:1.11', 'temurin:1.17']
os: [ubuntu-latest]
jvm: ['adopt:1.11', 'temurin:1.17']
fail-fast: false
name: Test sbt plugin on ${{ matrix.os }} - ${{ matrix.jvm }}
runs-on: ${{ matrix.os }}
Expand All @@ -48,7 +48,7 @@ jobs:
test-action:
strategy:
matrix:
os: [ubuntu-latest, macOS-latest, windows-latest]
os: [ubuntu-latest]
fail-fast: false
name: Test Github action on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
Expand Down
24 changes: 23 additions & 1 deletion dist/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

12 changes: 12 additions & 0 deletions sbt-plugin/src/main/contraband/input.contra
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ enum OnFailure {
warning
}

type Dependency {
organization: String!
name: String
revision: String
}

## Input of the githubSubmitDependencyGraph command
type SubmitInput {
onResolveFailure: ch.epfl.scala.OnFailure
Expand All @@ -16,4 +22,10 @@ type SubmitInput {
## The name of module is composed of the name of the project and its binary version.
## Example: foo_2.13
ignoredModules: [String]

## A set of dependencies to ignore.
## Ignore a specific list of dependencies across all modules. Transitive dependencies will also be ignored unless
## they're also a transitive dependency of something that isn't ignored.
## Example:
ignoredDependencies: [ch.epfl.scala.Dependency]
}
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ object GithubDependencyGraphPlugin extends AutoPlugin {
val scalaBinaryVersion = (Keys.artifactName / Keys.scalaBinaryVersion).value
val crossVersion = CrossVersion.apply(scalaVersion, scalaBinaryVersion)
val allDirectDependencies = Keys.allDependencies.value
val ignoredDependencies = Keys.state.value.attributes(githubSubmitInputKey).ignoredDependencies
Copy link
Member

@adpi2 adpi2 Aug 9, 2022

Choose a reason for hiding this comment

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

The githubSubmitInputKey attribute is set by the githubSubmitDependencyGraph command here.

I suggest to add a default value, for the task not to fail if the attribute is missing:

Suggested change
val ignoredDependencies = Keys.state.value.attributes(githubSubmitInputKey).ignoredDependencies
val ignoredDependencies = Keys.state.value.attributes.get(githubSubmitInputKey).toSeq.flatMap(_.ignoredDependencies)

val baseDirectory = Keys.baseDirectory.value
val logger = Keys.streams.value.log
val onResolveFailure = Keys.state.value.get(githubSubmitInputKey).flatMap(_.onResolveFailure)
Expand All @@ -116,6 +117,13 @@ object GithubDependencyGraphPlugin extends AutoPlugin {
.withExtraAttributes(Map.empty)
.toString

def isIgnored(module: ModuleID): Boolean =
ignoredDependencies.exists { ignored =>
ignored.organization == module.organization &&
ignored.name.forall(_ == module.name) &&
ignored.revision.forall(_ == module.revision)
}

reportResult match {
case Inc(cause) =>
val moduleName = crossVersion(projectID).name
Expand All @@ -137,7 +145,7 @@ object GithubDependencyGraphPlugin extends AutoPlugin {
configReport <- report.configurations
moduleReport <- configReport.modules
moduleRef = getReference(moduleReport.module)
if !moduleReport.evicted && !alreadySeen.contains(moduleRef)
if !moduleReport.evicted && !alreadySeen.contains(moduleRef) && !isIgnored(moduleReport.module)
Copy link
Member

Choose a reason for hiding this comment

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

This will filter out the library but not its transitive dependencies. Maybe I am wrong but I think it would be quite hard to filter out all transitive dependencies of a library. To do so we would need to build the entire tree of parents and check that all roots are ignored. Unfortunately, in a module report we only have one level of parents: moduleReport.callers.

What about filtering out entire configs rather than dependencies? That would be easier to implement.

} {
alreadySeen += moduleRef
moduleReports += (moduleReport -> configReport.configuration)
Expand Down
7 changes: 6 additions & 1 deletion sbt-plugin/src/sbt-test/submit-snapshot/ci-submit/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ val b = project

Global / checkManifests := {
val logger = streams.value.log
val expectedSize: Int = (Space ~> NatBasic).parsed
val (expectedSize, expectScalaLibrary): (Int, Boolean) = (Space ~> NatBasic ~ (Space ~> Bool)).parsed
val manifests = state.value.get(githubManifestsKey).getOrElse {
throw new MessageOnlyException(s"Not found ${githubManifestsKey.label} attribute")
}
Expand All @@ -53,4 +53,9 @@ Global / checkManifests := {
manifests.size == expectedSize,
s"expected $expectedSize manifests, found ${manifests.size}"
)
assert(
expectScalaLibrary || manifests.values.forall(
_.resolved.values.forall(_.dependencies.forall(!_.startsWith("org.scala-lang:scala-library")))
)
)
}
10 changes: 6 additions & 4 deletions sbt-plugin/src/sbt-test/submit-snapshot/ci-submit/test
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
> 'githubSubmitDependencyGraph {}'
> Global / checkManifests 4
> Global / checkManifests 4 true

> 'githubSubmitDependencyGraph {"ignoredModules":["a_2.13", "b_2.13"]}'
> Global / checkManifests 2
> Global / checkManifests 2 true

> 'githubSubmitDependencyGraph {"ignoredModules":["a_2.12", "a_2.13", "b_2.13"]}'
> Global / checkManifests 1
> Global / checkManifests 1 true

> 'githubSubmitDependencyGraph {"ignoredModules":[]}'
> Global / checkManifests 4
> Global / checkManifests 4 true

> 'githubSubmitDependencyGraph {"ignoredDependencies":[{"organization":"org.scala-lang", "name": "scala-library"}]}'
> Global / checkManifests 4 false
12 changes: 10 additions & 2 deletions sbt-plugin/src/test/scala/ch/epfl/scala/JsonProtocolTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,23 @@ class JsonProtocolTests extends FunSuite {
import ch.epfl.scala.JsonProtocol._
val raw = Parser.parseUnsafe("{}")
val obtained = Converter.fromJson[SubmitInput](raw).get
val expected = SubmitInput(None, Vector.empty)
val expected = SubmitInput(None, Vector.empty, Vector.empty)
assertEquals(obtained, expected)
}

test("decode input with onResolveFailure: warning") {
import ch.epfl.scala.JsonProtocol._
val raw = Parser.parseUnsafe("""{"onResolveFailure": "warning"}""")
val obtained = Converter.fromJson[SubmitInput](raw).get
val expected = SubmitInput(Some(OnFailure.warning), Vector.empty)
val expected = SubmitInput(Some(OnFailure.warning), Vector.empty, Vector.empty)
assertEquals(obtained, expected)
}

test("decode input with ignoredDependencies") {
import ch.epfl.scala.JsonProtocol._
val raw = Parser.parseUnsafe("""{"ignoredDependencies": [{"organization": "org.test", "name": "thing"}]}""")
val obtained = Converter.fromJson[SubmitInput](raw).get
val expected = SubmitInput(None, Vector.empty, Vector(Dependency("org.test", Some("thing"), None)))
assertEquals(obtained, expected)
}
}
24 changes: 23 additions & 1 deletion src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,28 @@ async function run(): Promise<void> {
.split(' ')
.filter(value => value.length > 0)

const ignoredDependencies = core
.getInput('dependencies-ignore')
.split(' ')
.filter(value => value.length > 0)
.map(value => {
const parts = value.split(':')
if (parts.length === 1) {
return { organization: parts[0] }
} else if (parts.length === 2) {
return { organization: parts[0], name: parts[1] }
} else if (parts.length === 3) {
return { organization: parts[0], name: parts[1], version: parts[2] }
} else {
core.setFailed(
`dependencies-ignore. Should be a space-separated list of dependency declarations,
with organization, name (optional) and version (optional) separated by single colons:
'org1(:name1)(:version1) org2(:name2)(:version2)'.`,
)
return {}
}
})

const onResolveFailure = core.getInput('on-resolve-failure')
if (!['error', 'warning'].includes(onResolveFailure)) {
core.setFailed(
Expand All @@ -43,7 +65,7 @@ async function run(): Promise<void> {
return
}

const input = { ignoredModules, onResolveFailure }
const input = { ignoredModules, ignoredDependencies, onResolveFailure }

process.env['GITHUB_TOKEN'] = token
await cli.exec('sbt', [`githubSubmitDependencyGraph ${JSON.stringify(input)}`], {
Expand Down