<commit_before>/* sbt -- Simple Build Tool
 * Copyright 2011 <NAME>
 */
package sbt

	import java.io.File
	import java.net.URI
	import Project._
	import Types.Endo
	import Command.{HistoryPath,Watch}
	import CommandSupport.logger
	import compile.Eval

final case class Project(id: String, base: File, aggregate: Seq[ProjectRef] = Nil, dependencies: Seq[Project.ClasspathDependency] = Nil, inherits: Seq[ProjectRef] = Nil,
	settings: Seq[Project.Setting[_]] = Project.defaultSettings, configurations: Seq[Configuration] = Configurations.default)
{
	def uses = aggregate ++ dependencies.map(_.project)
}
final case class Extracted(structure: Load.BuildStructure, session: SessionSettings, curi: URI, cid: String, rootProject: URI => String)

object Project extends Init[Scope]
{
	def defaultSettings: Seq[Setting[_]] = Nil

	final case class ClasspathDependency(project: ProjectRef, configuration: Option[String])
	final class Constructor(p: ProjectRef) {
		def %(conf: String): ClasspathDependency = new ClasspathDependency(p, Some(conf))
	}

	def getOrError[T](state: State, key: AttributeKey[T], msg: String): T = state get key getOrElse error(msg)
	def structure(state: State): Load.BuildStructure = getOrError(state, StructureKey, "No build loaded.")
	def session(state: State): SessionSettings = getOrError(state, SessionKey, "Session not initialized.")
	def extract(state: State): Extracted =
	{
		val se = session(state)
		val (curi, cid) = se.current
		val st = structure(state)
		Extracted(st, se, curi, cid, Load.getRootProject(st.units))
	}
	
	def current(state: State): (URI, String) = session(state).current
	def currentRef(state: State): ProjectRef =
	{
		val (unit, it) = current(state)
		ProjectRef(Some(unit), Some(it))
	}
	def updateCurrent(s: State): State =
	{
		val structure = Project.structure(s)
		val (uri, id) = Project.current(s)
		val ref = ProjectRef(uri, id)
		val project = Load.getProject(structure.units, uri, id)
		logger(s).info("Set current project to " + id + " (in build " + uri +")")

		val data = structure.data
		val historyPath = HistoryPath(ref).get(data).flatMap(identity)
		val newAttrs = s.attributes.put(Watch.key, makeWatched(data, ref, project)).put(HistoryPath.key, historyPath)
		s.copy(attributes = newAttrs)
	}

	def makeWatched(data: Settings[Scope], ref: ProjectRef, project: Project): Watched =
	{
		def getWatch(ref: ProjectRef) = Watch(ref).get(data)
		getWatch(ref) match
		{
			case Some(currentWatch) =>
				val subWatches = project.uses flatMap { p => getWatch(p) }
				Watched.multi(currentWatch, subWatches)
			case None => Watched.empty
		}
	}
	def display(scoped: ScopedKey[_]): String = Scope.display(scoped.scope, scoped.key.label)

	def mapScope(f: Scope => Scope) = new  (ScopedKey ~> ScopedKey) { def apply[T](key: ScopedKey[T]) =
		ScopedKey( f(key.scope), key.key)
	}
	def transform(g: Scope => Scope, ss: Seq[Setting[_]]): Seq[Setting[_]] = {
		val f = mapScope(g)
		ss.map(_ mapKey f mapReferenced f)
	}

	val SessionKey = AttributeKey[SessionSettings]("session-settings")
	val StructureKey = AttributeKey[Load.BuildStructure]("build-structure")
}

	import SessionSettings._

final case class SessionSettings(currentBuild: URI, currentProject: Map[URI, String], original: Seq[Setting[_]], prepend: SessionMap, append: SessionMap, currentEval: () => Eval)
{
	assert(currentProject contains currentBuild, "Current build (" + currentBuild + ") not associated with a current project.")
	def setCurrent(build: URI, project: String, eval: () => Eval): SessionSettings = copy(currentBuild = build, currentProject = currentProject.updated(build, project), currentEval = eval)
	def current: (URI, String) = (currentBuild, currentProject(currentBuild))
	def appendSettings(s: Seq[SessionSetting]): SessionSettings = copy(append = modify(append, _ ++ s))
	def prependSettings(s: Seq[SessionSetting]): SessionSettings = copy(prepend = modify(prepend, s ++ _))
	def mergeSettings: Seq[Setting[_]] = merge(prepend) ++ original ++ merge(append)

	private[this] def merge(map: SessionMap): Seq[Setting[_]] = map.values.toSeq.flatten[SessionSetting].map(_._1)
	private[this] def modify(map: SessionMap, onSeq: Endo[Seq[SessionSetting]]): SessionMap =
	{
		val cur = current
		map.updated(cur, onSeq(map.getOrElse( cur, Nil)))
	}
	
}
object SessionSettings
{
	type SessionSetting = (Setting[_], String)
	type SessionMap = Map[(URI, String), Seq[SessionSetting]]
}

trait ProjectConstructors
{
	implicit def configDependencyConstructor[T <% ProjectRef](p: T): Project.Constructor = new Project.Constructor(p)
	implicit def classpathDependency[T <% ProjectRef](p: T): Project.ClasspathDependency = new Project.ClasspathDependency(p, None)
}
// the URI must be resolved and normalized before it is definitive
final case class ProjectRef(uri: Option[URI], id: Option[String])
object ProjectRef
{
	def apply(base: URI, id: String): ProjectRef = ProjectRef(Some(base), Some(id))
	/** Reference to the project with 'id' in the current build unit.*/<commit_msg>add builder convenience methods to Project<commit_after>/* sbt -- Simple Build Tool
 * Copyright 2011 <NAME>
 */
package sbt

	import java.io.File
	import java.net.URI
	import Project._
	import Types.Endo
	import Command.{HistoryPath,Watch}
	import CommandSupport.logger
	import compile.Eval

final case class Project(id: String, base: File, aggregate: Seq[ProjectRef] = Nil, dependencies: Seq[Project.ClasspathDependency] = Nil, inherits: Seq[ProjectRef] = Nil,
	settings: Seq[Project.Setting[_]] = Project.defaultSettings, configurations: Seq[Configuration] = Configurations.default)
{
	def dependsOn(deps: Project.ClasspathDependency*): Project = copy(dependencies = dependencies ++ deps)
	def inherits(from: ProjectRef*): Project = copy(inherits = inherits ++ from)
	def aggregate(refs: ProjectRef*): Project = copy(aggregate = aggregate ++ refs)
	def configs(cs: Configuration*): Project = copy(configurations = configurations ++ cs)
	def settings(ss: Project.Setting[_]*): Project = copy(settings = settings ++ ss)
	
	def uses = aggregate ++ dependencies.map(_.project)
}
final case class Extracted(structure: Load.BuildStructure, session: SessionSettings, curi: URI, cid: String, rootProject: URI => String)

object Project extends Init[Scope]
{
	def defaultSettings: Seq[Setting[_]] = Nil

	final case class ClasspathDependency(project: ProjectRef, configuration: Option[String])
	final class Constructor(p: ProjectRef) {
		def %(conf: String): ClasspathDependency = new ClasspathDependency(p, Some(conf))
	}

	def getOrError[T](state: State, key: AttributeKey[T], msg: String): T = state get key getOrElse error(msg)
	def structure(state: State): Load.BuildStructure = getOrError(state, StructureKey, "No build loaded.")
	def session(state: State): SessionSettings = getOrError(state, SessionKey, "Session not initialized.")
	def extract(state: State): Extracted =
	{
		val se = session(state)
		val (curi, cid) = se.current
		val st = structure(state)
		Extracted(st, se, curi, cid, Load.getRootProject(st.units))
	}
	
	def current(state: State): (URI, String) = session(state).current
	def currentRef(state: State): ProjectRef =
	{
		val (unit, it) = current(state)
		ProjectRef(Some(unit), Some(it))
	}
	def updateCurrent(s: State): State =
	{
		val structure = Project.structure(s)
		val (uri, id) = Project.current(s)
		val ref = ProjectRef(uri, id)
		val project = Load.getProject(structure.units, uri, id)
		logger(s).info("Set current project to " + id + " (in build " + uri +")")

		val data = structure.data
		val historyPath = HistoryPath(ref).get(data).flatMap(identity)
		val newAttrs = s.attributes.put(Watch.key, makeWatched(data, ref, project)).put(HistoryPath.key, historyPath)
		s.copy(attributes = newAttrs)
	}

	def makeWatched(data: Settings[Scope], ref: ProjectRef, project: Project): Watched =
	{
		def getWatch(ref: ProjectRef) = Watch(ref).get(data)
		getWatch(ref) match
		{
			case Some(currentWatch) =>
				val subWatches = project.uses flatMap { p => getWatch(p) }
				Watched.multi(currentWatch, subWatches)
			case None => Watched.empty
		}
	}
	def display(scoped: ScopedKey[_]): String = Scope.display(scoped.scope, scoped.key.label)

	def mapScope(f: Scope => Scope) = new  (ScopedKey ~> ScopedKey) { def apply[T](key: ScopedKey[T]) =
		ScopedKey( f(key.scope), key.key)
	}
	def transform(g: Scope => Scope, ss: Seq[Setting[_]]): Seq[Setting[_]] = {
		val f = mapScope(g)
		ss.map(_ mapKey f mapReferenced f)
	}

	val SessionKey = AttributeKey[SessionSettings]("session-settings")
	val StructureKey = AttributeKey[Load.BuildStructure]("build-structure")
}

	import SessionSettings._

final case class SessionSettings(currentBuild: URI, currentProject: Map[URI, String], original: Seq[Setting[_]], prepend: SessionMap, append: SessionMap, currentEval: () => Eval)
{
	assert(currentProject contains currentBuild, "Current build (" + currentBuild + ") not associated with a current project.")
	def setCurrent(build: URI, project: String, eval: () => Eval): SessionSettings = copy(currentBuild = build, currentProject = currentProject.updated(build, project), currentEval = eval)
	def current: (URI, String) = (currentBuild, currentProject(currentBuild))
	def appendSettings(s: Seq[SessionSetting]): SessionSettings = copy(append = modify(append, _ ++ s))
	def prependSettings(s: Seq[SessionSetting]): SessionSettings = copy(prepend = modify(prepend, s ++ _))
	def mergeSettings: Seq[Setting[_]] = merge(prepend) ++ original ++ merge(append)

	private[this] def merge(map: SessionMap): Seq[Setting[_]] = map.values.toSeq.flatten[SessionSetting].map(_._1)
	private[this] def modify(map: SessionMap, onSeq: Endo[Seq[SessionSetting]]): SessionMap =
	{
		val cur = current
		map.updated(cur, onSeq(map.getOrElse( cur, Nil)))
	}
}
object SessionSettings
{
	type SessionSetting = (Setting[_], String)
	type SessionMap = Map[(URI, String), Seq[SessionSetting]]
}

trait ProjectConstructors
{
	implicit def configDependencyConstructor[T <% ProjectRef](p: T): Project.Constructor = new Project.Constructor(p)
	implicit def classpathDependency[T <% ProjectRef](p: T): Project.ClasspathDependency = new Project.ClasspathDependency(p, None)
}
// the URI must be resolved and normalized before it is definitive
final case class ProjectRef(uri: Option[URI], id: Option[String])
object ProjectRef
{
	def apply(base: URI, id: String): ProjectRef = ProjectRef(Some(base), Some(id))
	/** Reference to the project with 'id' in the current build unit.*/
{'fraction_non_alphanumeric': 0.1321564885496183, 'fraction_numerical': 0.0009541984732824427, 'mean_word_length': 5.637745408486384, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6049978', 'n_tokens_mistral': 3370, 'n_tokens_neox': 3229, 'n_words': 891}