Mercurial > cgi-bin > hgweb.cgi > Osdep
view src/name/blackcap/osdep/Osdep.kt @ 2:2abd1acde716
Fix KOTLIN_HOME paths.
author | davidb |
---|---|
date | Tue, 14 Apr 2020 11:48:32 -0700 |
parents | 5ea54efa8e45 |
children |
line wrap: on
line source
/* * Recursively examines the specified directories for files that end in * .<type>.osdep, where <type> is one of unix, mac, windows, or default. * The file that matches the current OS type (or the type specified with * the -t option) */ package name.blackcap.osdep import java.io.File import java.io.FileInputStream import java.io.FileOutputStream import java.io.IOException import kotlin.collections.HashMap import kotlin.collections.HashSet import org.apache.commons.cli.CommandLine import org.apache.commons.cli.DefaultParser import org.apache.commons.cli.HelpFormatter import org.apache.commons.cli.Option import org.apache.commons.cli.Options import org.apache.commons.cli.ParseException var ostype = run { val rawType = System.getProperty("os.name")?.toLowerCase() if (rawType == null) { "default" } else if (rawType.contains("win")) { "windows" } else if (rawType.contains("mac")) { "mac" } else if (rawType.contains("nix") || rawType.contains("nux") || rawType.contains("aix") || rawType.contains("sunos")) { "unix" } else { "default" } } val MYNAME = "osdep" val MYEXT = ".osdep" val files = HashMap<String, HashSet<String>>() var errors = 0 fun main(args: Array<String>) { val options = Options().apply { addOption("?", "help", false, "Print this help message.") addOption("c", "clean", false, "Clean instead of copying.") addOption("t", "type", true, "Specify OS type (default ${ostype}).") } val cmdLine: CommandLine? = try { DefaultParser().parse(options, args) } catch (e: ParseException) { System.err.format("%s: %s%n", MYNAME, e.message) System.exit(2) null } if (cmdLine!!.hasOption("help")) { val usage = MYNAME + " [--help] [--clean] [--type=type] directory [...]" HelpFormatter().printHelp(usage, options, false); System.exit(0); } val clOstype = cmdLine.getOptionValue("type") if (clOstype != null) { ostype = clOstype } for (arg in cmdLine.args) { try { File(arg).walk().forEach { build(it) } } catch (e: Exception) { handle(e, "cannot walk '${arg}'") } } val process = if (cmdLine.hasOption("clean")) ::clean else ::copy files.forEach { process(it.key, it.value) } System.exit(if (errors == 0) 0 else 1) } fun build(file: File) { if (!file.isFile()) { return } val path = file.toString() if (!path.endsWith(MYEXT)) { return } val dot2 = path.lastIndexOf('.') if (dot2 <= 0) { return } val dot1 = path.lastIndexOf('.', dot2 - 1) if (dot1 <= 0) { return } val base = path.substring(0 .. (dot1 - 1)) val type = path.substring((dot1 + 1) .. (dot2 - 1)) val fset = files[base] if (fset != null) { fset.add(type) } else { files[base] = HashSet<String>().apply { add(type) } } } fun copy(base: String, types: HashSet<String>) { val type = if (ostype in types) ostype else "default" if (type !in types) { System.err.format("%s: type '%s' missing for '%s'%n", MYNAME, type, base) errors += 1 return } copf("${base}.${type}${MYEXT}", base) } fun copf(source: String, target: String) { val sf = File(source) val tf = File(target) try { FileInputStream(sf).use { sfp -> FileOutputStream(tf).use { tfp -> sfp.copyTo(tfp) } } } catch (e: Exception) { handle(e, "cannot copy '${source}' to '${target}'") return } try { tf.setLastModified(sf.lastModified()) } catch (e: Exception) { handle(e, "cannot set time of '${target}'") } } fun clean(base: String, @Suppress("UNUSED_PARAMETER") ignored: HashSet<String>) { val file = File(base) if (file.exists()) { try { if (!file.delete()) { System.err.format("%s: '%s' not deleted%n", MYNAME, base) errors += 1 } } catch (e: Exception) { handle(e, "cannot delete '${base}'") } } } fun handle(exception: Exception, message: String) { val fallback = when (exception) { is SecurityException -> "security violation" is IOException -> "I/O error" else -> throw exception } System.err.format("%s: %s%n", MYNAME, exception.message ?: fallback) System.err.format("%s: %s%n", MYNAME, message) errors += 1 }