Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set up versioning from git tags using mill #225

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ examplesold/
src/test/scala/dump/
src/test/analysis/dump/
*.gtirb
*.json
*.json
src/main/scala/Version.scala
1 change: 1 addition & 0 deletions VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.1.2-alpha
83 changes: 71 additions & 12 deletions build.sc
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ import os.Path
import $ivy.`com.lihaoyi::mill-contrib-scalapblib:$MILL_VERSION`
import contrib.scalapblib._



object basil extends RootModule with ScalaModule with antlr.AntlrModule with ScalaPBModule{
object basil extends RootModule with ScalaModule with antlr.AntlrModule with ScalaPBModule {
def scalaVersion = "3.3.1"

val javaTests = ivy"com.novocode:junit-interface:0.11"
Expand All @@ -18,34 +16,95 @@ object basil extends RootModule with ScalaModule with antlr.AntlrModule with Sca
val sourceCode = ivy"com.lihaoyi::sourcecode:0.3.0"
val mainArgs = ivy"com.lihaoyi::mainargs:0.5.1"
val sprayJson = ivy"io.spray::spray-json:1.3.6"
val scalapb = ivy"com.thesamet.scalapb::scalapb-runtime:0.11.15"
val scalapb = ivy"com.thesamet.scalapb::scalapb-runtime:0.11.15"

def scalaPBVersion = "0.11.15"


def mainClass = Some("Main")

override def scalaPBSources = T.sources {Seq(PathRef(this.millSourcePath / "main" / "protobuf"))}
override def scalaPBSources = T.sources { Seq(PathRef(this.millSourcePath / "main" / "protobuf")) }
def millSourcePath = super.millSourcePath / "src"
def ivyDeps = Agg(scalactic, antlrRuntime, sourceCode, mainArgs, sprayJson, scalapb)
def sources = T.sources {Seq(PathRef(this.millSourcePath / "main" / "scala" ))}

def getTryUpdateVersion() = {

/** Checks for presence of git binary and repository and then tries to update version files.
*/

print("Checking for git version tag ... ")
val error =
try {
val r = os.proc("git", "status").spawn()
r.join(1000)
if (r.exitCode() != 0) {
Some("git repo not found.")
} else {
None
}
} catch {
case _: Throwable => Some("git binary not found.")
}

error match {
case None => updateVersion()
case Some(msg) => {
val declaredVersion = os.read(os.pwd / "VERSION")
writeVersionFiles(declaredVersion, declaredVersion)
println(msg + " using " + declaredVersion + ".")
}
}

}

/** declaredVersion: git tagged version in semver buildVersion: current build, as checked out in git, either
* declaredVersion or declaredVersion+shortSHA
*/
def writeVersionFiles(declaredVersion: String, buildVersion: String) = {
val versionDecl = s"val BASILVersion = \"$declaredVersion\""
val buildVersionDecl = "val BASILBuildVersion = \"" + buildVersion + "\""
val wd = os.pwd
os.write.over(wd / "VERSION", declaredVersion)
os.write.over(wd / "src" / "main" / "scala" / "Version.scala", versionDecl + "\n" + buildVersionDecl)
}

def sources = T.sources {
getTryUpdateVersion()
Seq(PathRef(this.millSourcePath / "main" / "scala"))
}

override def antlrPackage: Option[String] = Some("Parsers")
override def antlrGenerateVisitor = true
override def antlrGrammarSources = T.sources {
Seq(PathRef(millSourcePath / "main" / "antlr4"))
}

object test extends ScalaTests with TestModule.ScalaTest {
object test extends ScalaTests with TestModule.ScalaTest {
def ivyDeps = Agg(scalaTests, javaTests)
def sources = T.sources {Seq(PathRef(this.millSourcePath / "scala" ))}
def sources = T.sources { Seq(PathRef(this.millSourcePath / "scala")) }
}

/** Updates VERSION and Version.Scala files using the most recent git tagged version. Assumes `git` binary is
* available in PATH
*/
def updateVersion() = T.command {
val lastTaggedCommit = os.proc("git", "rev-list", "--tags", "--max-count=1").spawn().stdout.trim()
val version = os.proc("git", "describe", "--tags", lastTaggedCommit).spawn().stdout.trim()
val buildVersion = os.proc("git", "describe", "--tags").spawn().stdout.trim()

val wd = os.pwd
val declaredVersion = os.read(wd / "VERSION")

if (declaredVersion != version) {
println(s"WARN: Updating VERSION file $declaredVersion to $version")
} else {
println("No new version")
}

writeVersionFiles(version, buildVersion)
}

/**
* Updates the expected
*/
/** Updates the expected
*/

def updateExpectedBAP() = T.command {
val correctPath = test.millSourcePath / "correct"
Expand Down
43 changes: 35 additions & 8 deletions src/main/scala/Main.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,17 @@ import mainargs.{main, arg, ParserForClass, Flag}

object Main {

@main(name = "BASIL")
@main(name = "BASIL", doc=s"BASIL version ${BASILBuildVersion}")
case class Checks(
@arg(name = "version", doc = "Print the version string and exit.")
version: Flag,
@arg(name = "help", short = 'h', doc = "Show this help message.")
help: Flag,
)
@main(name = "BASIL", doc=s"BASIL version ${BASILBuildVersion}")
case class Config(
@arg(name = "input", short = 'i', doc = "BAP .adt file or GTIRB/ASLi .gts file")
inputFileName: String,
inputFileName: String,
@arg(name = "relf", short = 'r', doc = "Name of the file containing the output of 'readelf -s -r -W'.")
relfFileName: String,
@arg(name = "spec", short = 's', doc = "BASIL specification file.")
Expand All @@ -40,31 +47,51 @@ object Main {
mainProcedureName: String = "main",
@arg(name = "procedure-call-depth", doc = "Cull procedures beyond this call depth from the main function (defaults to Int.MaxValue)")
procedureDepth: Int = Int.MaxValue,
@arg(name = "help", short = 'h', doc = "Show this help message.")
help: Flag,
@arg(name = "analysis-results", doc = "Log analysis results in files at specified path.")
analysisResults: Option[String],
@arg(name = "analysis-results-dot", doc = "Log analysis results in .dot form at specified path.")
analysisResultsDot: Option[String],
@arg(name = "threads", short = 't', doc = "Separates threads into multiple .bpl files with given output filename as prefix (requires --analyse flag)")
threadSplit: Flag
threadSplit: Flag,
// below exist just for help text, they are handled in the first pass
@arg(name = "version", doc = "Print the version string and exit.")
version: Flag,
@arg(name = "help", short = 'h', doc = "Show this help message.")
help: Flag,
)

def main(args: Array[String]): Unit = {
val parser = ParserForClass[Config]
val parsed = parser.constructEither(args.toSeq)
val parseOpt = ParserForClass[Checks]
val optParsed = parseOpt.constructEither(args.toSeq, autoPrintHelpAndExit = None)

val conf = parsed match {
val check = optParsed match {
case Right(r) => r
case Left(l) =>
println(l)
return
}

if (conf.help.value) {
if (check.help.value) {
println(parser.helpText(sorted = false))
return
}

if (check.version.value) {
println(BASILBuildVersion)
return
}

val parsed = parser.constructEither(args.toSeq, sorted=false)

val conf = parsed match {
case Right(r) => r
case Left(l) =>
println(l)
return
}


Logger.setLevel(LogLevel.INFO)
if (conf.verbose.value) {
Logger.setLevel(LogLevel.DEBUG)
Expand Down