summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Haoyi <haoyi.sg@gmail.com>2018-02-17 23:41:39 -0800
committerLi Haoyi <haoyi.sg@gmail.com>2018-02-17 23:45:43 -0800
commit0013898d7628980f920dba7eed68153b36fd26fb (patch)
tree04306367d8e1a95817dcaf39ae4302d51b629432
parent6c66864dd45cb1f12524f9645b2c9158e5e0b592 (diff)
downloadmill-0013898d7628980f920dba7eed68153b36fd26fb.tar.gz
mill-0013898d7628980f920dba7eed68153b36fd26fb.tar.bz2
mill-0013898d7628980f920dba7eed68153b36fd26fb.zip
Update resolution tests in `MainTests.scala`
Added test cases for new "Did you mean...", "Try `mill.resolve ...`" hints
-rw-r--r--core/src/mill/eval/Evaluator.scala2
-rw-r--r--main/src/mill/main/Resolve.scala61
-rw-r--r--main/test/src/mill/eval/EvaluationTests.scala4
-rw-r--r--main/test/src/mill/main/MainTests.scala63
4 files changed, 93 insertions, 37 deletions
diff --git a/core/src/mill/eval/Evaluator.scala b/core/src/mill/eval/Evaluator.scala
index 0a2ec6d8..23a06cc2 100644
--- a/core/src/mill/eval/Evaluator.scala
+++ b/core/src/mill/eval/Evaluator.scala
@@ -71,7 +71,7 @@ case class Evaluator[T](outPath: Path,
val additional =
if (finalTaskOverrides == t.ctx.overrides) Nil
- else Seq(Segment.Label("overriden"), Segment.Label(t.ctx.enclosing))
+ else Seq(Segment.Label("overriden")) ++ t.ctx.enclosing.split('.').map(Segment.Label)
Right(Labelled(t, segments ++ additional))
case t if goals.contains(t) => Left(t)
diff --git a/main/src/mill/main/Resolve.scala b/main/src/mill/main/Resolve.scala
index 01c3dcf3..ccb5ec04 100644
--- a/main/src/mill/main/Resolve.scala
+++ b/main/src/mill/main/Resolve.scala
@@ -130,8 +130,6 @@ object ResolveTasks extends Resolve[NamedTask[Any]]{
command orElse target orElse Resolve.runDefault(obj, Segment.Label(last), discover, rest).flatten.headOption match {
case None =>
- pprint.log(revSelectorsSoFar)
- pprint.log(last)
Resolve.errorMsgLabel(
singleModuleMeta(obj, discover, revSelectorsSoFar.isEmpty),
last,
@@ -168,25 +166,26 @@ object Resolve{
def unableToResolve(segments: String): String = "Cannot resolve " + segments + "."
- def hintList(last: Segment, revSelectorsSoFar: List[Segment]) = {
- val search = Segments((last :: revSelectorsSoFar).reverse: _*).render
+ def hintList(revSelectorsSoFar: List[Segment]) = {
+ val search = Segments(revSelectorsSoFar.reverse: _*).render
s" Try `mill resolve $search` to see what's available."
}
def hintListLabel(revSelectorsSoFar: List[Segment]) = {
- hintList(Segment.Label("_"), revSelectorsSoFar)
+ hintList(Segment.Label("_") :: revSelectorsSoFar)
}
def hintListCross(revSelectorsSoFar: List[Segment]) = {
- hintList(Segment.Cross(Seq("__")), revSelectorsSoFar)
+ hintList(Segment.Cross(Seq("__")) :: revSelectorsSoFar)
}
def errorMsgBase[T](direct: Seq[T],
last0: T,
revSelectorsSoFar: List[Segment],
- editSplit: String => String)
+ editSplit: String => String,
+ defaultErrorMsg: String)
(strings: T => Seq[String],
- render: T => String)= {
+ render: T => String): Left[String, Nothing] = {
val last = strings(last0)
val similar =
direct
@@ -196,19 +195,29 @@ object Resolve{
.filter(_._2 < 3)
.sortBy(_._2)
- val hint = similar match{
- case Nil => hintListLabel(revSelectorsSoFar)
- case items =>
- " Did you mean " + render(items.head._1)+ "?"
+ if (similar.headOption.exists(_._1 == last0)){
+ // Special case: if the most similar segment is the desired segment itself,
+ // this means we are trying to resolve a module where a task is present.
+ // Special case the error message to make it something meaningful
+ Left("Task " + last0 + " is not a module and has no children.")
+ }else{
+
+ val hint = similar match{
+ case Nil => defaultErrorMsg
+ case items => " Did you mean " + render(items.head._1) + "?"
+ }
+ Left(unableToResolve(render(last0)) + hint)
}
- pprint.log(direct)
- pprint.log(revSelectorsSoFar)
- pprint.log(last0)
- pprint.log(last)
- Left(unableToResolve(render(last0)) + hint)
}
+
def errorMsgLabel(direct: Seq[String], last: String, revSelectorsSoFar: List[Segment]) = {
- errorMsgBase(direct, Segments((Segment.Label(last) :: revSelectorsSoFar).reverse:_*).render, revSelectorsSoFar, _.split('.').last)(
+ errorMsgBase(
+ direct,
+ Segments((Segment.Label(last) :: revSelectorsSoFar).reverse:_*).render,
+ revSelectorsSoFar,
+ _.split('.').last,
+ hintListLabel(revSelectorsSoFar)
+ )(
rendered => Seq(rendered.split('.').last),
x => x
)
@@ -217,7 +226,13 @@ object Resolve{
def errorMsgCross(crossKeys: Seq[Seq[String]],
last: Seq[String],
revSelectorsSoFar: List[Segment]) = {
- errorMsgBase(crossKeys, last, revSelectorsSoFar, x => x)(
+ errorMsgBase(
+ crossKeys,
+ last,
+ revSelectorsSoFar,
+ x => x,
+ hintListCross(revSelectorsSoFar)
+ )(
crossKeys => crossKeys,
crossKeys => Segments((Segment.Cross(crossKeys) :: revSelectorsSoFar).reverse:_*).render
)
@@ -308,11 +323,15 @@ abstract class Resolve[R: ClassTag] {
.find(_.millOuterCtx.segment == Segment.Label(singleLabel))
.toSeq
},
- Resolve.errorMsgLabel(
+ if (singleLabel != "_") Resolve.errorMsgLabel(
singleModuleMeta(obj, discover, revSelectorsSoFar.isEmpty),
singleLabel,
revSelectorsSoFar
)
+ else Left(
+ "Cannot resolve " + Segments((remainingSelector.reverse ++ revSelectorsSoFar).reverse:_*).render +
+ ". Try `mill resolve " + Segments((Segment.Label("_") :: revSelectorsSoFar).reverse:_*).render + "` to see what's available"
+ )
)
case Segment.Cross(cross) =>
obj match{
@@ -329,7 +348,7 @@ abstract class Resolve[R: ClassTag] {
Resolve.errorMsgCross(
c.items.map(_._1.map(_.toString)),
cross.map(_.toString),
- newRevSelectorsSoFar
+ revSelectorsSoFar
)
)
case _ =>
diff --git a/main/test/src/mill/eval/EvaluationTests.scala b/main/test/src/mill/eval/EvaluationTests.scala
index e5f0e57d..da399449 100644
--- a/main/test/src/mill/eval/EvaluationTests.scala
+++ b/main/test/src/mill/eval/EvaluationTests.scala
@@ -211,7 +211,7 @@ object EvaluationTests extends TestSuite{
val public = ammonite.ops.read(checker.evaluator.outPath / 'foo / "meta.json")
val overriden = ammonite.ops.read(
checker.evaluator.outPath / 'foo /
- 'overriden / "mill.util.TestGraphs.BaseModule#foo" / "meta.json"
+ 'overriden / "mill" / "util" / "TestGraphs" / "BaseModule#foo" / "meta.json"
)
assert(
public.contains("base"),
@@ -239,7 +239,7 @@ object EvaluationTests extends TestSuite{
val public = ammonite.ops.read(checker.evaluator.outPath / 'cmd / "meta.json")
val overriden = ammonite.ops.read(
checker.evaluator.outPath / 'cmd /
- 'overriden / "mill.util.TestGraphs.BaseModule#cmd" / "meta.json"
+ 'overriden / "mill" / "util" / "TestGraphs" / "BaseModule#cmd" / "meta.json"
)
assert(
public.contains("base1"),
diff --git a/main/test/src/mill/main/MainTests.scala b/main/test/src/mill/main/MainTests.scala
index 7ad5c00e..fbf193e1 100644
--- a/main/test/src/mill/main/MainTests.scala
+++ b/main/test/src/mill/main/MainTests.scala
@@ -27,19 +27,39 @@ object MainTests extends TestSuite{
'single - {
val check = MainTests.check(singleton) _
'pos - check("single", Right(Seq(_.single)))
- 'neg1 - check("doesntExist", Left("Cannot resolve doesntExist. Try `mill resolve _` to see what's available."))
- 'neg2 - check("single.doesntExist", Left("Cannot resolve single. Try `mill resolve _` to see what's available."))
- 'neg3 - check("", Left("Selector cannot be empty"))
+ 'neg1 - check("sngle", Left("Cannot resolve sngle. Did you mean single?"))
+ 'neg2 - check("snigle", Left("Cannot resolve snigle. Did you mean single?"))
+ 'neg3 - check("nsiigle", Left("Cannot resolve nsiigle. Did you mean single?"))
+ 'neg4 - check("ansiigle", Left("Cannot resolve ansiigle. Try `mill resolve _` to see what's available."))
+ 'neg5 - check("doesntExist", Left("Cannot resolve doesntExist. Try `mill resolve _` to see what's available."))
+ 'neg6 - check("single.doesntExist", Left("Task single is not a module and has no children."))
+ 'neg7 - check("", Left("Selector cannot be empty"))
}
'nested - {
val check = MainTests.check(nestedModule) _
'pos1 - check("single", Right(Seq(_.single)))
'pos2 - check("nested.single", Right(Seq(_.nested.single)))
'pos3 - check("classInstance.single", Right(Seq(_.classInstance.single)))
- 'neg1 - check("doesntExist", Left("Cannot resolve doesntExist"))
- 'neg2 - check("single.doesntExist", Left("Cannot resolve single"))
- 'neg3 - check("nested.doesntExist", Left("Cannot resolve nested.doesntExist"))
- 'neg4 - check("classInstance.doesntExist", Left("Cannot resolve classInstance.doesntExist"))
+ 'neg1 - check(
+ "doesntExist",
+ Left("Cannot resolve doesntExist. Try `mill resolve _` to see what's available.")
+ )
+ 'neg2 - check(
+ "single.doesntExist",
+ Left("Task single is not a module and has no children.")
+ )
+ 'neg3 - check(
+ "nested.doesntExist",
+ Left("Cannot resolve nested.doesntExist. Try `mill resolve nested._` to see what's available.")
+ )
+ 'neg3 - check(
+ "nested.singel",
+ Left("Cannot resolve nested.singel. Did you mean nested.single?")
+ )
+ 'neg4 - check(
+ "classInstance.doesntExist",
+ Left("Cannot resolve classInstance.doesntExist. Try `mill resolve classInstance._` to see what's available.")
+ )
'wildcard - check(
"_.single",
Right(Seq(
@@ -49,11 +69,15 @@ object MainTests extends TestSuite{
)
'wildcardNeg - check(
"_._.single",
- Left("Cannot resolve _")
+ Left("Cannot resolve _._.single. Try `mill resolve _` to see what's available")
)
'wildcardNeg2 - check(
"_._.__",
- Left("Cannot resolve _")
+ Left("Cannot resolve _._.__. Try `mill resolve _` to see what's available")
+ )
+ 'wildcardNeg3 - check(
+ "nested._.foobar",
+ Left("Cannot resolve nested._.foobar. Try `mill resolve nested._` to see what's available")
)
'wildcard2 - check(
"__.single",
@@ -78,9 +102,22 @@ object MainTests extends TestSuite{
val check = MainTests.check(singleCross) _
'pos1 - check("cross[210].suffix", Right(Seq(_.cross("210").suffix)))
'pos2 - check("cross[211].suffix", Right(Seq(_.cross("211").suffix)))
- 'neg1 - check("cross[210].doesntExist", Left("Cannot resolve cross[210].doesntExist"))
- 'neg2 - check("cross[doesntExist].doesntExist", Left("Cannot resolve cross[doesntExist]"))
- 'neg2 - check("cross[doesntExist].suffix", Left("Cannot resolve cross[doesntExist]"))
+ 'neg1 - check(
+ "cross[210].doesntExist",
+ Left("Cannot resolve cross[210].doesntExist. Try `mill resolve cross[210]._` to see what's available.")
+ )
+ 'neg2 - check(
+ "cross[doesntExist].doesntExist",
+ Left("Cannot resolve cross[doesntExist]. Try `mill resolve cross[__]` to see what's available.")
+ )
+ 'neg3 - check(
+ "cross[221].doesntExist",
+ Left("Cannot resolve cross[221]. Did you mean cross[211]?")
+ )
+ 'neg4 - check(
+ "cross[doesntExist].suffix",
+ Left("Cannot resolve cross[doesntExist]. Try `mill resolve cross[__]` to see what's available.")
+ )
'wildcard - check(
"cross[_].suffix",
Right(Seq(
@@ -111,7 +148,7 @@ object MainTests extends TestSuite{
'wildcard - {
'labelNeg - check(
"_.suffix",
- Left("Cannot resolve _.suffix")
+ Left("Cannot resolve _.suffix. Try `mill resolve _._` to see what's available.")
)
'labelPos - check(
"__.suffix",