@@ -9,13 +9,14 @@ import coursier.parse.JavaOrScalaModule
9
9
import coursier .parse .ModuleParser
10
10
import coursier .util .ModuleMatcher
11
11
import mainargs .Flag
12
- import mill .api .Loose .Agg
13
- import mill .define .ModuleRef
12
+ import mill .Agg
14
13
import mill .api .{JarManifest , PathRef , Result , internal }
15
- import mill .util .Jvm
14
+ import mill .define .{Command , ModuleRef , Segment , Task , TaskModule }
15
+ import mill .scalalib .internal .ModuleUtils
16
16
import mill .scalalib .api .CompilationResult
17
17
import mill .scalalib .bsp .{BspBuildTarget , BspModule }
18
18
import mill .scalalib .publish .Artifact
19
+ import mill .util .Jvm
19
20
import os .Path
20
21
21
22
/**
@@ -122,15 +123,49 @@ trait JavaModule
122
123
*/
123
124
def javacOptions : T [Seq [String ]] = T { Seq .empty[String ] }
124
125
125
- /** The direct dependencies of this module */
126
+ /**
127
+ * The direct dependencies of this module.
128
+ * @see [[moduleDepschecked ]]
129
+ */
126
130
def moduleDeps : Seq [JavaModule ] = Seq .empty
127
131
132
+ /** Same as [[moduleDeps ]] but checked to not contain cycles. */
133
+ final def moduleDepsChecked : Seq [JavaModule ] = {
134
+ // trigger initialization to check for cycles
135
+ recModuleDeps
136
+ moduleDeps
137
+ }
138
+
139
+ /** Should only be called from [[moduleDepsChecked ]] */
140
+ private lazy val recModuleDeps : Seq [JavaModule ] =
141
+ ModuleUtils .recursive[JavaModule ](
142
+ (millModuleSegments ++ Seq (Segment .Label (" moduleDeps" ))).render,
143
+ this ,
144
+ _.moduleDeps
145
+ )
146
+
128
147
/** The compile-only direct dependencies of this module. */
129
148
def compileModuleDeps : Seq [JavaModule ] = Seq .empty
130
149
150
+ /** Same as [[compileModuleDeps ]] but checked to not contain cycles. */
151
+ final def compileModuleDepsChecked : Seq [JavaModule ] = {
152
+ // trigger initialization to check for cycles
153
+ recCompileModuleDeps
154
+ compileModuleDeps
155
+ }
156
+
157
+ /** Should only be called from [[compileModuleDeps ]] */
158
+ private lazy val recCompileModuleDeps : Seq [JavaModule ] =
159
+ ModuleUtils .recursive[JavaModule ](
160
+ (millModuleSegments ++ Seq (Segment .Label (" compileModuleDeps" ))).render,
161
+ this ,
162
+ _.compileModuleDeps
163
+ )
164
+
131
165
/** The direct and indirect dependencies of this module */
132
166
def recursiveModuleDeps : Seq [JavaModule ] = {
133
- moduleDeps.flatMap(_.transitiveModuleDeps).distinct
167
+ // moduleDeps.flatMap(_.transitiveModuleDeps).distinct
168
+ recModuleDeps
134
169
}
135
170
136
171
/**
@@ -148,32 +183,32 @@ trait JavaModule
148
183
* look at the direct `compileModuleDeps` when assembling this list
149
184
*/
150
185
def transitiveModuleCompileModuleDeps : Seq [JavaModule ] = {
151
- (moduleDeps ++ compileModuleDeps ).flatMap(_.transitiveModuleDeps).distinct
186
+ (moduleDepsChecked ++ compileModuleDepsChecked ).flatMap(_.transitiveModuleDeps).distinct
152
187
}
153
188
154
189
/** The compile-only transitive ivy dependencies of this module and all it's upstream compile-only modules. */
155
190
def transitiveCompileIvyDeps : T [Agg [BoundDep ]] = T {
156
191
// We never include compile-only dependencies transitively, but we must include normal transitive dependencies!
157
192
compileIvyDeps().map(bindDependency()) ++
158
- T .traverse(compileModuleDeps )(_.transitiveIvyDeps)().flatten
193
+ T .traverse(compileModuleDepsChecked )(_.transitiveIvyDeps)().flatten
159
194
}
160
195
161
196
/**
162
197
* Show the module dependencies.
163
198
* @param recursive If `true` include all recursive module dependencies, else only show direct dependencies.
164
199
*/
165
200
def showModuleDeps (recursive : Boolean = false ): Command [Unit ] = T .command {
166
- val normalDeps = if (recursive) recursiveModuleDeps else moduleDeps
201
+ val normalDeps = if (recursive) recursiveModuleDeps else moduleDepsChecked
167
202
val compileDeps =
168
- if (recursive) compileModuleDeps .flatMap(_.transitiveModuleDeps).distinct
169
- else compileModuleDeps
203
+ if (recursive) compileModuleDepsChecked .flatMap(_.transitiveModuleDeps).distinct
204
+ else compileModuleDepsChecked
170
205
val deps = (normalDeps ++ compileDeps).distinct
171
206
val asString =
172
207
s " ${if (recursive) " Recursive module"
173
208
else " Module" } dependencies of ${millModuleSegments.render}: \n\t ${deps
174
209
.map { dep =>
175
210
dep.millModuleSegments.render ++
176
- (if (compileModuleDeps .contains(dep) || ! normalDeps.contains(dep)) " (compile)"
211
+ (if (compileModuleDepsChecked .contains(dep) || ! normalDeps.contains(dep)) " (compile)"
177
212
else " " )
178
213
}
179
214
.mkString(" \n\t " )}"
@@ -193,7 +228,7 @@ trait JavaModule
193
228
*/
194
229
def transitiveIvyDeps : T [Agg [BoundDep ]] = T {
195
230
(ivyDeps() ++ mandatoryIvyDeps()).map(bindDependency()) ++
196
- T .traverse(moduleDeps )(_.transitiveIvyDeps)().flatten
231
+ T .traverse(moduleDepsChecked )(_.transitiveIvyDeps)().flatten
197
232
}
198
233
199
234
/**
0 commit comments