diff --git a/tools/admin/afp_component_hugo.scala b/tools/admin/afp_component_hugo.scala --- a/tools/admin/afp_component_hugo.scala +++ b/tools/admin/afp_component_hugo.scala @@ -1,118 +1,125 @@ +/* Author: Fabian Huch, TU Muenchen + +Build Isabelle component for hugo site generator. See also: + + - https://gohugo.io + - https://github.com/gohugoio/hugo + */ + package afp import isabelle._ object AFP_Component_Hugo { - val default_mirror = "https://github.com/gohugoio/hugo/releases/download/v0.88.1" - - def make_component_name(version: String): String = "hugo-" + version + /* platform information */ - def make_archive_name(release: String, platform: Platform.Family): String = { - val arch = platform match { - case isabelle.Platform.Family.linux => "Linux-64bit" - case isabelle.Platform.Family.macos => "macOS-64bit" - case _ => error("Unsupported platform: " + platform) - } - "hugo_extended_" + release + "_" + arch + ".tar.gz" + sealed case class Download_Platform(platform_name: String, url_template: String) { + override def toString: String = platform_name + + def is_windows: Boolean = url_template.contains("windows") + def url(base_url: String, version: String): String = + base_url + "/v" + version + "/" + url_template.replace("{V}", version) } - def build_hugo( - progress: Progress = new Progress, - mirror: String = default_mirror, - target_dir: Path = Path.current - ): Unit = { - Isabelle_System.with_tmp_dir("hugo") { tmp_dir => - /* component */ - - val Version = """^.*?v([^/]+)$""".r - val version = - mirror match { - case Version(version) => version - case _ => error("Failed to determine component version from " + quote(mirror)) - } - - val component = make_component_name(version) - val component_dir = Isabelle_System.new_directory(target_dir.absolute + Path.basic(component)) - progress.echo("Component " + component_dir) + val platforms: List[Download_Platform] = + List( + Download_Platform("arm64-darwin", "hugo_extended_{V}_darwin-universal.tar.gz"), + Download_Platform("arm64-linux", "hugo_extended_{V}_linux-arm64.tar.gz"), + Download_Platform("x86_64-darwin", "hugo_extended_{V}_darwin-universal.tar.gz"), + Download_Platform("x86_64-linux", "hugo_extended_{V}_linux-amd64.tar.gz"), + Download_Platform("x86_64-windows", "hugo_extended_{V}_windows-amd64.zip")) - /* platform */ - - val platform_name = - proper_string(Isabelle_System.getenv("ISABELLE_PLATFORM64")) getOrElse - error("No 64bit platform") + /* build hugo */ - val platform_dir = Isabelle_System.make_directory(component_dir + Path.basic(platform_name)) - + val default_url = "https://github.com/gohugoio/hugo/releases/download" + val default_version = "0.119.0" - /* archive */ + def build_hugo( + base_url: String = default_url, + version: String = default_version, + target_dir: Path = Path.current, + progress: Progress = new Progress + ): Unit = { + /* component */ - val platform = Platform.Family.values.find(Platform.Family.standard(_) == platform_name).get - - val archive_name = make_archive_name(version, platform) + val component = "hugo-" + version + val component_dir = + Components.Directory(target_dir + Path.basic(component)).create(progress = progress) - /* download */ + /* download */ - val archive_path = tmp_dir + Path.basic(archive_name) - val download_url = mirror + "/" + archive_name - Isabelle_System.download_file(download_url, archive_path, progress = progress) + for (platform <- platforms) { + val platform_dir = + Isabelle_System.make_directory(component_dir.path + Path.basic(platform.platform_name)) - Isabelle_System.bash("tar xzf " + File.bash_path(archive_path), cwd = tmp_dir.file).check + val url = platform.url(base_url, version) + val name = Library.take_suffix(_ != '/', url.toList)._2.mkString + + val exe = Path.basic("hugo").exe_if(platform.is_windows) + + Isabelle_System.with_tmp_dir("download", component_dir.path.file) { download_dir => + Isabelle_System.with_tmp_dir("tmp", component_dir.path.file) { tmp_dir => + val archive_file = download_dir + Path.basic(name) + + Isabelle_System.download_file(url, archive_file, progress = progress) + Isabelle_System.extract(archive_file, tmp_dir) + Isabelle_System.move_file(tmp_dir + exe, platform_dir) + Isabelle_System.move_file(tmp_dir + Path.basic("LICENSE"), component_dir.LICENSE) + File.set_executable(platform_dir + exe) + } + } + } - /* install */ - - Isabelle_System.copy_file(tmp_dir + Path.explode("hugo"), platform_dir) - Isabelle_System.copy_file(tmp_dir + Path.explode("LICENSE"), component_dir) - + /* settings */ - /* settings */ - - val etc_dir = Isabelle_System.make_directory(component_dir + Path.basic("etc")) - File.write(etc_dir + Path.basic("settings"), - """# -*- shell-script -*- :mode=shellscript: - -ISABELLE_HUGO="$COMPONENT/$ISABELLE_PLATFORM64" + component_dir.write_settings(""" +ISABELLE_HUGO="$COMPONENT/${ISABELLE_WINDOWS_PLATFORM64:-${ISABELLE_APPLE_PLATFORM64:-$ISABELLE_PLATFORM64}}" """) - /* README */ + /* README */ - File.write(component_dir + Path.basic("README"), - "This Isabelle components provides a hugo extended " + version + - """ component from """ + mirror + """ + File.write(component_dir.README, + """This Isabelle components provides a hugo extended """ + version + """. + +See also https://gohugo.io and executables from """ + base_url + """ Fabian """ + Date.Format.date(Date.now()) + "\n") - } } - val isabelle_tool = Isabelle_Tool("afp_component_hugo", "build afp hugo component", - Scala_Project.here, - { args => - var target_dir = Path.current - var mirror = default_mirror + val isabelle_tool = + Isabelle_Tool("afp_component_hugo", "build afp hugo component", Scala_Project.here, + { args => + var target_dir = Path.current + var base_url = default_url + var version = default_version - val getopts = Getopts(""" + val getopts = Getopts(""" Usage: isabelle afp_component_hugo [OPTIONS] Options are: -D DIR target directory (default ".") - -U URL release mirror - (default """ + mirror + """) + -U URL download URL (default: """" + default_url + """") + -V VERSION version (default: """" + default_version + """") Build extended hugo component. -""", - "D:" -> (arg => target_dir = Path.explode(arg)), - "U:" -> (arg => mirror = arg)) + """, + "D:" -> (arg => target_dir = Path.explode(arg)), + "U:" -> (arg => base_url = arg), + "V:" -> (arg => version = arg)) - getopts(args) + val more_args = getopts(args) + if (more_args.nonEmpty) getopts.usage() - val progress = new Console_Progress() + val progress = new Console_Progress() - build_hugo(progress = progress, mirror = mirror, target_dir = target_dir) - }) + build_hugo(base_url = base_url, version = version, target_dir = target_dir, + progress = progress) + }) } \ No newline at end of file