Skip to content

Commit e728b5e

Browse files
committed
Fix source map URLs (as much as possible). Fixes cquiroz#519
1 parent 3f25107 commit e728b5e

File tree

3 files changed

+55
-3
lines changed

3 files changed

+55
-3
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ on:
1515
tags: [v*]
1616

1717
env:
18+
CI: true
1819
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
1920

2021

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,5 @@ tzdb/js/src/main/resources/
4141
project/metals.sbt
4242
.direnv/
4343
.bsp/
44+
45+
.DS_Store

build.sbt

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,11 @@ lazy val commonSettings = Seq(
9494
/**
9595
* Copy source files and translate them to the java.time package
9696
*/
97-
def copyAndReplace(srcDirs: Seq[File], destinationDir: File): Seq[File] = {
97+
def copyAndReplace(
98+
srcDirs: Seq[File],
99+
destinationDir: File,
100+
createNestedDirs: Boolean = false
101+
): Seq[File] = {
98102
// Copy a directory and return the list of files
99103
def copyDirectory(
100104
source: File,
@@ -112,7 +116,12 @@ def copyAndReplace(srcDirs: Seq[File], destinationDir: File): Seq[File] = {
112116
// Copy the source files from the base project, exclude classes on java.util and dirs
113117
val generatedFiles: List[java.io.File] = onlyScalaDirs
114118
.foldLeft(Set.empty[File]) { (files, sourceDir) =>
115-
files ++ copyDirectory(sourceDir, destinationDir, overwrite = true)
119+
val targetDestinationDir = if (createNestedDirs) {
120+
destinationDir / sourceDir.getName
121+
} else {
122+
destinationDir
123+
}
124+
files ++ copyDirectory(sourceDir, targetDestinationDir, overwrite = true)
116125
}
117126
.filterNot(_.isDirectory)
118127
.filter(_.getName.endsWith(".scala"))
@@ -141,6 +150,7 @@ def copyAndReplace(srcDirs: Seq[File], destinationDir: File): Seq[File] = {
141150
lazy val core = crossProject(JVMPlatform, JSPlatform, NativePlatform)
142151
.crossType(CrossType.Full)
143152
.in(file("core"))
153+
.disablePlugins(TypelevelScalaJSGitHubPlugin)
144154
.settings(commonSettings)
145155
.settings(
146156
name := "scala-java-time",
@@ -152,10 +162,11 @@ lazy val core = crossProject(JVMPlatform, JSPlatform, NativePlatform)
152162
if (tlIsScala3.value) Seq("-scalajs-genStaticForwardersForNonTopLevelObjects")
153163
else Seq("-P:scalajs:genStaticForwardersForNonTopLevelObjects")
154164
},
165+
scalaJsGithubSourceMaps("core/shared"),
155166
Compile / sourceGenerators += Def.task {
156167
val srcDirs = (Compile / sourceDirectories).value
157168
val destinationDir = (Compile / sourceManaged).value
158-
copyAndReplace(srcDirs, destinationDir)
169+
copyAndReplace(srcDirs, destinationDir, createNestedDirs = true)
159170
}.taskValue,
160171
libraryDependencies ++= Seq(
161172
"io.github.cquiroz" %%% "scala-java-locales" % scalajavaLocalesVersion
@@ -265,3 +276,41 @@ lazy val demo = crossProject(JSPlatform, JVMPlatform, NativePlatform)
265276
.nativeSettings(
266277
tzdbPlatform := TzdbPlugin.Platform.Native
267278
)
279+
280+
def scalaJsGithubSourceMaps(projectDir: String) = {
281+
// - Unfortunately we can only specify one `projectDir`.
282+
// So, if our JS project has sources in both `core/js` and `core/shared`,
283+
// we can only pick one of those, and all sources in the other one will have
284+
// broken URLs in source maps.
285+
// - The root of the problem is that in `copyAndReplace` we copy the contents of
286+
// multiple source directories into a single src_managed directory, and so we
287+
// lose information about where our sources originally came from, and even if we
288+
// could capture or recover this information, the syntax of `mapSourceURI` option
289+
// doesn't allow more than one mapping, so we probably wouldn't be able to use it
290+
// to create multiple mappings.
291+
// - Also, for the same reason, we are unable to map sources that are not copied
292+
// to src_managed (stuff under java.util). Those will have invalid file: URLs.
293+
// - In the future, maybe we can somehow adjust the folder structure inside `src_managed`
294+
// to introduce new top level directories matching project names (`core`).
295+
// - The CI env var is set by Github actions automatically.
296+
// We only want this transformation to run when creating & publishing an artifact to Maven,
297+
// as this lets us use the original local file paths for local dev / publishLocal.
298+
// ---
299+
// - How to test changes to this code locally:
300+
// - Make sure the sys.env.get("CI") filter passes, one way or another
301+
// - publishLocal the core project (press enter to skip passphrase, don't need signing)
302+
// - find the resulting jar – see file path in sbt output. Open it (it's a zip archive).
303+
// - find .sjsir files inside the jar, open some of them with plain text editor
304+
// - in the first bytes of the binary, observe the raw.githubusercontent.com URL in plaintext
305+
// - copy-paste that URL into the browser.
306+
// - It should show the contents of this file on github (subject to caveats above)
307+
// - If it doesn't, make sure the version / commit hash you have locally exists on github (or fake it).
308+
scalacOptions ++= sys.env.get("CI").map { _ =>
309+
val localCopiedSourcesPath = (Compile / sourceManaged).value.toURI
310+
val remoteSourcesPath =
311+
s"https://raw.githubusercontent.com/cquiroz/scala-java-time/${git.gitHeadCommit.value.get}/${projectDir}/src/main/"
312+
val sourcesOptionName =
313+
if (tlIsScala3.value) "-scalajs-mapSourceURI" else "-P:scalajs:mapSourceURI"
314+
s"${sourcesOptionName}:$localCopiedSourcesPath->$remoteSourcesPath"
315+
}
316+
}

0 commit comments

Comments
 (0)