Java tutorial
/* * Copyright (c) 2016, Stein Eldar Johnsen * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package net.morimekta.idltool; import com.google.common.collect.ImmutableSortedMap; import net.morimekta.idltool.config.IdlRC; import net.morimekta.idltool.config.Idl_Constants; import net.morimekta.idltool.meta.Meta; import net.morimekta.providence.serializer.JsonSerializer; import net.morimekta.util.io.IOUtils; import org.apache.commons.codec.digest.DigestUtils; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.lib.Config; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectLoader; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevTree; import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.treewalk.TreeWalk; import org.eclipse.jgit.treewalk.filter.PathFilter; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.UncheckedIOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.time.Clock; import java.time.Instant; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.Base64; import java.util.Map; import java.util.Properties; /** * General IDL tool utilities. */ public class IdlUtils { public static String versionString() { Properties properties = new Properties(); try (InputStream in = IdlUtils.class.getResourceAsStream("/build.properties")) { properties.load(in); return "v" + properties.getProperty("build.version"); } catch (IOException e) { throw new UncheckedIOException(e); } } private static File getCacheDirectory(File cacheDir, String repository) throws IOException { if (!cacheDir.exists()) { if (!cacheDir.mkdirs()) { throw new IOException( "Unable to create cache directory " + cacheDir.getCanonicalFile().getAbsolutePath()); } } String hash = Base64.getUrlEncoder() .encodeToString(DigestUtils.sha1(repository.getBytes(StandardCharsets.UTF_8))); return new File(cacheDir, hash).getCanonicalFile().getAbsoluteFile(); } public static Git getCacheRepository(File cacheDir, String repository) throws IOException, GitAPIException { File repoCache = getCacheDirectory(cacheDir, repository); Runtime runtime = Runtime.getRuntime(); if (!repoCache.exists()) { Process p = runtime .exec(new String[] { "git", "clone", repository, repoCache.getAbsoluteFile().toString() }); try { int response = p.waitFor(); if (response != 0) { throw new IOException(IOUtils.readString(p.getErrorStream())); } } catch (InterruptedException e) { throw new IOException(e.getMessage(), e); } } else { Process p = runtime.exec(new String[] { "git", "fetch", "origin", "-p" }, null, repoCache); try { int response = p.waitFor(); if (response != 0) { throw new IOException(IOUtils.readString(p.getErrorStream())); } } catch (InterruptedException e) { throw new IOException(e.getMessage(), e); } p = runtime.exec(new String[] { "git", "add", "-A" }, null, repoCache); try { int response = p.waitFor(); if (response != 0) { throw new IOException(IOUtils.readString(p.getErrorStream())); } } catch (InterruptedException e) { throw new IOException(e.getMessage(), e); } p = runtime.exec(new String[] { "git", "reset", "origin/master", "--hard" }, null, repoCache); try { int response = p.waitFor(); if (response != 0) { throw new IOException(IOUtils.readString(p.getErrorStream())); } } catch (InterruptedException e) { throw new IOException(e.getMessage(), e); } } return Git.open(repoCache); } public static IdlRC readRepoRc(File rc) throws IOException { try (FileInputStream in = new FileInputStream(rc)) { return new JsonSerializer().deserialize(in, IdlRC.kDescriptor); } } public static File findHomeDotCacheIdlTool(File cacheOverride) throws IOException { if (cacheOverride != null) { cacheOverride = cacheOverride.getCanonicalFile(); if (cacheOverride.exists() && cacheOverride.isDirectory()) { return cacheOverride; } throw new IOException("No such cache directory: " + cacheOverride.toString()); } File home = new File(System.getenv("HOME")).getAbsoluteFile().getCanonicalFile(); cacheOverride = new File(new File(home, ".cache"), "idltool"); if (!cacheOverride.exists()) { if (!cacheOverride.mkdirs()) { throw new IOException("Unable to create RC directory: " + cacheOverride.toString()); } } if (!cacheOverride.isDirectory()) { throw new IOException("RC location is not a directory: " + cacheOverride.toString()); } return cacheOverride; } public static File findRepoRc(File workingDir, boolean recursive) throws IOException { if (workingDir == null) { throw new IllegalArgumentException("No working directory"); } if (!workingDir.exists()) { throw new IOException("No such directory: " + workingDir.toString()); } if (!workingDir.isDirectory()) { throw new IOException("No RC location not a directory: " + workingDir.toString()); } File pwd = workingDir; File rc = new File(pwd, ".idlrc"); if (recursive) { while (!rc.exists()) { pwd = pwd.getParentFile(); if (pwd == null) { throw new IOException("No .idlrc file at: " + workingDir.getAbsolutePath() + " (recursive)"); } rc = new File(pwd, ".idlrc"); } } if (!rc.exists()) { throw new IOException("No .idlrc file at: " + workingDir.getAbsolutePath()); } if (!rc.isFile()) { throw new IOException("Found .idlrc is not a file: " + pwd.getAbsolutePath()); } return rc; } public static String getLocalRemoteName(Repository repository, String remoteName) throws IOException { Config config = repository.getConfig(); String currentBranch = repository.getBranch(); if (currentBranch == null) { throw new RuntimeException("No current branch!"); } if (remoteName == null) { String branch = config.getString("default", null, "branch"); if (branch == null) { branch = "master"; } remoteName = config.getString("branch", branch, "remote"); if (remoteName == null) { remoteName = config.getString("branch", "master", "remote"); if (remoteName == null) { remoteName = "origin"; } } } String remoteUrl = config.getString("remote", remoteName, "url"); if (remoteUrl == null) { throw new RuntimeException("No URL for remote " + remoteName); } return remoteUrl.replaceAll("^.*://", "").replaceAll("^.*@", "").replaceAll("[.]git$", "").replaceAll(":", "/"); } public static Meta getMetaInRegistry(Repository repo) throws IOException, GitAPIException { // use tree and meta.json file to show available services. ObjectId lastCommitId = repo.resolve(Constants.HEAD); // now we have to get the commit RevWalk revWalk = new RevWalk(repo); RevCommit commit = revWalk.parseCommit(lastCommitId); // and using commit's tree find the path RevTree tree = commit.getTree(); TreeWalk treeWalk = new TreeWalk(repo); treeWalk.addTree(tree); treeWalk.setRecursive(true); treeWalk.setFilter(PathFilter.create(Idl_Constants.META_JSON)); if (!treeWalk.next()) { throw new RuntimeException("No registry meta file found, should be at " + new File(repo.getDirectory(), Idl_Constants.META_JSON).getCanonicalFile().getAbsolutePath()); } ObjectId objectId = treeWalk.getObjectId(0); ObjectLoader loader = repo.open(objectId); // and then one can use either InputStream in = loader.openStream(); return new JsonSerializer().deserialize(in, Meta.kDescriptor); } public static String formatAgo(long timestamp) { Instant instant = Instant.ofEpochSecond(timestamp / 1000); LocalDateTime local = instant.atZone(Clock.systemUTC().getZone()) .withZoneSameInstant(Clock.systemDefaultZone().getZone()).toLocalDateTime(); return DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(local).replaceAll("[T]", " "); } public static Map<String, String> buildSha1Sums(Path dir) throws IOException { ImmutableSortedMap.Builder<String, String> sha1sums = ImmutableSortedMap.naturalOrder(); // TODO: Support nested directories. Files.list(dir).forEach(file -> { try { if (Files.isRegularFile(file)) { String sha = DigestUtils.sha1Hex(Files.readAllBytes(file)); sha1sums.put(file.getFileName().toString(), sha); } } catch (IOException e) { throw new UncheckedIOException(e.getMessage(), e); } }); return sha1sums.build(); } }