diff options
-rw-r--r-- | examples/multi-combined-example/build/build/build.scala | 4 | ||||
-rw-r--r-- | stage2/BasicBuild.scala | 2 | ||||
-rw-r--r-- | stage2/BuildBuild.scala | 8 | ||||
-rw-r--r-- | stage2/BuildDependency.scala | 40 | ||||
-rw-r--r-- | stage2/GitDependency.scala | 122 |
5 files changed, 82 insertions, 94 deletions
diff --git a/examples/multi-combined-example/build/build/build.scala b/examples/multi-combined-example/build/build/build.scala index b87351d..a5b0201 100644 --- a/examples/multi-combined-example/build/build/build.scala +++ b/examples/multi-combined-example/build/build/build.scala @@ -1,8 +1,8 @@ package cbt_build.cbt_examples.multi_combined_example.build import cbt._ class Build(val context: Context) extends BuildBuild{ - //println(DirectoryDependency( projectDirectory / ".." / "sub4" / "build" ).dependency.exportedClasspath) + //println(DirectoryDependency( projectDirectory / ".." / "sub4" / "build" ).exportedClasspath) override def dependencies: Seq[cbt.Dependency] = - super.dependencies :+ DirectoryDependency( projectDirectory / ".." / "sub4" / "build" ).dependency + super.dependencies :+ DirectoryDependency( projectDirectory / ".." / "sub4" / "build" ) def foo = DirectoryDependency( projectDirectory / ".." / "sub4" / "build" ) } diff --git a/stage2/BasicBuild.scala b/stage2/BasicBuild.scala index 0d8017f..68bda15 100644 --- a/stage2/BasicBuild.scala +++ b/stage2/BasicBuild.scala @@ -212,7 +212,7 @@ trait BaseBuild extends BuildInterface with DependencyImplementation with Trigge val testDirectory = projectDirectory / "test" if( (testDirectory / lib.buildDirectoryName / lib.buildFileName).exists ){ // FIYME: maybe we can make loadRoot(...).finalBuild an Option some - DirectoryDependency( testDirectory ).dependency + DirectoryDependency( testDirectory ) } else { new BasicBuild( context.copy(workingDirectory = testDirectory) ){ override def dependencies = Seq( diff --git a/stage2/BuildBuild.scala b/stage2/BuildBuild.scala index d778049..dead081 100644 --- a/stage2/BuildBuild.scala +++ b/stage2/BuildBuild.scala @@ -14,7 +14,7 @@ class plugins(implicit context: Context){ context.copy( workingDirectory = context.cbtHome / "plugins" / dir ) - ).dependency + ) final lazy val essentials = plugin( "essentials" ) final lazy val proguard = plugin( "proguard" ) final lazy val sbtLayout = plugin( "sbt_layout" ) @@ -66,9 +66,9 @@ trait BuildBuildWithoutEssentials extends BaseBuild{ // otherwise we'd have to recursively build all versions since // the beginning. Instead CBT always needs to build the pure Java // Launcher in the checkout with itself and then run it via reflection. - val dep = new GitDependency(base, hash, Some("nailgun_launcher")) - val ctx = managedContext.copy( cbtHome = dep.checkout ) - dep.classLoader + val build = GitDependency(base, hash, Some("nailgun_launcher")).asInstanceOf[BaseBuild] + val ctx = managedContext.copy( cbtHome = build.projectDirectory.getParentFile ) + build.classLoader .loadClass( "cbt.NailgunLauncher" ) .getMethod( "getBuild", classOf[AnyRef] ) .invoke( null, ctx ) diff --git a/stage2/BuildDependency.scala b/stage2/BuildDependency.scala index 9a2918a..d7520d8 100644 --- a/stage2/BuildDependency.scala +++ b/stage2/BuildDependency.scala @@ -15,43 +15,39 @@ trait TriggerLoop extends DependencyImplementation{ def triggerLoopFiles: Seq[File] } /** You likely want to use the factory method in the BasicBuild class instead of this. */ -final case class DirectoryDependency(context: Context, pathToNestedBuild: String*) extends TriggerLoop{ - def classLoaderCache = context.classLoaderCache - override def toString = show - override def show = this.getClass.getSimpleName ++ "(" ++ context.workingDirectory.string ++ ")" - def moduleKey = this.getClass.getName ++ "("+context.workingDirectory.string+")" - lazy val logger = context.logger - override lazy val lib: Lib = new Lib(logger) - def transientCache = context.transientCache - private lazy val root = lib.loadRoot( context ) - lazy val dependency: Dependency = { +object DirectoryDependency{ + def apply(context: Context, pathToNestedBuild: String*): BuildInterface = { + val lib: Lib = new Lib(context.logger) + // TODO: move this into finalBuild probably - def selectNestedBuild( build: Dependency, names: Seq[String], previous: Seq[String] ): Dependency = { + // TODO: unify this with lib.callReflective + def selectNestedBuild( build: BuildInterface, names: Seq[String], previous: Seq[String] ): BuildInterface = { names.headOption.map{ name => if( lib.taskNames(build.getClass).contains(name) ){ val method = build.getClass.getMethod(name) val returnType = method.getReturnType - if( classOf[Dependency] isAssignableFrom returnType ){ + if( classOf[BuildInterface] isAssignableFrom returnType ){ selectNestedBuild( - method.invoke(build).asInstanceOf[Dependency], + method.invoke(build).asInstanceOf[BuildInterface], names.tail, previous :+ name ) } else { - throw new RuntimeException( s"Expected subtype of Dependency, found $returnType for " + previous.mkString(".") + " in " + show ) + throw new RuntimeException( + s"Expected subtype of BuildInterface, found $returnType for " + previous.mkString(".") + " in " + build + ) } } else { - throw new RuntimeException( (previous :+ name).mkString(".") + " not found in " + show ) + throw new RuntimeException( (previous :+ name).mkString(".") + " not found in " + build ) } }.getOrElse( build ) } - selectNestedBuild( root.finalBuild(context.workingDirectory), pathToNestedBuild, Nil ) + selectNestedBuild( + lib.loadRoot( context ).finalBuild(context.workingDirectory), + pathToNestedBuild, + Nil + ) } - def exportedClasspath = ClassPath() - def dependencies = Seq(dependency) - def triggerLoopFiles = root.triggerLoopFiles - def lastModified = dependency.lastModified - def targetClasspath = ClassPath() } /* case class DependencyOr(first: DirectoryDependency, second: JavaDependency) extends ProjectProxy with DirectoryDependencyBase{ @@ -59,4 +55,4 @@ case class DependencyOr(first: DirectoryDependency, second: JavaDependency) exte def triggerLoopFiles = if(isFirst) first.triggerLoopFiles else Seq() protected val delegate = if(isFirst) first else second } -*/
\ No newline at end of file +*/ diff --git a/stage2/GitDependency.scala b/stage2/GitDependency.scala index f2ac7a6..028401b 100644 --- a/stage2/GitDependency.scala +++ b/stage2/GitDependency.scala @@ -9,70 +9,68 @@ import org.eclipse.jgit.lib.Ref object GitDependency{ val GitUrl = "(git:|https:|file:/)//([^/]+)/(.+)".r -} -case class GitDependency( - url: String, ref: String, subDirectory: Option[String] = None, // example: git://github.com/cvogt/cbt.git#<some-hash> - pathToNestedBuild: Seq[String] = Seq() -)(implicit val logger: Logger, classLoaderCache: ClassLoaderCache, context: Context ) extends DependencyImplementation{ - import GitDependency._ - override def lib = new Lib(logger) - def classLoaderCache = context.classLoaderCache - def moduleKey = ( - this.getClass.getName - ++ "(" ++ url ++ subDirectory.map("/" ++ _).getOrElse("") ++ "#" ++ ref - ++ ", " - ++ pathToNestedBuild.mkString(", ") - ++ ")" - ) - def transientCache = context.transientCache - // TODO: add support for authentication via ssh and/or https - // See http://www.codeaffine.com/2014/12/09/jgit-authentication/ - private val GitUrl( _, domain, path ) = url + def apply( + url: String, ref: String, subDirectory: Option[String] = None, // example: git://github.com/cvogt/cbt.git#<some-hash> + pathToNestedBuild: Seq[String] = Seq() + )(implicit context: Context ): BuildInterface = { + // TODO: add support for authentication via ssh and/or https + // See http://www.codeaffine.com/2014/12/09/jgit-authentication/ + val GitUrl( _, domain, path ) = url + val credentialsFile = context.workingDirectory ++ "/git.login" + def authenticate(_git: CloneCommand) = + if(!credentialsFile.exists){ + _git + } else { + val (user, password) = { + // TODO: implement safer method than reading credentials from plain text file + val c = new String(readAllBytes(credentialsFile.toPath)).split("\n").head.trim.split(":") + (c(0), c.drop(1).mkString(":")) + } + _git.setCredentialsProvider( new UsernamePasswordCredentialsProvider(user, password) ) + } - private val credentialsFile = context.workingDirectory ++ "/git.login" + val logger = context.logger - private def authenticate(_git: CloneCommand) = - if(!credentialsFile.exists){ - _git - } else { - val (user, password) = { - // TODO: implement safer method than reading credentials from plain text file - val c = new String(readAllBytes(credentialsFile.toPath)).split("\n").head.trim.split(":") - (c(0), c.drop(1).mkString(":")) - } - _git.setCredentialsProvider( new UsernamePasswordCredentialsProvider(user, password) ) - } + def moduleKey = ( + this.getClass.getName + ++ "(" ++ url ++ subDirectory.map("/" ++ _).getOrElse("") ++ "#" ++ ref + ++ ", " + ++ pathToNestedBuild.mkString(", ") + ++ ")" + ) - def checkout: File = taskCache[GitDependency]("checkout").memoize{ - val checkoutDirectory = context.cache ++ s"/git/$domain/$path/$ref" - val _git = if(checkoutDirectory.exists){ - logger.git(s"Found existing checkout of $url#$ref in $checkoutDirectory") - val _git = new Git(new FileRepository(checkoutDirectory ++ "/.git")) - val actualRef = _git.getRepository.getBranch - if(actualRef != ref){ - logger.git(s"actual ref '$actualRef' does not match expected ref '$ref' - fetching and checking out") - _git.fetch().call() - _git.checkout().setName(ref).call - } - _git - } else { - logger.git(s"Cloning $url into $checkoutDirectory") - val _git = authenticate( - Git - .cloneRepository() - .setURI(url) - .setDirectory(checkoutDirectory) - ).call() + val taskCache = new PerClassCache(context.transientCache, moduleKey)(logger) - logger.git(s"Checking out ref $ref") - _git.checkout().setName(ref).call() - _git + def checkout: File = taskCache[Dependency]("checkout").memoize{ + val checkoutDirectory = context.cache ++ s"/git/$domain/$path/$ref" + val _git = if(checkoutDirectory.exists){ + logger.git(s"Found existing checkout of $url#$ref in $checkoutDirectory") + val _git = new Git(new FileRepository(checkoutDirectory ++ "/.git")) + val actualRef = _git.getRepository.getBranch + if(actualRef != ref){ + logger.git(s"actual ref '$actualRef' does not match expected ref '$ref' - fetching and checking out") + _git.fetch().call() + _git.checkout().setName(ref).call + } + _git + } else { + logger.git(s"Cloning $url into $checkoutDirectory") + val _git = authenticate( + Git + .cloneRepository() + .setURI(url) + .setDirectory(checkoutDirectory) + ).call() + + logger.git(s"Checking out ref $ref") + _git.checkout().setName(ref).call() + _git + } + val actualRef = _git.getRepository.getBranch + assert( actualRef == ref, s"actual ref '$actualRef' does not match expected ref '$ref'") + checkoutDirectory } - val actualRef = _git.getRepository.getBranch - assert( actualRef == ref, s"actual ref '$actualRef' does not match expected ref '$ref'") - checkoutDirectory - } - def dependency = taskCache[GitDependency]("dependency").memoize{ + DirectoryDependency( context.copy( workingDirectory = checkout ++ subDirectory.map("/" ++ _).getOrElse("") @@ -80,10 +78,4 @@ case class GitDependency( pathToNestedBuild: _* ) } - - def dependencies = Seq(dependency) - - def exportedClasspath = ClassPath() - private[cbt] def targetClasspath = exportedClasspath - def lastModified: Long = dependency.lastModified } |