Sbt plugin run tasks before / after an other task
I know, I saw Run custom task automatically before/after standard task but it seems outdated. I also found SBT before/after hooks for a task but it does not have any code example.
I am on SBT 0.13.17
.
So I want to run my task MyBeforeTask
and MyAfterTask
automatically after an other tasks, says Compile
.
So when you do sbt compile
I would like to see:
...log...
This is my before test text
...compile log...
This is my after test text
So I would need to have:
object MyPlugin extends AutoPlugin {
object autoImport {
val MyBeforeTask = taskKey[Unit]("desc...")
val MyAfterTask = taskKey[Unit]("desc...")
}
import autoImport._
override def projectSettings: Seq[Def.Setting[_]] = {
MyBeforeTask := {
println("This is my before test text")
},
MyAfterTask := {
println("This is my after test text")
}
}
}
So I think I need things like dependsOn
and in
but I am not sure how to set them up.
scala sbt
add a comment |
I know, I saw Run custom task automatically before/after standard task but it seems outdated. I also found SBT before/after hooks for a task but it does not have any code example.
I am on SBT 0.13.17
.
So I want to run my task MyBeforeTask
and MyAfterTask
automatically after an other tasks, says Compile
.
So when you do sbt compile
I would like to see:
...log...
This is my before test text
...compile log...
This is my after test text
So I would need to have:
object MyPlugin extends AutoPlugin {
object autoImport {
val MyBeforeTask = taskKey[Unit]("desc...")
val MyAfterTask = taskKey[Unit]("desc...")
}
import autoImport._
override def projectSettings: Seq[Def.Setting[_]] = {
MyBeforeTask := {
println("This is my before test text")
},
MyAfterTask := {
println("This is my after test text")
}
}
}
So I think I need things like dependsOn
and in
but I am not sure how to set them up.
scala sbt
add a comment |
I know, I saw Run custom task automatically before/after standard task but it seems outdated. I also found SBT before/after hooks for a task but it does not have any code example.
I am on SBT 0.13.17
.
So I want to run my task MyBeforeTask
and MyAfterTask
automatically after an other tasks, says Compile
.
So when you do sbt compile
I would like to see:
...log...
This is my before test text
...compile log...
This is my after test text
So I would need to have:
object MyPlugin extends AutoPlugin {
object autoImport {
val MyBeforeTask = taskKey[Unit]("desc...")
val MyAfterTask = taskKey[Unit]("desc...")
}
import autoImport._
override def projectSettings: Seq[Def.Setting[_]] = {
MyBeforeTask := {
println("This is my before test text")
},
MyAfterTask := {
println("This is my after test text")
}
}
}
So I think I need things like dependsOn
and in
but I am not sure how to set them up.
scala sbt
I know, I saw Run custom task automatically before/after standard task but it seems outdated. I also found SBT before/after hooks for a task but it does not have any code example.
I am on SBT 0.13.17
.
So I want to run my task MyBeforeTask
and MyAfterTask
automatically after an other tasks, says Compile
.
So when you do sbt compile
I would like to see:
...log...
This is my before test text
...compile log...
This is my after test text
So I would need to have:
object MyPlugin extends AutoPlugin {
object autoImport {
val MyBeforeTask = taskKey[Unit]("desc...")
val MyAfterTask = taskKey[Unit]("desc...")
}
import autoImport._
override def projectSettings: Seq[Def.Setting[_]] = {
MyBeforeTask := {
println("This is my before test text")
},
MyAfterTask := {
println("This is my after test text")
}
}
}
So I think I need things like dependsOn
and in
but I am not sure how to set them up.
scala sbt
scala sbt
asked Nov 14 '18 at 19:56
WonayWonay
394111
394111
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
It is not possible to configure for a particular task to run after the given task, because that's not how the task dependencies model works - when you specify the task, its dependencies and itself will be executed, but there is no way to define an "after" dependency. However, you can simulate that with dynamic tasks.
To run some task before another, you can use dependsOn
:
compile in Compile := (compile in Compile).dependsOn(myBeforeTask).value
This establishes a dependency between two tasks, which ensures that myBeforeTask
will be run before compile in Compile
.
Note that there is a more generic way to make multiple tasks run one after another:
aggregateTask := Def.sequential(task1, task2, task3, task4).value
Def.sequential
relies on the dynamic tasks machinery, which sets up dependencies between tasks at runtime. However, there are some limitations to this mechanism, in particular, you cannot reference the task being defined in the list of tasks to execute, so you can't use Def.sequential
to augment existing tasks:
compile in Compile := Def.sequential(myBeforeTask, compile in Compile).value
This definition will fail at runtime with a strange error message which basically means that you have a loop in your task dependencies graph. However, for some use cases it is extremely useful.
To run some task after another, however, you have to resort to defining a dynamic task dependency using Def.taskDyn
:
compile in Compile := Def.taskDyn {
val result = (compile in Compile).value
Def.task {
val _ = myAfterTask.value
result
}
}.value
Def.taskDyn
accepts a block which must return a Def.Initialize[Task[T]]
, which will be used to instantiate a task to be run later, after the main body of Def.taskDyn
completes. This allows one to compute tasks dynamically, and establish dependencies between tasks at runtime. As I said above, however, this can result in very strange errors happening at runtime, which are usually caused by loops in the dependency graph.
Therefore, the full example, with both "before" and "after" tasks, would look like this:
compile in Compile := Def.taskDyn {
val result = (compile in Compile).value
Def.task {
val _ = myAfterTask.value
result
}
}.dependsOn(myBeforeTask).value
What about doing something likecompile in Compile := {val r = (compile in Compile).value ; /* run after? */ ; r }
? Sorry can't really do multi line in comments :/
– Wonay
Nov 14 '18 at 21:14
1
@Wonay, yes, indeed, this would work - it would run the original compile task before your code. This won't allow you to express your "run after" task as a real task though. That being said, maybe you can simulate that with carefulDef.taskDyn
application, with all potential issues dynamic tasks introduce.
– Vladimir Matveev
Nov 14 '18 at 21:31
@Wonay please see the updated answer.
– Vladimir Matveev
Nov 14 '18 at 21:39
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53307884%2fsbt-plugin-run-tasks-before-after-an-other-task%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
It is not possible to configure for a particular task to run after the given task, because that's not how the task dependencies model works - when you specify the task, its dependencies and itself will be executed, but there is no way to define an "after" dependency. However, you can simulate that with dynamic tasks.
To run some task before another, you can use dependsOn
:
compile in Compile := (compile in Compile).dependsOn(myBeforeTask).value
This establishes a dependency between two tasks, which ensures that myBeforeTask
will be run before compile in Compile
.
Note that there is a more generic way to make multiple tasks run one after another:
aggregateTask := Def.sequential(task1, task2, task3, task4).value
Def.sequential
relies on the dynamic tasks machinery, which sets up dependencies between tasks at runtime. However, there are some limitations to this mechanism, in particular, you cannot reference the task being defined in the list of tasks to execute, so you can't use Def.sequential
to augment existing tasks:
compile in Compile := Def.sequential(myBeforeTask, compile in Compile).value
This definition will fail at runtime with a strange error message which basically means that you have a loop in your task dependencies graph. However, for some use cases it is extremely useful.
To run some task after another, however, you have to resort to defining a dynamic task dependency using Def.taskDyn
:
compile in Compile := Def.taskDyn {
val result = (compile in Compile).value
Def.task {
val _ = myAfterTask.value
result
}
}.value
Def.taskDyn
accepts a block which must return a Def.Initialize[Task[T]]
, which will be used to instantiate a task to be run later, after the main body of Def.taskDyn
completes. This allows one to compute tasks dynamically, and establish dependencies between tasks at runtime. As I said above, however, this can result in very strange errors happening at runtime, which are usually caused by loops in the dependency graph.
Therefore, the full example, with both "before" and "after" tasks, would look like this:
compile in Compile := Def.taskDyn {
val result = (compile in Compile).value
Def.task {
val _ = myAfterTask.value
result
}
}.dependsOn(myBeforeTask).value
What about doing something likecompile in Compile := {val r = (compile in Compile).value ; /* run after? */ ; r }
? Sorry can't really do multi line in comments :/
– Wonay
Nov 14 '18 at 21:14
1
@Wonay, yes, indeed, this would work - it would run the original compile task before your code. This won't allow you to express your "run after" task as a real task though. That being said, maybe you can simulate that with carefulDef.taskDyn
application, with all potential issues dynamic tasks introduce.
– Vladimir Matveev
Nov 14 '18 at 21:31
@Wonay please see the updated answer.
– Vladimir Matveev
Nov 14 '18 at 21:39
add a comment |
It is not possible to configure for a particular task to run after the given task, because that's not how the task dependencies model works - when you specify the task, its dependencies and itself will be executed, but there is no way to define an "after" dependency. However, you can simulate that with dynamic tasks.
To run some task before another, you can use dependsOn
:
compile in Compile := (compile in Compile).dependsOn(myBeforeTask).value
This establishes a dependency between two tasks, which ensures that myBeforeTask
will be run before compile in Compile
.
Note that there is a more generic way to make multiple tasks run one after another:
aggregateTask := Def.sequential(task1, task2, task3, task4).value
Def.sequential
relies on the dynamic tasks machinery, which sets up dependencies between tasks at runtime. However, there are some limitations to this mechanism, in particular, you cannot reference the task being defined in the list of tasks to execute, so you can't use Def.sequential
to augment existing tasks:
compile in Compile := Def.sequential(myBeforeTask, compile in Compile).value
This definition will fail at runtime with a strange error message which basically means that you have a loop in your task dependencies graph. However, for some use cases it is extremely useful.
To run some task after another, however, you have to resort to defining a dynamic task dependency using Def.taskDyn
:
compile in Compile := Def.taskDyn {
val result = (compile in Compile).value
Def.task {
val _ = myAfterTask.value
result
}
}.value
Def.taskDyn
accepts a block which must return a Def.Initialize[Task[T]]
, which will be used to instantiate a task to be run later, after the main body of Def.taskDyn
completes. This allows one to compute tasks dynamically, and establish dependencies between tasks at runtime. As I said above, however, this can result in very strange errors happening at runtime, which are usually caused by loops in the dependency graph.
Therefore, the full example, with both "before" and "after" tasks, would look like this:
compile in Compile := Def.taskDyn {
val result = (compile in Compile).value
Def.task {
val _ = myAfterTask.value
result
}
}.dependsOn(myBeforeTask).value
What about doing something likecompile in Compile := {val r = (compile in Compile).value ; /* run after? */ ; r }
? Sorry can't really do multi line in comments :/
– Wonay
Nov 14 '18 at 21:14
1
@Wonay, yes, indeed, this would work - it would run the original compile task before your code. This won't allow you to express your "run after" task as a real task though. That being said, maybe you can simulate that with carefulDef.taskDyn
application, with all potential issues dynamic tasks introduce.
– Vladimir Matveev
Nov 14 '18 at 21:31
@Wonay please see the updated answer.
– Vladimir Matveev
Nov 14 '18 at 21:39
add a comment |
It is not possible to configure for a particular task to run after the given task, because that's not how the task dependencies model works - when you specify the task, its dependencies and itself will be executed, but there is no way to define an "after" dependency. However, you can simulate that with dynamic tasks.
To run some task before another, you can use dependsOn
:
compile in Compile := (compile in Compile).dependsOn(myBeforeTask).value
This establishes a dependency between two tasks, which ensures that myBeforeTask
will be run before compile in Compile
.
Note that there is a more generic way to make multiple tasks run one after another:
aggregateTask := Def.sequential(task1, task2, task3, task4).value
Def.sequential
relies on the dynamic tasks machinery, which sets up dependencies between tasks at runtime. However, there are some limitations to this mechanism, in particular, you cannot reference the task being defined in the list of tasks to execute, so you can't use Def.sequential
to augment existing tasks:
compile in Compile := Def.sequential(myBeforeTask, compile in Compile).value
This definition will fail at runtime with a strange error message which basically means that you have a loop in your task dependencies graph. However, for some use cases it is extremely useful.
To run some task after another, however, you have to resort to defining a dynamic task dependency using Def.taskDyn
:
compile in Compile := Def.taskDyn {
val result = (compile in Compile).value
Def.task {
val _ = myAfterTask.value
result
}
}.value
Def.taskDyn
accepts a block which must return a Def.Initialize[Task[T]]
, which will be used to instantiate a task to be run later, after the main body of Def.taskDyn
completes. This allows one to compute tasks dynamically, and establish dependencies between tasks at runtime. As I said above, however, this can result in very strange errors happening at runtime, which are usually caused by loops in the dependency graph.
Therefore, the full example, with both "before" and "after" tasks, would look like this:
compile in Compile := Def.taskDyn {
val result = (compile in Compile).value
Def.task {
val _ = myAfterTask.value
result
}
}.dependsOn(myBeforeTask).value
It is not possible to configure for a particular task to run after the given task, because that's not how the task dependencies model works - when you specify the task, its dependencies and itself will be executed, but there is no way to define an "after" dependency. However, you can simulate that with dynamic tasks.
To run some task before another, you can use dependsOn
:
compile in Compile := (compile in Compile).dependsOn(myBeforeTask).value
This establishes a dependency between two tasks, which ensures that myBeforeTask
will be run before compile in Compile
.
Note that there is a more generic way to make multiple tasks run one after another:
aggregateTask := Def.sequential(task1, task2, task3, task4).value
Def.sequential
relies on the dynamic tasks machinery, which sets up dependencies between tasks at runtime. However, there are some limitations to this mechanism, in particular, you cannot reference the task being defined in the list of tasks to execute, so you can't use Def.sequential
to augment existing tasks:
compile in Compile := Def.sequential(myBeforeTask, compile in Compile).value
This definition will fail at runtime with a strange error message which basically means that you have a loop in your task dependencies graph. However, for some use cases it is extremely useful.
To run some task after another, however, you have to resort to defining a dynamic task dependency using Def.taskDyn
:
compile in Compile := Def.taskDyn {
val result = (compile in Compile).value
Def.task {
val _ = myAfterTask.value
result
}
}.value
Def.taskDyn
accepts a block which must return a Def.Initialize[Task[T]]
, which will be used to instantiate a task to be run later, after the main body of Def.taskDyn
completes. This allows one to compute tasks dynamically, and establish dependencies between tasks at runtime. As I said above, however, this can result in very strange errors happening at runtime, which are usually caused by loops in the dependency graph.
Therefore, the full example, with both "before" and "after" tasks, would look like this:
compile in Compile := Def.taskDyn {
val result = (compile in Compile).value
Def.task {
val _ = myAfterTask.value
result
}
}.dependsOn(myBeforeTask).value
edited Nov 14 '18 at 21:53
answered Nov 14 '18 at 21:10
Vladimir MatveevVladimir Matveev
70.4k15171214
70.4k15171214
What about doing something likecompile in Compile := {val r = (compile in Compile).value ; /* run after? */ ; r }
? Sorry can't really do multi line in comments :/
– Wonay
Nov 14 '18 at 21:14
1
@Wonay, yes, indeed, this would work - it would run the original compile task before your code. This won't allow you to express your "run after" task as a real task though. That being said, maybe you can simulate that with carefulDef.taskDyn
application, with all potential issues dynamic tasks introduce.
– Vladimir Matveev
Nov 14 '18 at 21:31
@Wonay please see the updated answer.
– Vladimir Matveev
Nov 14 '18 at 21:39
add a comment |
What about doing something likecompile in Compile := {val r = (compile in Compile).value ; /* run after? */ ; r }
? Sorry can't really do multi line in comments :/
– Wonay
Nov 14 '18 at 21:14
1
@Wonay, yes, indeed, this would work - it would run the original compile task before your code. This won't allow you to express your "run after" task as a real task though. That being said, maybe you can simulate that with carefulDef.taskDyn
application, with all potential issues dynamic tasks introduce.
– Vladimir Matveev
Nov 14 '18 at 21:31
@Wonay please see the updated answer.
– Vladimir Matveev
Nov 14 '18 at 21:39
What about doing something like
compile in Compile := {val r = (compile in Compile).value ; /* run after? */ ; r }
? Sorry can't really do multi line in comments :/– Wonay
Nov 14 '18 at 21:14
What about doing something like
compile in Compile := {val r = (compile in Compile).value ; /* run after? */ ; r }
? Sorry can't really do multi line in comments :/– Wonay
Nov 14 '18 at 21:14
1
1
@Wonay, yes, indeed, this would work - it would run the original compile task before your code. This won't allow you to express your "run after" task as a real task though. That being said, maybe you can simulate that with careful
Def.taskDyn
application, with all potential issues dynamic tasks introduce.– Vladimir Matveev
Nov 14 '18 at 21:31
@Wonay, yes, indeed, this would work - it would run the original compile task before your code. This won't allow you to express your "run after" task as a real task though. That being said, maybe you can simulate that with careful
Def.taskDyn
application, with all potential issues dynamic tasks introduce.– Vladimir Matveev
Nov 14 '18 at 21:31
@Wonay please see the updated answer.
– Vladimir Matveev
Nov 14 '18 at 21:39
@Wonay please see the updated answer.
– Vladimir Matveev
Nov 14 '18 at 21:39
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53307884%2fsbt-plugin-run-tasks-before-after-an-other-task%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown