socket 1.1.141 → 1.1.143
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/dist/cli.js +202 -116
- package/dist/cli.js.map +1 -1
- package/dist/constants.js +4 -4
- package/dist/constants.js.map +1 -1
- package/dist/init.gradle +73 -0
- package/dist/manifest-scripts/maven-extension/coana-maven-extension.jar +0 -0
- package/dist/manifest-scripts/socket-facts.init.gradle +79 -2
- package/dist/manifest-scripts/socket-facts.plugin.scala +97 -20
- package/dist/tsconfig.dts.tsbuildinfo +1 -1
- package/dist/types/commands/manifest/cmd-manifest-auto.d.mts.map +1 -1
- package/dist/types/commands/manifest/cmd-manifest-gradle.d.mts.map +1 -1
- package/dist/types/commands/manifest/cmd-manifest-kotlin.d.mts.map +1 -1
- package/dist/types/commands/manifest/cmd-manifest-maven.d.mts.map +1 -1
- package/dist/types/commands/manifest/cmd-manifest-scala.d.mts.map +1 -1
- package/dist/types/commands/manifest/convert-gradle-to-facts.d.mts +2 -1
- package/dist/types/commands/manifest/convert-gradle-to-facts.d.mts.map +1 -1
- package/dist/types/commands/manifest/convert-maven-to-facts.d.mts +2 -1
- package/dist/types/commands/manifest/convert-maven-to-facts.d.mts.map +1 -1
- package/dist/types/commands/manifest/convert-sbt-to-facts.d.mts +2 -1
- package/dist/types/commands/manifest/convert-sbt-to-facts.d.mts.map +1 -1
- package/dist/types/commands/manifest/convert_gradle_to_maven.d.mts +2 -1
- package/dist/types/commands/manifest/convert_gradle_to_maven.d.mts.map +1 -1
- package/dist/types/commands/manifest/generate_auto_manifest.d.mts +4 -1
- package/dist/types/commands/manifest/generate_auto_manifest.d.mts.map +1 -1
- package/dist/types/commands/manifest/run-manifest-facts.d.mts +2 -1
- package/dist/types/commands/manifest/run-manifest-facts.d.mts.map +1 -1
- package/dist/types/commands/manifest/scripts/run.d.mts +4 -0
- package/dist/types/commands/manifest/scripts/run.d.mts.map +1 -1
- package/dist/types/commands/scan/exclude-paths.d.mts +2 -2
- package/dist/types/commands/scan/exclude-paths.d.mts.map +1 -1
- package/dist/types/commands/scan/handle-create-new-scan.d.mts.map +1 -1
- package/dist/types/utils/api.d.mts.map +1 -1
- package/dist/types/utils/dlx.d.mts.map +1 -1
- package/dist/types/utils/sdk.d.mts +1 -0
- package/dist/types/utils/sdk.d.mts.map +1 -1
- package/dist/utils.js +19 -6
- package/dist/utils.js.map +1 -1
- package/package.json +2 -2
|
@@ -38,6 +38,17 @@ object SocketFactsPlugin extends AutoPlugin {
|
|
|
38
38
|
val extracted = Project.extract(st)
|
|
39
39
|
val allRefs = extracted.structure.allProjectRefs
|
|
40
40
|
|
|
41
|
+
// `-Dsocket.excludePaths` (scan-root-relative globs): a subproject whose dir is wholly excluded is
|
|
42
|
+
// never resolved and emits no project record. Source-file-level exclusion is left to the analysis.
|
|
43
|
+
val excludeMatchers = parseExcludeMatchers()
|
|
44
|
+
val rootCanonPath = buildRoot.getCanonicalFile.toPath
|
|
45
|
+
def relOf(f: File): String = {
|
|
46
|
+
val r = rootCanonPath.relativize(f.getCanonicalFile.toPath).toString.replace(java.io.File.separator, "/")
|
|
47
|
+
if (r.isEmpty) "." else r
|
|
48
|
+
}
|
|
49
|
+
def isExcludedRef(ref: ProjectRef): Boolean =
|
|
50
|
+
isExcludedPath(relOf(extracted.get(baseDirectory.in(ref))), excludeMatchers)
|
|
51
|
+
|
|
41
52
|
// Prefer `updateFull` (coursier `update` returns empty callers); fall back to `update` (sbt 0.13).
|
|
42
53
|
val hasUpdateFull =
|
|
43
54
|
extracted.structure.settings.map(_.key.key).exists(_.label == "updateFull")
|
|
@@ -53,9 +64,11 @@ object SocketFactsPlugin extends AutoPlugin {
|
|
|
53
64
|
val moduleExts = buildModuleExts(allRefs, extracted)
|
|
54
65
|
|
|
55
66
|
allRefs.foreach { ref =>
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
67
|
+
if (!isExcludedRef(ref)) {
|
|
68
|
+
runUpdateResilient(updateTaskName, ref, extracted, st, failures).foreach { report =>
|
|
69
|
+
foldReport(report, ref, extracted, matcher, scannedConfigs, withFiles, populateScope, moduleExts).foreach {
|
|
70
|
+
case (rootKey, tree) => perSub(rootKey) = tree
|
|
71
|
+
}
|
|
59
72
|
}
|
|
60
73
|
}
|
|
61
74
|
}
|
|
@@ -63,12 +76,6 @@ object SocketFactsPlugin extends AutoPlugin {
|
|
|
63
76
|
val moduleDirs: Map[String, (Seq[String], Seq[String])] =
|
|
64
77
|
if (withFiles) buildModuleDirs(allRefs, extracted) else Map.empty
|
|
65
78
|
|
|
66
|
-
val rootPath = buildRoot.getCanonicalFile.toPath
|
|
67
|
-
def relOf(f: File): String = {
|
|
68
|
-
val r = rootPath.relativize(f.getCanonicalFile.toPath).toString.replace(java.io.File.separator, "/")
|
|
69
|
-
if (r.isEmpty) "." else r
|
|
70
|
-
}
|
|
71
|
-
|
|
72
79
|
val sb = new StringBuilder
|
|
73
80
|
def rec(fields: String*): Unit = {
|
|
74
81
|
sb.append(fields.map(esc).mkString("\t")); sb.append('\n')
|
|
@@ -76,16 +83,19 @@ object SocketFactsPlugin extends AutoPlugin {
|
|
|
76
83
|
|
|
77
84
|
rec("meta", "sbt", extracted.getOpt(sbtVersion).getOrElse(""), sys.props.getOrElse("java.version", ""))
|
|
78
85
|
|
|
79
|
-
// One `project` record per build module (sources/targets only with --with-files).
|
|
86
|
+
// One `project` record per build module (sources/targets only with --with-files). Excluded
|
|
87
|
+
// subprojects are omitted (they were also skipped during resolution above).
|
|
80
88
|
allRefs.foreach { ref =>
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
+
if (!isExcludedRef(ref)) {
|
|
90
|
+
val mid = rootIdOf(extracted, ref)
|
|
91
|
+
val ver = if (mid.revision == null) "" else mid.revision
|
|
92
|
+
rec("project", ref.project, mid.organization, mid.name, ver, relOf(extracted.get(baseDirectory.in(ref))))
|
|
93
|
+
if (withFiles) {
|
|
94
|
+
moduleDirs.get(mid.organization + ":" + mid.name + ":" + ver).foreach {
|
|
95
|
+
case (sources, targets) =>
|
|
96
|
+
sources.foreach(s => rec("projectSrc", ref.project, s))
|
|
97
|
+
targets.foreach(t => rec("projectTgt", ref.project, t))
|
|
98
|
+
}
|
|
89
99
|
}
|
|
90
100
|
}
|
|
91
101
|
}
|
|
@@ -141,6 +151,8 @@ object SocketFactsPlugin extends AutoPlugin {
|
|
|
141
151
|
|
|
142
152
|
// Absolute source roots + compiled-output dirs per build module, keyed by GAV. --with-files only;
|
|
143
153
|
// absolute because reachability locates an internal module's code on THIS machine (no registry jar).
|
|
154
|
+
// ALL of the project's configurations are scanned (not just Compile/Test) so custom ones
|
|
155
|
+
// (IntegrationTest, ...) reach the analysis; source-file-level exclusion is coana's job.
|
|
144
156
|
private def buildModuleDirs(
|
|
145
157
|
allRefs: Seq[ProjectRef],
|
|
146
158
|
extracted: Extracted
|
|
@@ -148,10 +160,12 @@ object SocketFactsPlugin extends AutoPlugin {
|
|
|
148
160
|
allRefs.map { ref =>
|
|
149
161
|
val mid = rootIdOf(extracted, ref)
|
|
150
162
|
val ver = if (mid.revision == null) "" else mid.revision
|
|
151
|
-
val
|
|
163
|
+
val configs: Seq[Configuration] =
|
|
164
|
+
extracted.getOpt(thisProject.in(ref)).map(_.configurations).getOrElse(Seq(Compile, Test))
|
|
165
|
+
val sources = configs
|
|
152
166
|
.flatMap(c => extracted.getOpt(sourceDirectories.in(ref).in(c)).getOrElse(Nil))
|
|
153
167
|
.map(_.getAbsolutePath).distinct.sorted
|
|
154
|
-
val targets =
|
|
168
|
+
val targets = configs
|
|
155
169
|
.flatMap(c => extracted.getOpt(classDirectory.in(ref).in(c)))
|
|
156
170
|
.map(_.getAbsolutePath).distinct.sorted
|
|
157
171
|
(mid.organization + ":" + mid.name + ":" + ver) -> ((sources, targets))
|
|
@@ -378,6 +392,69 @@ object SocketFactsPlugin extends AutoPlugin {
|
|
|
378
392
|
catch { case _: Throwable => c.toString }
|
|
379
393
|
}
|
|
380
394
|
|
|
395
|
+
// `-Dsocket.excludePaths` → glob PathMatchers, used only to skip whole excluded subprojects. Each
|
|
396
|
+
// entry variant yields the entry itself and `entry/**` so it matches the dir and its subtree (same expansion
|
|
397
|
+
// as the SCA ignore path). A trailing `/**` is stripped first, so a user-written `dir/**` still excludes the
|
|
398
|
+
// `dir` directory itself, not only its contents. Standard glob semantics (anchored to the scan root, matching
|
|
399
|
+
// the CLI flag): `x` is root-level, `**/x` matches at any depth. Mirrors the gradle/maven producers.
|
|
400
|
+
private def parseExcludeMatchers(): Seq[java.nio.file.PathMatcher] = {
|
|
401
|
+
sys.props.get("socket.excludePaths").map(_.trim).filter(_.nonEmpty) match {
|
|
402
|
+
case None => Nil
|
|
403
|
+
case Some(raw) =>
|
|
404
|
+
val fs = java.nio.file.FileSystems.getDefault
|
|
405
|
+
raw.split(",").toSeq.flatMap { r =>
|
|
406
|
+
var g = r.trim.replace("\\", "/")
|
|
407
|
+
while (g.startsWith("/")) g = g.substring(1)
|
|
408
|
+
while (g.endsWith("/")) g = g.substring(0, g.length - 1)
|
|
409
|
+
while (g.endsWith("/**")) {
|
|
410
|
+
g = g.substring(0, g.length - 3)
|
|
411
|
+
while (g.endsWith("/")) g = g.substring(0, g.length - 1)
|
|
412
|
+
}
|
|
413
|
+
if (g.isEmpty) Nil
|
|
414
|
+
else zeroDepthVariants(g).flatMap { v =>
|
|
415
|
+
Seq(fs.getPathMatcher("glob:" + v), fs.getPathMatcher("glob:" + v + "/**"))
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// NIO glob requires a slash-adjacent `**` to consume at least one path segment, but the CLI's
|
|
422
|
+
// micromatch lets it match zero (`**/x` matches root-level `x`). Emit every variant with `**/`
|
|
423
|
+
// occurrences dropped so both semantics hold.
|
|
424
|
+
private def zeroDepthVariants(glob: String): Seq[String] = {
|
|
425
|
+
val out = mutable.LinkedHashSet[String]()
|
|
426
|
+
val work = mutable.Queue(glob)
|
|
427
|
+
while (work.nonEmpty) {
|
|
428
|
+
val cur = work.dequeue()
|
|
429
|
+
if (out.add(cur)) {
|
|
430
|
+
var idx = cur.indexOf("**/")
|
|
431
|
+
while (idx >= 0) {
|
|
432
|
+
if (idx == 0 || cur.charAt(idx - 1) == '/') {
|
|
433
|
+
val collapsed = cur.substring(0, idx) + cur.substring(idx + 3)
|
|
434
|
+
if (collapsed.nonEmpty) work.enqueue(collapsed)
|
|
435
|
+
}
|
|
436
|
+
idx = cur.indexOf("**/", idx + 1)
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
out.toSeq
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
private def isExcludedPath(rel: String, matchers: Seq[java.nio.file.PathMatcher]): Boolean = {
|
|
444
|
+
if (matchers.isEmpty) false
|
|
445
|
+
else {
|
|
446
|
+
var c = (if (rel == null) "" else rel).replace("\\", "/")
|
|
447
|
+
while (c.startsWith("./")) c = c.substring(2)
|
|
448
|
+
while (c.startsWith("/")) c = c.substring(1)
|
|
449
|
+
while (c.endsWith("/")) c = c.substring(0, c.length - 1)
|
|
450
|
+
if (c.isEmpty) false
|
|
451
|
+
else {
|
|
452
|
+
val p = java.nio.file.Paths.get(c)
|
|
453
|
+
matchers.exists(_.matches(p))
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
|
|
381
458
|
private def isTestConf(name: String): Boolean = name.toLowerCase.contains("test")
|
|
382
459
|
|
|
383
460
|
// Only feeds the informational `dev` flag, never gates analysis.
|