From 31735051ea0f46015329ecc0d95834fc146db80c Mon Sep 17 00:00:00 2001 From: Eugene Vigdorchik Date: Wed, 15 Feb 2012 13:06:00 +0400 Subject: [PATCH 1/8] Overwrite previous setting if possible. --- main/SessionSettings.scala | 52 +++++++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 12 deletions(-) mode change 100644 => 100755 main/SessionSettings.scala diff --git a/main/SessionSettings.scala b/main/SessionSettings.scala old mode 100644 new mode 100755 index 659d1ead2..c94d687d8 --- a/main/SessionSettings.scala +++ b/main/SessionSettings.scala @@ -80,19 +80,49 @@ object SessionSettings } def saveSomeSettings(s: State)(include: ProjectRef => Boolean): State = withSettings(s){session => - for( (ref, settings) <- session.append if !settings.isEmpty && include(ref) ) - writeSettings(ref, settings, Project.structure(s)) - reapply(session.copy(original = session.mergeSettings, append = Map.empty), s) + val newAppend = + for( (ref, settings) <- session.append if !settings.isEmpty && include(ref) ) + yield ref -> writeSettings(ref, settings.toList, session.original, Project.structure(s)) + val newSession = session.copy(append = newAppend) + reapply(newSession.copy(original = newSession.mergeSettings, append = Map.empty), s) } - def writeSettings(pref: ProjectRef, settings: Seq[SessionSetting], structure: Load.BuildStructure) + def writeSettings(pref: ProjectRef, settings: List[SessionSetting], original: Seq[Setting[_]], structure: Load.BuildStructure): List[SessionSetting] = { val project = Project.getProject(pref, structure).getOrElse(error("Invalid project reference " + pref)) - val appendTo: File = BuildPaths.configurationSources(project.base).headOption.getOrElse(new File(project.base, "build.sbt")) - val baseAppend = settingStrings(settings).flatMap("" :: _ :: Nil) - val adjustedLines = if(appendTo.isFile && hasTrailingBlank(IO readLines appendTo) ) baseAppend else "" +: baseAppend - IO.writeLines(appendTo, adjustedLines, append = true) + val writeTo: File = BuildPaths.configurationSources(project.base).headOption.getOrElse(new File(project.base, "build.sbt")) + writeTo.createNewFile() + + val path = writeTo.getAbsolutePath + val inFile = original collect { s => s.pos match { case SourceCoord(`path`, line) => (s, line) } } + val (lineMap, newSettings) = splitAppended(inFile, settings) + val exist = IO.readLines(writeTo).zipWithIndex map { + case (line, idx) => lineMap get (idx+1) map (_._2) getOrElse line + } + val adjusted = if(!newSettings.isEmpty && needsTrailingBlank(exist)) exist :+ "" else exist + val lines = adjusted ++ newSettings.map(_._2).flatMap(_ :: "" :: Nil) + IO.writeLines(writeTo, lines) + val offs = adjusted.size + 1 + val withPos = newSettings zip Range(offs, offs + 2*newSettings.size, 2) map { + case ((s, text), line) => (s withPos SourceCoord(path, line), text) + } + withPos ++ lineMap.values } - def hasTrailingBlank(lines: Seq[String]) = lines.takeRight(1).exists(_.trim.isEmpty) + def splitAppended(original: Seq[(Setting[_], Int)], settings: List[SessionSetting]): (Map[Int, SessionSetting], List[SessionSetting]) = { + def depends(s: Setting[_]) = !s.init.dependencies.isEmpty + val (m, news) = ((Map.empty[Int, SessionSetting], List[SessionSetting]()) /: settings) { + case ((m, news), s) => + val replace = if (depends(s._1)) None else + original.collect { + case (orig, line) if orig.key == s._1.key => (orig, line -> s) + }.lastOption.collect { + // If the setting to replace depends on other keys, we'd better not delete a part of the dependency chain. + case (orig, bind) if !depends(orig) => bind + } + (m ++ replace, if (replace.isDefined) news else s::news) + } + (m, news.reverse) + } + def needsTrailingBlank(lines: Seq[String]) = !lines.isEmpty && !lines.takeRight(1).exists(_.trim.isEmpty) def printAllSettings(s: State): State = withSettings(s){ session => for( (ref, settings) <- session.append if !settings.isEmpty) { @@ -107,11 +137,9 @@ object SessionSettings s } def printSettings(settings: Seq[SessionSetting]): Unit = - for((stringRep, index) <- settingStrings(settings).zipWithIndex) + for(((_,stringRep), index) <- settings.zipWithIndex) println(" " + (index+1) + ". " + stringRep) - def settingStrings(s: Seq[SessionSetting]): Seq[String] = s.map(_._2) - def Help = """session Manipulates session settings, which are temporary settings that do not persist past the current sbt execution (that is, the current session). From e0b2475dd6027c9fdae60b3787e7fac1fd139d6f Mon Sep 17 00:00:00 2001 From: Eugene Vigdorchik Date: Wed, 15 Feb 2012 13:06:00 +0400 Subject: [PATCH 2/8] Overwrite previous setting if possible. --- main/SessionSettings.scala | 52 +++++++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 12 deletions(-) mode change 100644 => 100755 main/SessionSettings.scala diff --git a/main/SessionSettings.scala b/main/SessionSettings.scala old mode 100644 new mode 100755 index 659d1ead2..c94d687d8 --- a/main/SessionSettings.scala +++ b/main/SessionSettings.scala @@ -80,19 +80,49 @@ object SessionSettings } def saveSomeSettings(s: State)(include: ProjectRef => Boolean): State = withSettings(s){session => - for( (ref, settings) <- session.append if !settings.isEmpty && include(ref) ) - writeSettings(ref, settings, Project.structure(s)) - reapply(session.copy(original = session.mergeSettings, append = Map.empty), s) + val newAppend = + for( (ref, settings) <- session.append if !settings.isEmpty && include(ref) ) + yield ref -> writeSettings(ref, settings.toList, session.original, Project.structure(s)) + val newSession = session.copy(append = newAppend) + reapply(newSession.copy(original = newSession.mergeSettings, append = Map.empty), s) } - def writeSettings(pref: ProjectRef, settings: Seq[SessionSetting], structure: Load.BuildStructure) + def writeSettings(pref: ProjectRef, settings: List[SessionSetting], original: Seq[Setting[_]], structure: Load.BuildStructure): List[SessionSetting] = { val project = Project.getProject(pref, structure).getOrElse(error("Invalid project reference " + pref)) - val appendTo: File = BuildPaths.configurationSources(project.base).headOption.getOrElse(new File(project.base, "build.sbt")) - val baseAppend = settingStrings(settings).flatMap("" :: _ :: Nil) - val adjustedLines = if(appendTo.isFile && hasTrailingBlank(IO readLines appendTo) ) baseAppend else "" +: baseAppend - IO.writeLines(appendTo, adjustedLines, append = true) + val writeTo: File = BuildPaths.configurationSources(project.base).headOption.getOrElse(new File(project.base, "build.sbt")) + writeTo.createNewFile() + + val path = writeTo.getAbsolutePath + val inFile = original collect { s => s.pos match { case SourceCoord(`path`, line) => (s, line) } } + val (lineMap, newSettings) = splitAppended(inFile, settings) + val exist = IO.readLines(writeTo).zipWithIndex map { + case (line, idx) => lineMap get (idx+1) map (_._2) getOrElse line + } + val adjusted = if(!newSettings.isEmpty && needsTrailingBlank(exist)) exist :+ "" else exist + val lines = adjusted ++ newSettings.map(_._2).flatMap(_ :: "" :: Nil) + IO.writeLines(writeTo, lines) + val offs = adjusted.size + 1 + val withPos = newSettings zip Range(offs, offs + 2*newSettings.size, 2) map { + case ((s, text), line) => (s withPos SourceCoord(path, line), text) + } + withPos ++ lineMap.values } - def hasTrailingBlank(lines: Seq[String]) = lines.takeRight(1).exists(_.trim.isEmpty) + def splitAppended(original: Seq[(Setting[_], Int)], settings: List[SessionSetting]): (Map[Int, SessionSetting], List[SessionSetting]) = { + def depends(s: Setting[_]) = !s.init.dependencies.isEmpty + val (m, news) = ((Map.empty[Int, SessionSetting], List[SessionSetting]()) /: settings) { + case ((m, news), s) => + val replace = if (depends(s._1)) None else + original.collect { + case (orig, line) if orig.key == s._1.key => (orig, line -> s) + }.lastOption.collect { + // If the setting to replace depends on other keys, we'd better not delete a part of the dependency chain. + case (orig, bind) if !depends(orig) => bind + } + (m ++ replace, if (replace.isDefined) news else s::news) + } + (m, news.reverse) + } + def needsTrailingBlank(lines: Seq[String]) = !lines.isEmpty && !lines.takeRight(1).exists(_.trim.isEmpty) def printAllSettings(s: State): State = withSettings(s){ session => for( (ref, settings) <- session.append if !settings.isEmpty) { @@ -107,11 +137,9 @@ object SessionSettings s } def printSettings(settings: Seq[SessionSetting]): Unit = - for((stringRep, index) <- settingStrings(settings).zipWithIndex) + for(((_,stringRep), index) <- settings.zipWithIndex) println(" " + (index+1) + ". " + stringRep) - def settingStrings(s: Seq[SessionSetting]): Seq[String] = s.map(_._2) - def Help = """session Manipulates session settings, which are temporary settings that do not persist past the current sbt execution (that is, the current session). From d23d39cc0f1b9f48e09b94a98dd7f70fdb5d3cb6 Mon Sep 17 00:00:00 2001 From: Eugene Vigdorchik Date: Mon, 20 Feb 2012 12:27:26 +0400 Subject: [PATCH 3/8] Support multiline settings in build.sbt, assumes set command doesn't allow multiline settings. TODO:tests. --- main/SessionSettings.scala | 68 +++++++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 27 deletions(-) diff --git a/main/SessionSettings.scala b/main/SessionSettings.scala index c94d687d8..47bfc27d4 100755 --- a/main/SessionSettings.scala +++ b/main/SessionSettings.scala @@ -80,47 +80,61 @@ object SessionSettings } def saveSomeSettings(s: State)(include: ProjectRef => Boolean): State = withSettings(s){session => - val newAppend = - for( (ref, settings) <- session.append if !settings.isEmpty && include(ref) ) - yield ref -> writeSettings(ref, settings.toList, session.original, Project.structure(s)) - val newSession = session.copy(append = newAppend) + val newSettings = + for( (ref, settings) <- session.append if !settings.isEmpty && include(ref) ) yield { + val (news, olds) = writeSettings(ref, settings.toList, session.original, Project.structure(s)) + (ref -> news, olds) + } + val (newAppend, newOriginal) = newSettings.unzip + val newSession = session.copy(append = newAppend.toMap, original = newOriginal.flatten.toSeq) reapply(newSession.copy(original = newSession.mergeSettings, append = Map.empty), s) } - def writeSettings(pref: ProjectRef, settings: List[SessionSetting], original: Seq[Setting[_]], structure: Load.BuildStructure): List[SessionSetting] = + def writeSettings(pref: ProjectRef, settings: List[SessionSetting], original: Seq[Setting[_]], structure: Load.BuildStructure): (Seq[SessionSetting], Seq[Setting[_]]) = { val project = Project.getProject(pref, structure).getOrElse(error("Invalid project reference " + pref)) val writeTo: File = BuildPaths.configurationSources(project.base).headOption.getOrElse(new File(project.base, "build.sbt")) writeTo.createNewFile() val path = writeTo.getAbsolutePath - val inFile = original collect { s => s.pos match { case SourceCoord(`path`, line) => (s, line) } } - val (lineMap, newSettings) = splitAppended(inFile, settings) - val exist = IO.readLines(writeTo).zipWithIndex map { - case (line, idx) => lineMap get (idx+1) map (_._2) getOrElse line + val (inFile, other, _) = ((List[Setting[_]](), List[Setting[_]](), Set.empty[ScopedKey[_]]) /: original.reverse) { + case ((in, oth, keys), s) => + s.pos match { + case RangePosition(`path`, _) if !keys.contains(s.key) => (s::in, oth, keys + s.key) + case _ => (in, s::oth, keys) + } } + + val (_, oldShifted, replace, lineMap) = ((0, List[Setting[_]](), List[SessionSetting](), Map.empty[Int, (Int, String)]) /: inFile) { + case ((offs, olds, repl, lineMap), s) => + val RangePosition(_, r@LineRange(start, end)) = s.pos + def depends(s: Setting[_]) = !s.init.dependencies.isEmpty + settings find (_._1.key == s.key) match { + case Some(ss@(ns, text)) if !depends(s) && !depends(ns) => + val shifted = ns withPos RangePosition(path, LineRange(start - offs, start - offs + 1)) + (offs + end - start - 1, shifted::olds, ss::repl, lineMap + (start -> (end, text))) + case _ => + val shifted = s withPos RangePosition(path, r shift -offs) + (offs, shifted::olds, repl, lineMap) + } + } + val newSettings = settings diff replace + val (tmpLines, _) = ((List[String](), 1) /: IO.readLines(writeTo).zipWithIndex) { + case ((accLines, n), (line, m)) if n == m + 1 => + lineMap.get(n) match { + case Some(Pair(end, text)) => (text::accLines, end) + case None => (line::accLines, n + 1) + } + case (res,_) => res + } + val exist = tmpLines.reverse val adjusted = if(!newSettings.isEmpty && needsTrailingBlank(exist)) exist :+ "" else exist val lines = adjusted ++ newSettings.map(_._2).flatMap(_ :: "" :: Nil) IO.writeLines(writeTo, lines) val offs = adjusted.size + 1 - val withPos = newSettings zip Range(offs, offs + 2*newSettings.size, 2) map { - case ((s, text), line) => (s withPos SourceCoord(path, line), text) + val newWithPos = newSettings zip Range(offs, offs + 2*newSettings.size, 2) map { + case ((s, text), line) => (s withPos RangePosition(path, LineRange(line, line + 1)), text) } - withPos ++ lineMap.values - } - def splitAppended(original: Seq[(Setting[_], Int)], settings: List[SessionSetting]): (Map[Int, SessionSetting], List[SessionSetting]) = { - def depends(s: Setting[_]) = !s.init.dependencies.isEmpty - val (m, news) = ((Map.empty[Int, SessionSetting], List[SessionSetting]()) /: settings) { - case ((m, news), s) => - val replace = if (depends(s._1)) None else - original.collect { - case (orig, line) if orig.key == s._1.key => (orig, line -> s) - }.lastOption.collect { - // If the setting to replace depends on other keys, we'd better not delete a part of the dependency chain. - case (orig, bind) if !depends(orig) => bind - } - (m ++ replace, if (replace.isDefined) news else s::news) - } - (m, news.reverse) + (newWithPos, other ++ oldShifted) } def needsTrailingBlank(lines: Seq[String]) = !lines.isEmpty && !lines.takeRight(1).exists(_.trim.isEmpty) def printAllSettings(s: State): State = From eaa10b7a48d8e4ecf464b1bcef906c22ced8511e Mon Sep 17 00:00:00 2001 From: Eugene Vigdorchik Date: Mon, 20 Feb 2012 15:52:57 +0400 Subject: [PATCH 4/8] Support multi-line replacements. --- main/SessionSettings.scala | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/main/SessionSettings.scala b/main/SessionSettings.scala index 9cc36cc0e..3d0cff4f4 100755 --- a/main/SessionSettings.scala +++ b/main/SessionSettings.scala @@ -104,14 +104,15 @@ object SessionSettings } } - val (_, oldShifted, replace, lineMap) = ((0, List[Setting[_]](), List[SessionSetting](), Map.empty[Int, (Int, String)]) /: inFile) { + val (_, oldShifted, replace, lineMap) = ((0, List[Setting[_]](), List[SessionSetting](), Map.empty[Int, (Int, List[String])]) /: inFile) { case ((offs, olds, repl, lineMap), s) => val RangePosition(_, r@LineRange(start, end)) = s.pos def depends(s: Setting[_]) = !s.init.dependencies.isEmpty settings find (_._1.key == s.key) match { case Some(ss@(ns, text)) if !depends(s) && !depends(ns) => val shifted = ns withPos RangePosition(path, LineRange(start - offs, start - offs + 1)) - (offs + end - start - 1, shifted::olds, ss::repl, lineMap + (start -> (end, text))) + val newLines = text.split('\n').toList + (offs + end - start - newLines.size, shifted::olds, ss::repl, lineMap + (start -> (end, newLines))) case _ => val shifted = s withPos RangePosition(path, r shift -offs) (offs, shifted::olds, repl, lineMap) @@ -121,20 +122,21 @@ object SessionSettings val (tmpLines, _) = ((List[String](), 1) /: IO.readLines(writeTo).zipWithIndex) { case ((accLines, n), (line, m)) if n == m + 1 => lineMap.get(n) match { - case Some(Pair(end, text)) => (text::accLines, end) + case Some(Pair(end, lines)) => (lines reverse_::: accLines, end) case None => (line::accLines, n + 1) } case (res,_) => res } val exist = tmpLines.reverse val adjusted = if(!newSettings.isEmpty && needsTrailingBlank(exist)) exist :+ "" else exist - val lines = adjusted ++ newSettings.map(_._2).flatMap(_ :: "" :: Nil) + val lines = adjusted ++ newSettings.map(_._2 split '\n').flatten.flatMap(_ :: "" :: Nil) IO.writeLines(writeTo, lines) - val offs = adjusted.size + 1 - val newWithPos = newSettings zip Range(offs, offs + 2*newSettings.size, 2) map { - case ((s, text), line) => (s withPos RangePosition(path, LineRange(line, line + 1)), text) + val (newWithPos, _) = ((List[SessionSetting](), adjusted.size + 1) /: newSettings) { + case ((acc, line), (s, text)) => + val endLine = line + text.split('\n').size + ((s withPos RangePosition(path, LineRange(line, endLine)), text)::acc, endLine + 1) } - (newWithPos, other ++ oldShifted) + (newWithPos.reverse, other ++ oldShifted) } def needsTrailingBlank(lines: Seq[String]) = !lines.isEmpty && !lines.takeRight(1).exists(_.trim.isEmpty) def printAllSettings(s: State): State = From bb646d04378c6e86bff89f58d669d8518abc820e Mon Sep 17 00:00:00 2001 From: Eugene Vigdorchik Date: Mon, 27 Feb 2012 11:46:23 +0400 Subject: [PATCH 5/8] SessionSetting to contain seq of line. --- main/Main.scala | 2 +- main/SessionSettings.scala | 13 ++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/main/Main.scala b/main/Main.scala index bfa7dafaf..1c547f67b 100644 --- a/main/Main.scala +++ b/main/Main.scala @@ -174,7 +174,7 @@ object BuiltinCommands { import extracted._ val append = Load.transformSettings(Load.projectScope(currentRef), currentRef.build, rootProject, settings) - session.appendSettings( append map (a => (a, arg))) + session.appendSettings( append map (a => (a, arg.split('\n').toList))) } def inspect = Command(InspectCommand, inspectBrief, inspectDetailed)(inspectParser) { case (s, (option, sk)) => logger(s).info(inspectOutput(s, option, sk)) diff --git a/main/SessionSettings.scala b/main/SessionSettings.scala index 3d0cff4f4..ca5511a66 100755 --- a/main/SessionSettings.scala +++ b/main/SessionSettings.scala @@ -30,7 +30,7 @@ final case class SessionSettings(currentBuild: URI, currentProject: Map[URI, Str } object SessionSettings { - type SessionSetting = (Setting[_], String) + type SessionSetting = (Setting[_], List[String]) type SessionMap = Map[ProjectRef, Seq[SessionSetting]] def reapply(session: SessionSettings, s: State): State = @@ -109,9 +109,8 @@ object SessionSettings val RangePosition(_, r@LineRange(start, end)) = s.pos def depends(s: Setting[_]) = !s.init.dependencies.isEmpty settings find (_._1.key == s.key) match { - case Some(ss@(ns, text)) if !depends(s) && !depends(ns) => + case Some(ss@(ns, newLines)) if !depends(s) && !depends(ns) => val shifted = ns withPos RangePosition(path, LineRange(start - offs, start - offs + 1)) - val newLines = text.split('\n').toList (offs + end - start - newLines.size, shifted::olds, ss::repl, lineMap + (start -> (end, newLines))) case _ => val shifted = s withPos RangePosition(path, r shift -offs) @@ -129,12 +128,12 @@ object SessionSettings } val exist = tmpLines.reverse val adjusted = if(!newSettings.isEmpty && needsTrailingBlank(exist)) exist :+ "" else exist - val lines = adjusted ++ newSettings.map(_._2 split '\n').flatten.flatMap(_ :: "" :: Nil) + val lines = adjusted ++ newSettings.map(_._2).flatten.flatMap(_ :: "" :: Nil) IO.writeLines(writeTo, lines) val (newWithPos, _) = ((List[SessionSetting](), adjusted.size + 1) /: newSettings) { - case ((acc, line), (s, text)) => - val endLine = line + text.split('\n').size - ((s withPos RangePosition(path, LineRange(line, endLine)), text)::acc, endLine + 1) + case ((acc, line), (s, newLines)) => + val endLine = line + newLines.size + ((s withPos RangePosition(path, LineRange(line, endLine)), newLines)::acc, endLine + 1) } (newWithPos.reverse, other ++ oldShifted) } From e747b7b378799d46b712d09c15f86c2d45eda8f3 Mon Sep 17 00:00:00 2001 From: Eugene Vigdorchik Date: Mon, 27 Feb 2012 18:28:06 +0400 Subject: [PATCH 6/8] Add simple scripted test to verify overwrite functionality doesn't break .sbt file. --- .../sbt-test/project/session-save/build.sbt | 6 +++++ .../project/session-save/project/Build.scala | 8 +++++++ sbt/src/sbt-test/project/session-save/test | 22 +++++++++++++++++++ 3 files changed, 36 insertions(+) create mode 100755 sbt/src/sbt-test/project/session-save/build.sbt create mode 100755 sbt/src/sbt-test/project/session-save/project/Build.scala create mode 100755 sbt/src/sbt-test/project/session-save/test diff --git a/sbt/src/sbt-test/project/session-save/build.sbt b/sbt/src/sbt-test/project/session-save/build.sbt new file mode 100755 index 000000000..fcf95068c --- /dev/null +++ b/sbt/src/sbt-test/project/session-save/build.sbt @@ -0,0 +1,6 @@ +k1 := { +} + +k2 := { +} + diff --git a/sbt/src/sbt-test/project/session-save/project/Build.scala b/sbt/src/sbt-test/project/session-save/project/Build.scala new file mode 100755 index 000000000..d90a26779 --- /dev/null +++ b/sbt/src/sbt-test/project/session-save/project/Build.scala @@ -0,0 +1,8 @@ +import sbt._ + +object TestBuild extends Build { + val k1 = TaskKey[Unit]("k1") + val k2 = TaskKey[Unit]("k2") + + lazy val root = Project("root", file(".")) +} diff --git a/sbt/src/sbt-test/project/session-save/test b/sbt/src/sbt-test/project/session-save/test new file mode 100755 index 000000000..9011de364 --- /dev/null +++ b/sbt/src/sbt-test/project/session-save/test @@ -0,0 +1,22 @@ +> set k1 := {error("k1")} +> session save +> reload +-> k1 + +> set k2 <<= k1 map identity +> session save +> reload +-> k2 + +> set k1 := {} +> session save +> reload +> k1 +> k2 + +> set k1 <<= k1 map {_ => error("k1")} +> set k2 := {} +> session save +> reload +-> k1 +> k2 \ No newline at end of file From cca5b7e2f7b15a2ad21520c4a98ebd1480d1feb5 Mon Sep 17 00:00:00 2001 From: Eugene Vigdorchik Date: Mon, 27 Feb 2012 19:24:10 +0400 Subject: [PATCH 7/8] Add overwrite validation to the test. --- sbt/src/sbt-test/project/session-save/build.check.1 | 7 +++++++ sbt/src/sbt-test/project/session-save/build.check.2 | 7 +++++++ sbt/src/sbt-test/project/session-save/test | 5 ++++- scripted/base/FileCommands.scala | 9 ++++++++- 4 files changed, 26 insertions(+), 2 deletions(-) create mode 100755 sbt/src/sbt-test/project/session-save/build.check.1 create mode 100755 sbt/src/sbt-test/project/session-save/build.check.2 diff --git a/sbt/src/sbt-test/project/session-save/build.check.1 b/sbt/src/sbt-test/project/session-save/build.check.1 new file mode 100755 index 000000000..85beb3faa --- /dev/null +++ b/sbt/src/sbt-test/project/session-save/build.check.1 @@ -0,0 +1,7 @@ +k1 := {error("k1")} + +k2 := { +} + +k2 <<= k1 map identity + diff --git a/sbt/src/sbt-test/project/session-save/build.check.2 b/sbt/src/sbt-test/project/session-save/build.check.2 new file mode 100755 index 000000000..d47b51846 --- /dev/null +++ b/sbt/src/sbt-test/project/session-save/build.check.2 @@ -0,0 +1,7 @@ +k1 := {} + +k2 := { +} + +k2 <<= k1 map identity + diff --git a/sbt/src/sbt-test/project/session-save/test b/sbt/src/sbt-test/project/session-save/test index 9011de364..c552f3a31 100755 --- a/sbt/src/sbt-test/project/session-save/test +++ b/sbt/src/sbt-test/project/session-save/test @@ -7,16 +7,19 @@ > session save > reload -> k2 +$ must-mirror build.sbt build.check.1 > set k1 := {} > session save > reload > k1 > k2 +$ must-mirror build.sbt build.check.2 > set k1 <<= k1 map {_ => error("k1")} > set k2 := {} > session save > reload -> k1 -> k2 \ No newline at end of file +> k2 +$ must-mirror build.sbt build.check.3 \ No newline at end of file diff --git a/scripted/base/FileCommands.scala b/scripted/base/FileCommands.scala index 6c9ca1c68..d425911ad 100644 --- a/scripted/base/FileCommands.scala +++ b/scripted/base/FileCommands.scala @@ -24,6 +24,7 @@ class FileCommands(baseDirectory: File) extends BasicStatementHandler "exec" nonEmpty(execute _ ), "copy" copy (to => rebase(baseDirectory, to)), "copy-file" twoArg("Two paths", copyFile _), + "must-mirror" twoArg("Two paths", diffFiles _), "copy-flat" copy flat ) @@ -42,6 +43,12 @@ class FileCommands(baseDirectory: File) extends BasicStatementHandler IO.copyFile(fromString(from), fromString(to)) def makeDirectories(paths: List[String]) = IO.createDirectories(fromStrings(paths)) + def diffFiles(file1: String, file2: String) = { + val lines1 = IO.readLines(fromString(file1)) + val lines2 = IO.readLines(fromString(file2)) + if (lines1 != lines2) + scriptError("File contents are different:\n" + lines1.mkString("\n") + "\nAnd:\n" + lines2.mkString("\n")) + } def newer(a: String, b: String) = { @@ -115,4 +122,4 @@ class FileCommands(baseDirectory: File) extends BasicStatementHandler def wrongArguments(requiredArgs: String, args: List[String]): Some[String] = scriptError("Wrong number of arguments to " + commandName + " command. " + requiredArgs + " required, found: '" + spaced(args) + "'.") } -} \ No newline at end of file +} From 63aa36bd1eb3e3940576757d68e4423f6b8ca473 Mon Sep 17 00:00:00 2001 From: Eugene Vigdorchik Date: Mon, 27 Feb 2012 22:28:09 +0400 Subject: [PATCH 8/8] More agressive overwrite. --- main/SessionSettings.scala | 3 +-- sbt/src/sbt-test/project/session-save/build.check.1 | 3 --- sbt/src/sbt-test/project/session-save/build.check.2 | 3 --- sbt/src/sbt-test/project/session-save/build.check.3 | 6 ++++++ 4 files changed, 7 insertions(+), 8 deletions(-) create mode 100755 sbt/src/sbt-test/project/session-save/build.check.3 diff --git a/main/SessionSettings.scala b/main/SessionSettings.scala index ca5511a66..2a487c0d2 100755 --- a/main/SessionSettings.scala +++ b/main/SessionSettings.scala @@ -107,9 +107,8 @@ object SessionSettings val (_, oldShifted, replace, lineMap) = ((0, List[Setting[_]](), List[SessionSetting](), Map.empty[Int, (Int, List[String])]) /: inFile) { case ((offs, olds, repl, lineMap), s) => val RangePosition(_, r@LineRange(start, end)) = s.pos - def depends(s: Setting[_]) = !s.init.dependencies.isEmpty settings find (_._1.key == s.key) match { - case Some(ss@(ns, newLines)) if !depends(s) && !depends(ns) => + case Some(ss@(ns, newLines)) if !ns.init.dependencies.contains(ns.key) => val shifted = ns withPos RangePosition(path, LineRange(start - offs, start - offs + 1)) (offs + end - start - newLines.size, shifted::olds, ss::repl, lineMap + (start -> (end, newLines))) case _ => diff --git a/sbt/src/sbt-test/project/session-save/build.check.1 b/sbt/src/sbt-test/project/session-save/build.check.1 index 85beb3faa..1e25d0391 100755 --- a/sbt/src/sbt-test/project/session-save/build.check.1 +++ b/sbt/src/sbt-test/project/session-save/build.check.1 @@ -1,7 +1,4 @@ k1 := {error("k1")} -k2 := { -} - k2 <<= k1 map identity diff --git a/sbt/src/sbt-test/project/session-save/build.check.2 b/sbt/src/sbt-test/project/session-save/build.check.2 index d47b51846..42c414288 100755 --- a/sbt/src/sbt-test/project/session-save/build.check.2 +++ b/sbt/src/sbt-test/project/session-save/build.check.2 @@ -1,7 +1,4 @@ k1 := {} -k2 := { -} - k2 <<= k1 map identity diff --git a/sbt/src/sbt-test/project/session-save/build.check.3 b/sbt/src/sbt-test/project/session-save/build.check.3 new file mode 100755 index 000000000..ad18cca9f --- /dev/null +++ b/sbt/src/sbt-test/project/session-save/build.check.3 @@ -0,0 +1,6 @@ +k1 := {} + +k2 := {} + +k1 <<= k1 map {_ => error("k1")} +