Skip to content

Commit e042d63

Browse files
committed
updated site
1 parent 3b4d47a commit e042d63

10 files changed

+170
-22
lines changed

2.x/docs/en/changes/migrating-from-sbt-1.x.html

+51-5
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,11 @@ <h2 id="bare-settings-changes"><a class="header" href="#bare-settings-changes">B
203203
</code></pre>
204204
<h3 id="migrating-thisbuild"><a class="header" href="#migrating-thisbuild">Migrating ThisBuild</a></h3>
205205
<p>In sbt 2.x, bare settings settings should no longer be scoped to <code>ThisBuild</code>. One benefit of the new <em>common settings</em> over <code>ThisBuild</code> is that it would act in a more predictable delegation. These settings are inserted between plugins settings and those defined in <code>settings(...)</code>, meaning they can be used to define settings like <code>Compile / scalacOptions</code>, which was not possible with <code>ThisBuild</code>.</p>
206+
<h2 id="migrating-to-slash-syntax"><a class="header" href="#migrating-to-slash-syntax">Migrating to slash syntax</a></h2>
207+
<p>sbt 1.x supported both the sbt 0.13 style syntax and the slash syntax. sbt 2.x removes the support for the sbt 0.13 syntax, so use the slash syntax for both sbt shell and in <code>build.sbt</code>:</p>
208+
<pre><code class="language-scala">&lt;project-id&gt; / Config / intask / key
209+
</code></pre>
210+
<p>For example, <code>test:compile</code> will no longer work on the shell. Use <code>Test/compile</code> instead. See <a href="https://eed3si9n.com/syntactic-scalafix-rule-for-unified-slash-syntax/">syntactic Scalafix rule for unified slash syntax</a> for semi-automated migration of <code>build.sbt</code> files.</p>
206211
<h2 id="cross-building-sbt-plugins"><a class="header" href="#cross-building-sbt-plugins">Cross building sbt plugins</a></h2>
207212
<p>In sbt 2.x, if you cross build an sbt plugin with Scala 3.x and 2.12.x, it will automatically cross build against sbt 1.x and sbt 2.x:</p>
208213
<pre><code class="language-scala">// using sbt 2.x
@@ -233,18 +238,59 @@ <h3 id="cross-building-sbt-plugin-with-sbt-1x"><a class="header" href="#cross-bu
233238
},
234239
)
235240
</code></pre>
236-
<h2 id="migrating-to-slash-syntax"><a class="header" href="#migrating-to-slash-syntax">Migrating to slash syntax</a></h2>
237-
<p>sbt 1.x supported both the sbt 0.13 style syntax and the slash syntax. sbt 2.x removes the support for the sbt 0.13 syntax, so use the slash syntax for both sbt shell and in <code>build.sbt</code>:</p>
238-
<pre><code class="language-scala">&lt;project-id&gt; / Config / intask / key
239-
</code></pre>
240-
<p>For example, <code>test:compile</code> will no longer work on the shell. Use <code>Test/compile</code> instead. See <a href="https://eed3si9n.com/syntactic-scalafix-rule-for-unified-slash-syntax/">syntactic Scalafix rule for unified slash syntax</a> for semi-automated migration of <code>build.sbt</code> files.</p>
241241
<h2 id="changes-to-"><a class="header" href="#changes-to-">Changes to <code>%%</code></a></h2>
242242
<p>In sbt 2.x, <code>ModuleID</code>'s <code>%%</code> operator has become platform-aware. For JVM subprojects, <code>%%</code> works as before, encoding Scala suffix (for example <code>_3</code>) on Maven repositories.</p>
243243
<h3 id="migrating--operator"><a class="header" href="#migrating--operator">Migrating <code>%%%</code> operator</a></h3>
244244
<p>When Scala.JS or Scala Native becomes available on sbt 2.x, <code>%%</code> will encode both the Scala version (such as <code>_3</code>) and the platform suffix (<code>_sjs1</code> etc). As a result, <code>%%%</code> can be replaced with <code>%%</code>:</p>
245245
<pre><code class="language-scala">libraryDependencies += "org.scala-js" %% "scalajs-dom" % "2.8.0"
246246
</code></pre>
247247
<p>Use <code>.platform(Platform.jvm)</code> in case where JVM libraries are needed.</p>
248+
<h2 id="the-plugincompat-technique"><a class="header" href="#the-plugincompat-technique">The PluginCompat technique</a></h2>
249+
<p>To use the same <code>*.scala</code> source but target both sbt 1.x and 2.x, we can create a shim, for example an object named <code>PluginCompat</code> in both <code>src/main/scala-2.12/</code> and <code>src/main/scala-3/</code>.</p>
250+
<h3 id="migrating-classpath-type"><a class="header" href="#migrating-classpath-type">Migrating Classpath type</a></h3>
251+
<p>sbt 2.x changed the <code>Classpath</code> type to be an alias of the <code>Seq[Attributed[xsbti.HashedVirtualFileRef]]</code> type. The following is a shim created to work with classpaths from both sbt 1.x and 2.x.</p>
252+
<pre><code class="language-scala">// src/main/scala-3/PluginCompat.scala
253+
254+
package sbtfoo
255+
256+
import java.nio.file.{ Path =&gt; NioPath }
257+
import sbt.*
258+
import xsbti.{ FileConverter, HashedVirtualFileRef, VirtualFile }
259+
260+
private[sbtfoo] object PluginCompat:
261+
type FileRef = HashedVirtualFileRef
262+
type Out = VirtualFile
263+
264+
def toNioPath(a: Attributed[HashedVirtualFileRef])(using conv: FileConverter): NioPath =
265+
conv.toPath(a.data)
266+
inline def toFile(a: Attributed[HashedVirtualFileRef])(using conv: FileConverter): File =
267+
toNioPath(a).toFile()
268+
def toNioPaths(cp: Seq[Attributed[HashedVirtualFileRef]])(using conv: FileConverter): Vector[NioPath] =
269+
cp.map(toNioPath).toVector
270+
inline def toFiles(cp: Seq[Attributed[HashedVirtualFileRef]])(using conv: FileConverter): Vector[File] =
271+
toNioPaths(cp).map(_.toFile())
272+
end PluginCompat
273+
</code></pre>
274+
<p>and here's for sbt 1.x:</p>
275+
<pre><code class="language-scala">// src/main/scala-2.12/PluginCompat.scala
276+
277+
package sbtfoo
278+
279+
private[sbtfoo] object PluginCompat {
280+
type FileRef = java.io.File
281+
type Out = java.io.File
282+
283+
def toNioPath(a: Attributed[File])(implicit conv: FileConverter): NioPath =
284+
a.data.toPath()
285+
def toFile(a: Attributed[File])(implicit conv: FileConverter): File =
286+
a.data
287+
def toNioPaths(cp: Seq[Attributed[File]])(implicit conv: FileConverter): Vector[NioPath] =
288+
cp.map(_.data.toPath()).toVector
289+
def toFiles(cp: Seq[Attributed[File]])(implicit conv: FileConverter): Vector[File] =
290+
cp.map(_.data).toVector
291+
}
292+
</code></pre>
293+
<p>Now we can import <code>PluginCompat.*</code> and use <code>toNioPaths(...)</code> etc to absorb the differences between sbt 1.x and 2.x. The above demonstrates how we can absorb the classpath type change, and convert it into a vector of NIO Paths.</p>
248294

249295
</main>
250296

2.x/docs/en/changes/sbt-2.0-change-summary.html

+1
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ <h2 id="changes-with-compatibility-implications"><a class="header" href="#change
198198
<li>sbt 2.x plugins are published with <code>_sbt2_3</code> suffix by <a href="https://github.com/eed3si9n">@eed3si9n</a> in <a href="https://github.com/sbt/sbt/pull/7671">#7671</a></li>
199199
<li>sbt 2.x adds <code>platform</code> setting so <code>ModuleID</code>'s <code>%%</code> operator can cross build on JVM as well as JS and Native, as opposed to <code>%%%</code> operator that was created in a plugin to workaround this issue, by <a href="https://github.com/eed3si9n">@eed3si9n</a> in <a href="https://github.com/sbt/sbt/pull/6746">#6746</a></li>
200200
<li>Dropped <code>useCoursier</code> setting so Coursier cannot be opted out, by <a href="https://github.com/eed3si9n">@eed3si9n</a> in <a href="https://github.com/sbt/sbt/pull/7712">#7712</a></li>
201+
<li><code>Key.Classpath</code> is changed to be an alias of the <code>Seq[Attributed[xsbti.HashedVirtualFileRef]]</code> type, instead of <code>Seq[Attributed[File]]</code>. Similarly, some task keys that used to return <code>File</code> have changed to return <code>HashedVirtualFileRef</code> instead. See <a href="../concepts/caching.html#caching-files">Caching Files</a>.</li>
201202
</ul>
202203
<h3 id="dropped-dreprecations"><a class="header" href="#dropped-dreprecations">Dropped dreprecations</a></h3>
203204
<ul>

2.x/docs/en/concepts/caching.html

+27
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,33 @@ <h2 id="automatic-caching"><a class="header" href="#automatic-caching">Automatic
205205
[info] demo0.1.0-SNAPSHOT!
206206
[success] elapsed time: 0 s, cache 100%, 1 disk cache hit
207207
</code></pre>
208+
<h3 id="caching-is-serializaiton-hard"><a class="header" href="#caching-is-serializaiton-hard">Caching is serializaiton-hard</a></h3>
209+
<p>To participate in the automatic caching, the input keys (e.g. <code>name</code> and <code>version</code>) must provide a given for <code>sjsonnew.HashWriter</code> typeclass and return type must provide a given for <code>sjsonnew.JsonFormat</code>. <a href="https://www.scala-sbt.org/contraband/">Contraband</a> can be used to generate sjson-new codecs.</p>
210+
<h2 id="caching-files"><a class="header" href="#caching-files">Caching files</a></h2>
211+
<p>Caching files (e.g. <code>java.io.File</code>) requires its own consideration, not because it's technically difficult, but mostly because of the ambiguity and assumptions when files are involved. When we say a "file" it could actually mean:</p>
212+
<ol>
213+
<li>Relative path from a well-known location</li>
214+
<li>Materialized actual file</li>
215+
<li>A unique proof of a file, or a content hash</li>
216+
</ol>
217+
<p>Technically speaking, a <code>File</code> just means the file path, so we can deserialize just the filename such as <code>target/a/b.jar</code>. This will fail the downstream tasks if they assumed that <code>target/a/b.jar</code> would exist in the file system. For clarity, and also for avoiding to capture absolute paths, sbt 2.x provides three separate types for the three cases.</p>
218+
<ul>
219+
<li><code>xsbti.VirtualFileRef</code> is used to mean just the relative path, which is equivalent to passing a string</li>
220+
<li><code>xsbti.VirtualFile</code> represents a materialized file with contents, which could be a virtual file or a file in your disk</li>
221+
</ul>
222+
<p>However, for the purpose of hermetic build, neither is great to represent a list of files. Having just the filename alone doesn't guarantee that the file will be the same, and carrying the entire content of the files is too inefficient in a JSON etc.</p>
223+
<p>This is where the mysterious third option, a unique proof of file comes in handy. In addition to the relative path, <code>HashedVirtualFileRef</code> tracks the SHA-256 content hash and the file size. This can easily be serialized to JSON yet we can reference the exact file.</p>
224+
<h3 id="the-effect-of-file-creation"><a class="header" href="#the-effect-of-file-creation">The effect of file creation</a></h3>
225+
<p>There are many tasks that generate file that do not use <code>VirtualFile</code> as the return type. For example, <code>compile</code> returns <code>Analysis</code> instead, and <code>*.class</code> file generation happens as a <em>side effect</em> in sbt 1.x.</p>
226+
<p>To participate in caching, we need to declare these effects as something we care about.</p>
227+
<pre><code class="language-scala">someKey := Def.cachedTask {
228+
val conv = fileConverter.value
229+
val out: java.nio.file.Path = createFile(...)
230+
val vf: xsbti.VirtualFile = conv.toVirtualFile(out)
231+
Def.declareOutput(vf)
232+
vf: xsbti.HashedVirtualFileRef
233+
}
234+
</code></pre>
208235
<h2 id="remote-caching"><a class="header" href="#remote-caching">Remote caching</a></h2>
209236
<p>You can optionally extend the build to use remote cache in addition to the local disk cache. Remote caching could improve build performance by allowing multiple machines to share build artifacts and outputs.</p>
210237
<p>Imagine you have a dozen people in your project or a company. Each morning, you will <code>git pull</code> the changes the dozen people made, and you need to build their code. If you have a successful project, the code size will only get bigger over time, and the % of the time you spend building someone else's in your day increases. This becomes the limiting factor of your team size and code size. Remote caching reverses this tide by CI systems hydrate the cache and you can download the artifacts and task outputs.</p>

0 commit comments

Comments
 (0)