Commit Graph

11646 Commits

Author SHA1 Message Date
andrea 0c11bc6add Build time configurable library management 2018-10-09 09:03:55 +01:00
Ethan Atkins 7d3d3c71d6 Refactor Watched
This commit reworks Watched to be more testable and extensible. It also
adds some small features. The previous implementation presented a number
of challenges:

1) It relied on external side effects to terminate the watch, which was
   difficult to test
2) It exposed irrelevant implementation details to the user in the
   methods that exposed the WatchState as a parameter.
3) It spun up two worker threads. One was to monitor System.in for user
   input. The other was to poll the watch service for events and write
   them to a queue. The user input thread actually broke '~console'
   because nearly every console session will hit the <enter> key, which
   would eventually cause the watch to stop when the user exited the
   console.

To address (1), I add the shouldTerminate method to WatchConfig. This
takes the current watch iteration is input and if the function returns
true, the watch will stop.

To address (2), I replace the triggeredMessage and watchingMessage keys
with watchTriggeredMessage and watchStartMessage. The latter two keys
are functions that do not take the WatchState as parameters. Both
functions take the current iteration count as a parameter and the
watchTriggeredMessage also has a parameter for the path that triggered
the build.

To address (3), I stop using the sbt.internal.io.EventMonitor and
instead use the sbt.io.FileEventMonitor. The latter class is similar to
the former except that it's polling method accepts a duration, which may
be finite or infinite) and returns all of the events that occurred since
it was last polled. By adding the ability to poll for a finite amount of
time, we can interleave polling for events with polling System.in for
user input, all on the main thread. This eliminates the two extraneous
threads and fixes the '~console' use case I described before.

I also let the user configure the function that reads from System.in via
the watchHandleInput method. In fact, this method need not read from
System.in at all since it's just () => Watched.Action. The reason that
it isn't () => Boolean is that I'd like to leave open the option for the
ability to trigger a build via user input, not just terminating the
watch. My initial idea was to add the ability to type 'r' to re-build in
addition to <enter> to exit. This doesn't work without integrating
jline though because the input is buffered. Regardless, for testing
purposes, it gives us the ability to add a timeout to the watch by
making handleInput return true when a deadline expires.

The tests are a bit wonky because I still need to rely on side effects
in the logging methods to orchestrate the sequence of file events that
I'd like to test. While I could move some of this logic into a
background thread, there still needs to be coordination between the
state of the watch and the background thread. I think it's easier to
reason about when all of the work occurs on the same thread, even if it
makes these user provided functions impure.

I deprecated all of the previous watch related keys that are no longer
used with the new infrastructure. To avoid breaking existing builds, I
make the watchConfig task use the deprecated logging methods if they are
defined in the user's builds, but sbt will not longer set the default
values. For the vast majority of users, it should be straightforward to
migrate their builds to use the new keys.  My hunch is that the of the
deprecated keys, only triggeredMessage is widely used (in conjunction
with the clear screen method) and it is dead simple to replace it with
watchTriggeredMessage.

Note: The FileTreeViewConfig class is not really necessary for this commit.
It will become more important in a subsequent commit which introduces an
optional global file system cache.
2018-10-08 22:00:50 -07:00
Ethan Atkins 7764dc42ae Move executeContinuously into LegacyWatched
This helps keep Watched.scala more manageable until we can potentially
remove this code.
2018-10-08 22:00:50 -07:00
Ethan Atkins 28aa1de32a Refactor continuous execution
This commit makes watch event logging work in the '~' command. The
previous design of the command made this difficult, so there is a
significant re-design of the implementation of '~'. I believe that this
redesign will allow the feature to be maintained and improved more
easily moving forward. With the redesign, it is now possible to test the
business logic of the watch command (and I add a rudimentary test that I
will build upon in subsequent commits).

A bonus of this redesign is that now if the user tries to watch an
invalid command, the watch will immediately terminate with an error
rather than get stuck waiting for events when the task can never
possibly succeed.

The previous implementation of the '~' command makes it difficult
to dynamically control the implementation arguments because it is
implemented in the command project which makes it unable to depend on
any task keys that are defined in the build. It works around this by
putting all of it's configuration in the Watched attribute which is
stored globally. This would not have been necessary if the function had
been defined in the main project where it could just extract the value
of the watched task rather than relying on the global attribute value.
Moreover, because it cannot depend on tasks, it makes it nigh impossible
to use the logging framework within the '~' command.

Another issue with the previous implementation is that it's somewhat
difficult to reason about. The executeContinuously has effectively two
entry points: one for the first time the command is run and one for each
subsequent invocation when a new build is triggered. The successive
invocations are triggered by prepending commands to run to the previous
state. This is made recursive by prepending the initial command (that
was prefixed with '~'. Which branch we're in is determined by checking
for the existence of a temporary attribute, that we must ensure that we
remove when the build is stopped. This makes a lot of behavior non-local and
difficult for an outsider who is less familiar with sbt to understand.

Broadly, this refactor does two things:
1) Move the definition of continuous from BasicCommands to BuiltInCommands
2) Re-work the implementation to be executed in code rather than using
   the sbt dsl.

The first part is simple. We just add an implementation of continuous to
BuiltInCommands and remove it from the list of BasicCommands. We need to
leave in the legacy implementation for binary compatibility. I also
moved all of the actual implementation logic into Watched, which makes
maintenance easier since most of the logic is in one place.

The second part is more complicated. Rather than rely on the sbt dsl
(e.g. `(ClearOnFailure :: next :: FailureWall :: repeat :: s)`) to
parse and run the command. We manually parse the command and generate a
task of type `() => State`. We don't actually need to do anything with
the generated state because we're going to return the original state at
the end of the command no matter what. With this task, we can then
create a tail recursive function that repeatedly executes the task until
the watch is terminated.

The parsing is handled in the Watch.command method (which is where I
moved the refactored BasicCommands.continuous implementation). The
actual task running and monitoring is handled in Watched.watch. This
method has no reference to the sbt state, which makes it testable. It sets
up an event monitor and then delegates the recursive monitoring to a
small nested function, Watched.watch.impl. One nice thing about this
approach is that it is very easy to reason about the life cycle of the
EventMonitor. The recursive call is within a try { } finally { } where
the monitor and stdin are guaranteed to be cleared at the end.

Adding support for a custom (and default) watch logger is trivial with
the new infrastructure and is done via the watchLogger TaskKey.

There was a small reporting race condition that was introduced by the
change to (2). Because the new implementation is able to bypass command
parsing for triggered builds, the watch message would usually end up
being printed before the task outcome was fully logged. To work around
this, I made the watch and triggered messages be logged rather than
printed directly to stdout. As a result, the only user visible result of
this change should be that instead of seeing:
"1. Waiting for source changes in project foo... (press enter to interrupt)",
users will now see:
"[info] 1. Waiting for source changes in project foo... (press enter to interrupt)".
2018-10-08 22:00:50 -07:00
Ethan Atkins 5e3f72ad8a Do not append default watch sources with ++=
Using ++= prevents these from being overridden by the user without doing
some nasty runtime manipulations.
2018-10-08 22:00:50 -07:00
Ethan Atkins 97598efcea Bump watch anti-entropy
There have been reports that often a new build will be triggered
immediately after the previous build even when none of the files have
been modified since the start of the last build. This can happen when,
for example, a program implements save with a rename. When that occurs,
a deletion watch event may trigger the build but the corresponding
creation event may be detected outside of the current 40ms window. By
bumping this value to 500ms, we hopefully prevent the majority of these
false triggers. For unusual workflows in which this longer quarantine
period is an issue, the setting can be overridden.
2018-10-08 22:00:50 -07:00
Ethan Atkins 6ffb4108e7 Set swoval.tmpdir property on startup
This change makes the temporary shared library that is created by
the swoval file-tree-views library to be extracted into the sbt global
base directory rather than the temp file. This way if there is a leak of
shared libraries, they can easily be found in ~/.sbt rather than in,
say, /tmp (or the osx/windows equivalent location). The extracted shared
library objects will be in the path ~/.sbt/swoval-jni. There is a
shutdown hook that removes them as well as a garbage collection process
that runs in the background whenever the swoval library is loaded, so
these shouldn't leak uncontrollably.
2018-10-08 22:00:50 -07:00
Ethan Atkins da54e2fbd3 Deprecate unused method 2018-10-08 22:00:50 -07:00
Ethan Atkins 3e62b983a2 Remove intellij warnings 2018-10-08 22:00:50 -07:00
Eugene Yokota ed76503629 Fix single repo emulation script
Fixes #4330
Ref 5b179a2611 (diff-fdc3abdfd754eeb24090dbd90aeec2ce)
2018-10-09 00:23:54 -04:00
eugene yokota 082d1767a1
Merge pull request #4406 from eatkins/bump-io
Bump io
2018-10-08 23:39:40 -04:00
Ethan Atkins ed7c152f2f Remove debug command from scripted test
This spams the logs and otherwise seems to serve little purpose.
2018-10-08 13:59:40 -07:00
Ethan Atkins aeadd8db72 Remove unneeded import 2018-10-08 13:59:40 -07:00
Ethan Atkins 51be0856a1 Fix deprecation warning in scripted tests 2018-10-08 13:59:40 -07:00
Ethan Atkins 6725b39a84 Bump io to 1.3.0-M3
I had to turn off -Xfatal-warnings in commandProj because after updating
io, commandProj depends on the deprecated EventMonitor class. In #4335,
I stop using EventMonitor, but deprecate the Watched class which is both
defined and used (as an unused attribute key) in commandProj. I think we
can probably get rid of Watched in 1.4.x and certainly in a hypothetical
2.x, so hopefully we can restore -Xfatal-warnings sooner than later.

I also had to replace uses of IO.classLocationFile with
IO.classLocationPath to avoid compilation failures due to
-Xfatal-warnings.
2018-10-08 13:59:34 -07:00
Eugene Yokota a82c834198 Scala 2.12.7 2018-10-08 12:02:19 -04:00
eugene yokota 04e63936b3
Merge pull request #4409 from eed3si9n/wip/nightlies
Include both explicit plugin resolves and boot resolvers
2018-10-07 01:09:41 -04:00
Eugene Yokota a9fd111143 Include both explicit plugin resolves and boot resolvers
Fixes #4408
2018-10-07 00:15:58 -04:00
eugene yokota 4867e87eca
Merge pull request #4396 from eed3si9n/wip/progress
"super shell" for sbt
2018-10-06 13:07:11 -04:00
eugene yokota c2dc7d62f4
Merge pull request #4405 from eed3si9n/bport/plugincross
[1.2.x]  check PluginCross.scala consisntency
2018-10-05 14:05:40 -04:00
eugene yokota 53209acf89
Merge pull request #4404 from eed3si9n/wip/plugincross
check PluginCross.scala consisntency
2018-10-05 13:56:02 -04:00
Eugene Yokota 4c6e421d59 add onLoadMessage 2018-10-05 13:40:59 -04:00
Eugene Yokota ce9aa0c920 check PluginCross.scala consisntency 2018-10-05 13:39:59 -04:00
Eugene Yokota c64166ea8d check PluginCross.scala consisntency 2018-10-05 13:32:40 -04:00
eugene yokota 9eb42e8768
Merge pull request #4403 from eed3si9n/wip/boot-dependencyresolution
Fix resolver for compiler bridge
2018-10-05 13:05:02 -04:00
eugene yokota 7893d8ad1c
Merge pull request #4402 from eed3si9n/wip/housebump
sbt-houserules 0.3.9
2018-10-05 10:23:31 -04:00
Eugene Yokota ca7c7d3841 Fix resolver for compiler bridge
I noticed that we can't resolve the compiler bridge out of snapshot repo.
2018-10-05 04:11:08 -04:00
eugene yokota ec26c512cd
Merge pull request #4401 from eed3si9n/wip/bump
Zinc 1.2.3
2018-10-05 03:31:31 -04:00
Eugene Yokota 0d788162ae add onLoadMessage 2018-10-05 03:04:22 -04:00
Eugene Yokota fa23e785d6 sbt-houserules 0.3.9 2018-10-05 03:03:59 -04:00
Eugene Yokota 1f0680efbf Bump modules 2018-10-05 02:25:36 -04:00
Eugene Yokota 48726a0d60 Formatting 2018-10-05 02:25:21 -04:00
eugene yokota 5649ac0410
Merge pull request #4400 from eed3si9n/bport/junit-reports
[1.2.x] Duplicate reports for backwards-compat adding a name-compliant copy
2018-10-05 01:18:20 -04:00
Ignasi Marimon-Clos 3ea7533d4f Duplicate reports for backwards-compat adding a name-compliant copy 2018-10-05 00:17:33 -04:00
Eugene Yokota 6224b1dda1 Util 1.3.0-M2 2018-10-02 11:08:49 -04:00
eugene yokota f16997d3a9
Merge pull request #184 from eed3si9n/wip/progress
Adds sbt.color flag and sbt.progress flag
2018-10-02 08:58:38 -04:00
Eugene Yokota efe04c1cde Cleaning up code 2018-10-02 08:51:17 -04:00
Eugene Yokota 6dc27a3f6e change to DeleteLine 2018-10-02 08:25:28 -04:00
Eugene Yokota 1465604f8c Demote "Done updating." log to debug level 2018-10-02 08:25:28 -04:00
Eugene Yokota c316c80093 adds task progress
Fixes #4362

This implements an instance of ExecuteProgress that is enabled by default to report progress on the shell.
Combined with the scroll up logger, this takes over the bottom lines of the terminal screen and display a count up clock of the currently executing task.
2018-10-02 08:25:28 -04:00
Eugene Yokota 4be4017f06 Refactor ExecuteProgress type parameters 2018-10-02 08:24:17 -04:00
Eugene Yokota 458675239c Add mima exclusion for JsonProtocol.LogOptionFormat
According to Travis CI only Scala 2.11 seems to be affected.
2018-10-02 08:17:08 -04:00
eugene yokota e2923541b1
Merge pull request #4384 from andreaTP/lspCancellationSupport
Implementing cancellation requests for LSP server
2018-10-01 15:00:43 -04:00
andrea d7c55a3d82 Implementing cancellation requests for LSP server 2018-10-01 14:39:26 +01:00
Eugene Yokota 9bb244314d implement sbt.progress
This implements a logger that grows upward, instead towards bottom.
2018-10-01 05:50:35 -04:00
Eugene Yokota 53c9b84858 add sbt.color flag
This implements a new sbt.color flag that takes always/auto/never/true/false value as a replacement of current sbt.log.format=true/false flag.

When neither flags are set, the default behavior is to enable color when the terminal supports ANSI and it detects an stdout console (as opposed to redirects).

Fixes https://github.com/sbt/sbt/issues/4284
2018-09-30 21:00:09 -04:00
eugene yokota cc0dc0c903
Merge pull request #4393 from eed3si9n/wip/sourcedependencies
Bump tests to 2.12
2018-09-30 13:54:54 -04:00
Eugene Yokota 94e18992b5 Bump tests to 2.12 2018-09-30 12:25:21 -04:00
eugene yokota 2afff9571b
Merge pull request #4392 from eed3si9n/wip/update-test-tests
Bump up test frameworks used in scripted tests
2018-09-30 00:41:24 -04:00
Eugene Yokota 467d653efb Bump up test frameworks used in scripted tests
This is in part to test these on JDK 11 by bumping tests to Scala 2.12.7.
2018-09-29 23:19:49 -04:00