Commit Graph

179 Commits

Author SHA1 Message Date
Eugene Yokota b0b7705739 Fixes Debian 11 compat
Fixes https://github.com/sbt/sbt/issues/7118

Problem
-------
sbtn 1.8.1 was built using ubuntu-latest, which meant picking up newer
glibc.

Solution
--------
This downgraded the ubuntu machine to build sbtn.
2023-01-04 17:19:29 -05:00
Matthias Kurz ac638a764d
Use latest sbtn 2023-01-03 16:02:18 +01:00
Matthias Kurz 5fa46859d2
Make use of sbtn aarch64 binary where possible 2023-01-03 12:41:49 +01:00
Arnout Engelen 8973fce1fa
More flexible Scala version switch
By using SemanticSelector instead of custom globbing.

Follow-up on https://github.com/sbt/sbt/pull/6894,
fixes https://github.com/sbt/sbt/issues/6934
2022-06-26 12:43:41 +02:00
Arnout Engelen cd915845db Add support for wildcards in Scala version switch
Picking from the `crossScalaVersions`

As discussed in https://github.com/sbt/sbt/discussions/6893
2022-06-24 01:41:38 -04:00
eugene yokota b3aae681bf
Merge pull request #6711 from xuwei-k/fix-scala-2-13-warn
fix Scala 2.13 warnings
2021-11-14 21:53:57 -05:00
xuwei-k 535b15b83e fix Scala 2.13 warnings 2021-11-14 22:59:34 +09:00
xuwei-k aa8b1141f8 Update scalatest 2021-11-14 22:03:59 +09:00
Amina Adewusi 3c81e08fa2 Migrates Treeview.scala to use Contraband
Migrates TreeView.scala to use Contraband from scala.util.parsing.json,
because this is now deprecated.
The TreeView logic is used in the dependencyBrowseTree task.
2021-11-12 16:52:12 +00:00
kxbmap 24e7398b5b Add Windows Java home selectors for some distributions that provides an installer
- Eclipse Temurin
- IBM Semeru Runtimes
- Microsoft Build of OpenJDK
- Amazon Corretto
- Azul Zulu Builds of OpenJDK
- Liberica JDK
2021-10-02 16:56:12 +09:00
Nima Taheri fcd7a3bef2 Handle cycles while rendering json dependency tree to json 2021-09-28 11:28:20 -07:00
Adrien Piquerez a76e209dde [BSP] send diagnostics when evaluating build.sbt
Since build.sbt is compiled/evaluated in `sbt.compiler.Eval`,
this commit introduces a `BuildServerEvalReporter` to redirect
the compiler errors to the BSP clients.

A new `finalReport` method is added in the new `EvalReporter` base class
to reset the old diagnostics.
2021-07-08 09:25:01 +02:00
Jason Zaugg 3d92827af3 Fix compilation error in test 2021-06-30 12:12:24 +10:00
Eugene Yokota 5deb1f5994 Fix configuration identifier completion
Fixes https://github.com/sbt/sbt/issues/6282
2021-01-23 22:15:06 -05:00
Eugene Yokota 98450fe743 Add half-failing tests for completions 2021-01-16 03:48:57 -05:00
Eugene Yokota 1c6a5d21bb Port mutable.Specification to verify.BasicTestSuite 2021-01-16 00:47:53 -05:00
Eugene Yokota 8f5759e48d Cross build to Scala 2.13 2021-01-10 20:24:05 -05:00
Naftoli Gugenheim 889b101cbd Update tests for fixed GCMonitor 2020-11-15 00:00:50 -05:00
Naftoli Gugenheim 6cca595420 Add file headers 2020-11-15 00:00:50 -05:00
Naftoli Gugenheim 1c258b8fc9 GCMonitor: Unit tests, refactor, and improve
* Refactor so as to be testable
 * Queue stores the _beginning_ timestamp of each GC time delta
 * Message states the correct time over which the GC time was recorded
 * Add heap stats from java.lang.Runtime to the message
2020-11-15 00:00:50 -05:00
Naftoli Gugenheim af7346f565 Program to manually test GCMonitor 2020-11-15 00:00:50 -05:00
Ethan Atkins 37e4dc5318 Disable InstallSbtnSpec
This test works fine locally on all platforms but there are issues in
CI. I think that it might work ok with 1.4.2 without a lot of extra
effort so I'm going to disable it for now.
2020-10-26 10:15:46 -07:00
Ethan Atkins beab10fc64 Add wizard for installing sbtn and completions
This commit adds a wizard for installing sbtn along with tab completions
for bash, fish, powershell and zsh. It introduces the `installSbtn`
command which installs sbtn into ~/.sbt/1.0/bin/sbtn(.exe) depending on
the platform. It also can optionally install completions. The
completions are installed into ~/.sbt/1.0/completions. The sbtn native
executable is installed by downloading the sbt universal zip for the
version (which can be provided as an input argument with a fallback to
the running sbt version) and extracting the platform specific binary
into ~/.sbt/1.0/bin. After installing the executable, it offers to setup
the path and completions for the four shells. With the user's consent,
it adds a line to the shell config that updates the path to include
~/.sbt/1.0/bin and another line to source the appropriate completion
file for the shell from ~/.sbt/1.0/completions.
2020-10-26 10:15:46 -07:00
Ethan Atkins b85209be78 Add sbt.Terminal trait
It can be useful for plugin and build authors to have access to some of
the virtual terminal properties. For instance, when writing a task that
needs a password, the author may wish to put the terminal in raw mode
with echo disabled. This commit introduces a new Terminal trait at the
sbt level and a corresponding task, terminal, that provides a basic
terminal api. The Terminal returned by the terminal task will correspond
to the terminal that initiated the task so that it should work with sbtn
as well as in console mode.
2020-09-27 13:33:47 -07:00
Ethan Atkins 525cff7fd7 Use java caffeine library rather than scalacache
sbt depends on scalacache (which hasn't been updated in about a year)
and we really don't need the functionality provided by scalacache. In
fact, the java api is somewhat easier to work with for our use case. The
motivation is that scalacache uses slf4j for logging which meant that it
was implicitly loading log4j. This caused some noisy logs during
shutdown when the previously unused cache was initialized just to be
cleaned up.

This commit also upgrades caffeine and moving forward we can always
upgrade caffeine (and potentially shade it) without any conflict with
the scalacache version.
2020-08-07 17:18:09 -07:00
Ethan Atkins 6565618a15 Cache compiled map during build load
The continuous command recompiles the setting graph into a CompiledMap
data structure so that it can determine which files it needs to
transitively monitor during watch. Generating the CompiledMap can be
very slow for large projects (5 seconds or so on my computer in the sbt
project) and this startup cost is paid every time the user enters a
watch with `~`. To avoid this, we can cache the compile map that is
generated during the initial settings evaluation.

The only real drawback I can see is that the compiled map is guaranteed
to remain in memory so long as the BuildStructure instance that holds it
is alive. Given the performance benefit, this seems like a worthwhile
tradeoff.
2020-07-03 14:08:26 -07:00
Ethan Atkins a2047a0b2c Refactor watch
The existing implementation of watch did not work with the thin client.
In sbt 1.3.0, watch was changed to be a blocking command that performed
manual task evaluation. This commit makes the implementation more
similar to < 1.3.0 where watch modifies the state and after running the
user specified command(s), it enters a blocking command. The new
blocking command is very similar to the shell command.

As part of this change, I also reworked some of the internals of watch
so that a number of threads are spawned for reading file and input
events. By using background threads that write to a single event queue,
we are able to block on the file events and terminal input stream rather
than polling. After this change, the cpu utilization as measured by ps
drops from roughly 2% of a cpu to 0.

To integrate with the network client, we introduce a new UITask that is
similar to the AskUserTask but instead of reading lines and adding execs
to the command queue, it reads characters and converts them into watch
commands that we also append to the command queue.

With this new implementation, the watch task that was added in 1.3.0 no
longer works. My guess is that no one was really using it. It wasn't
documented anywhere. The motivation for the task implementation was that
it could be called within another task which would let users define a
task that monitors for file changes before running. Since this had never
been advertised and is only of limited utility anyway, I think it's fine
to break it.

I also had to disable the input-parser and symlinks tests. I'm not 100%
sure why the symlinks test was failing. It would tend to work on my
machine but fail in CI. I gave up on debugging it. The input-parser test
also fails but would be a good candidate to be moved to the client test
in the serverTestProj. At any rate, it was testing a code path that was
only exercised if the user changed the watchInputStream method which is
highly unlikely to have been done in any user builds.

The WatchSpec had become a nuisance and wasn't really preventing from
any regressions so I removed it. The scripted tests are how we test
watch.
2020-06-25 10:05:59 -07:00
Ethan Atkins ba345dd797 Add multi-client ui to server
This commit makes it possible for the sbt server to render the same ui
to multiple clients. The network client ui should look nearly identical
to the console ui except for the log messages about the experimental
client.

The way that it works is that it associates a ui thread with each
terminal. Whenever a command starts or completes, callbacks are invoked
on the various channels to update their ui state. For example, if there
are two clients and one of them runs compile, then the prompt is changed
from AskUser to Running for the terminal that initiated the command
while the other client remains in the AskUser state. Whenever the client
changes uses ui states, the existing thread is terminated if it is
running and a new thread is begun.

The UITask formalizes this process. It is based on the AskUser class
from older versions of sbt. In fact, there is an AskUserTask which is
very similar. It uses jline to read input from the terminal (which could
be a network terminal). When it gets a line, it submits it to the
CommandExchange and exits. Once the next command is run (which may or
may not be the command it submitted), the ui state will be reset.

The debug, info, warn and error commands should work with the multi
client ui. When run, they set the log level globally, not just for the
client that set the level.
2020-06-24 19:40:17 -07:00
Dale Wijnand 722022ae97 Add conversions from Init/+Task to Taskable 2020-02-17 12:22:53 +00:00
Dale Wijnand fdfdd1ca47 Extract Taskable from ScopedTaskable 2020-02-17 12:22:53 +00:00
Eugene Yokota a8ab4ada68 Replace getResource("") trick
Fixes https://github.com/sbt/sbt/issues/5339

It seems like some tests are using `ClassLoader#getResource("")` to acquire the `classes` directory path. This does not seem to work on sbt 1.3.6, which returns `file:/home/travis/.cache/coursier/v1/https/repo1.maven.org/maven2/org/apache/logging/log4j/log4j-api/2.11.2/log4j-api-2.11.2.jar!/META-INF/versions/9/`. To workaround this issue, I've switched to loading the known folder name instead.
2019-12-27 16:43:20 -05:00
Eugene Yokota 1cfe14a877 Ignore the build ref case 2019-09-30 02:18:11 -04:00
Eugene Yokota d1993bcabb use hedgehog.Result 2019-09-30 02:09:02 -04:00
Eugene Yokota f2de61c681 check for ambiguous project names 2019-09-30 01:56:03 -04:00
Eugene Yokota 073c89059e make URI longer to avoid conflict 2019-09-30 01:56:00 -04:00
Eugene Yokota ad1596c400 increase example count 2019-09-30 01:53:50 -04:00
Charles O'Farrell 67a3eca698 Use hedgehog in ParseKey, Delegates, and ParserSpec test 2019-09-30 01:52:57 -04:00
Ethan Atkins fb15065438 Move implicit FileStamp JsonFormats into object
I realized it was probably not ideal to have these implicit JsonFormats
defined directly in the FileStamp object because they might
inadvertently be brought into scope with a wildcard import.
2019-08-09 12:18:22 -07:00
Ethan Atkins a3ac4c76a6 Bump scalafmt
Intellij had issues resolving 2.0.0-RCX so it will be nice to be using
the latest.
2019-07-18 12:40:21 -07:00
Eugene Yokota 41eca47e66 Fix Java version parsing
Fixes #4731
2019-05-29 23:11:20 -04:00
Ethan Atkins df51281d90 Remove dead test 2019-05-28 10:39:08 -07:00
Ethan Atkins 03bf539ce9 Add new ClassLoaderCache implementation
This commit adds a new ClassLoaderCache that builds on the
ClassLoaderCache that is present in zinc (and can be used to build an
instance of the zinc ClassLoaderCache to preserve compatibility). It
differs from the zinc classloader cache that it does not use direct
SoftReferences to classloaders. Instead, we create a wrapper loader
that can't load any classes and just delegates to its parent. This
allows us to add a thread that reaps the soft reference to the wrapper
loader. Crucially, we add a custom SoftReference class that has a strong
reference to the underlying classloader. This allows us to call close on
the strong reference.

The one issue with this approach is that we can't
rescue the jvm from crashing with an OOM: metaspace because the jvm
doesn't give us a chance to close and dereference the underlying
classloaders before it crashes. It WILL collect classloaders under
normal memory pressure, just not metaspace pressure. To fix this, I
check if the MaxMetaspaceSize is set via an MxBean and, if it is, we
fill the cache with regular soft references. We are going to change the
bash script to not set -XX:MaxMetaspaceSize by default so most builds
should probably end up correctly closing the classloaders after this
change. But we should break existing builds that set MaxMetaspaceSize
but don't crash.

As part of this commit, I audited all of the places where we were
instantiating ClassLoaderCache instances and instead pass in the
state's ClassLoaderCache instance. This reduces the total number of
classloaders created.
2019-05-28 09:53:35 -07:00
Ethan Atkins ec09e73437 Improve cache invalidation strategy
Previously the persistent attribute map was only reset when the file
event monitor detected a change. This made it possible for the cache to
be inconsistent with the state of the file system*. To fix this, I add an
observer on the file tree repository used by the continuous build that
invalidates the cache entry for any path for which it detects a change.
Invalidating the cache does not stamp the file. That only happens either
when a task asks for the stamp for that file or when the file event
monitor reports an event and we must check if the file was updated or
not.

After this change, touching a source file will not trigger a build
unless the contents of the file actually changes.

I added a test that touches one source file in a project and updates the
content of the other. If the source file that is only ever touched ever
triggers a build, then the test fails.

* This could lead to under-compilation because ExternalHooks would not
detect that the file had been updated.
2019-05-11 22:01:48 -07:00
Ethan Atkins b6ad077a72 Update io
The new io verion removes the PathFinder <-> Glob implicit translations.
It also has a number of small bug fixes related to directory listing via
FileTreeView.
2019-05-11 21:34:02 -07:00
Eugene Yokota b18f3e8710 Reduce the test noise by making id more realistic
Fixes #3893

This fixes the flaky ParserSpec by making the id generation more realistic ASCII identifiers.
2019-05-11 03:55:34 -04:00
Eugene Yokota 4b9533b124 ignore bad SDKMAN directories
Fixes #4655
2019-05-09 01:59:03 -04:00
Ethan Atkins 3319423369 Add full support for managing file task io
This commit unifies my previous work for automatically watching the
input files for a task with support for automatically tracking and
cleaning up the output files of a task. The big idea is that users may
want to define tasks that depend on the file outputs of other tasks and
we may not want to run the dependent tasks if the output files of the
parent tasks are unmodified.

For example, suppose we wanted to make a plugin for managing typescript
files. There may be, say, two tasks with the following inputs and
outputs:

compileTypescript = taskKey[Unit]("shells out to compile typescript files")
  fileInputs -- sourceDirectory / ** / "*.ts"
  fileOutputs -- target / "generated-js" / ** / "*.js"

minifyGeneratedJS = taskKey[Path]("minifies the js files generated by compileTypescript to a single combined js file.")
  dependsOn: compileTypeScript / fileOutputs

Given a clean build, the following should happen
> minifyGeneratedJS
// compileTypescript is run
// minifyGeneratedJS is run

> minifyGeneratedJS
// no op because nothing changed

> minifyGeneratedJS / clean
// removes the file returned by minifyGeneratedJS.previous

> minifyGeneratedJS
// re-runs minifyGeneratedJS with the previously compiled js artifacts

> compileTypescript / clean
// removes the generated js files

> minifyGeneratedJS
// compileTypescript is run because the previous clean removed the generated js files
// minifyGeneratedJS runs because the artifacts have changed

> clean
// removes the generated js files and the minified js file

> minifyGeneratedJS
// compileTypescript is run because the generated js files were
// minifyGeneratedJS is run both because it was removed and

Moreover, if compileTypescript fails, we want minifyGeneratedJS to fail
as well.

This commit makes this all possible. It adds a number of tasks to
sbt.nio.Keys that deal with the output files. When injecting settings, I
now identify all tasks that return Seq[File], File, Seq[Path] and Path
and create a hidden special task: dynamicFileOutputs: TaskKey[Seq[Path]]
This special task runs the underlying task and converts the result to
Seq[Path]. From there, we can have the tasks like changedOutputPaths
delegate to dynamicFileOutputs which, by proxy, runs the underlying
task. If any task in the input / output chain fails, the entire sequence
fails.

Unlike the fileInputs, we do not register the dynamicFileOutputs or
fileOutputs with continuous watch service so these paths will not
trigger a continuous build if they are modified. Only explicit unmanaged
input sources should should do that.

As part of this, I also added automatic generation of a custom clean task for
any task that returns Seq[File], File, Seq[Path] or Path. I also added
aggregation so that clean can be defined in a configuration or project
and it will automatically run clean for all of the tasks that have a
custom clean implementation in that task or project. The automatic clean
task will only delete files that are in the task target directory to
avoid accidentally deleting unmanaged files.
2019-05-02 14:36:08 -07:00
Ethan Atkins a5cefd45be Clean up nio apis
This commit refactors things so that the nio apis are located primarily
in the nio package. Because the nio keys are a first class sbt feature,
I had to add import sbt.nio._ and sbt.nio.Keys._ to the autoimports in
BuildUtil.scala
2019-05-02 14:36:06 -07:00
Ethan Atkins 72df8f674c Add support for managed task inputs
In my recent changes to watch, I have been moving towards a world in
which sbt manages the file inputs and outputs at the task level. The
main idea is that we want to enable a user to specify the inputs and
outputs of a task and have sbt able to track those inputs across
multiple task evaluations. Sbt should be able to automatically trigger a
build when the inputs change and it also should be able to avoid task
evaluation if non of the inputs have changed.

The former case of having sbt automatically watch the file inputs of a
task has been present since watch was refactored. In this commit, I
make it possible for the user to retrieve the lists of new, modified and
deleted files. The user can then avoid task evaluation if none of the
inputs have changed.

To implement this, I inject a number of new settings during project
load if the fileInputs setting is defined for a task. The injected
settings are:

allPathsAndAttributes -- this retrieves all of the paths described by
  the fileInputs for the task along with their attributes
fileStamps -- this retrieves all of the file stamps for the files
  returned by allPathsAndAttributes

Using these two injected tasks, I also inject a number of derived tasks,
such as allFiles, which returns all of the regular files returned by
allPathsAndAttributes and changedFiles, which returns all of the regular
files that have been modified since the last run.

Using these injected settings, the user is able to write tasks that
avoid evaluation if the inputs haven't changed.

foo / fileInputs += baseDirectory.value.toGlob / ** / "*.scala"
foo := {
  foo.previous match {
    case Some(p) if (foo / changedFiles).value.isEmpty => p
    case _ => fooImpl((foo / allFiles).value
  }
}

To make this whole mechanism work, I add a private task key:
val fileAttributeMap = taskKey[java.util.HashMap[Path, Stamp]]("...")
This keeps track of the stamps for all of the files that are managed by
sbt. The fileStamps task will first look for the stamp in the attribute
map and, only if it is not present, it will update the cache. This
allows us to ensure that a given file will only be stamped once per task
evaluation run no matter how the file inputs are specified. Moreover, in
a continuous build, I'm able to reuse the attribute map which can
significantly reduce latency because the default file stamping
implementation used by zinc is fairly expensive (it can take anywhere
between 300-1500ms to stamp 5000 8kb source files on my mac).

I also renamed some of the watch related keys to be a bit more clear.
2019-05-02 14:33:29 -07:00
Ethan Atkins 2deac62b00 Bump io
The newest version of io repackages a number of classes into the
sbt.nio.* packages. It also changes some of the semantics of glob
related apis. This commit updates all of the usages of the updated apis
within sbt but should have no functional difference.
2019-05-02 14:33:01 -07:00