Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame^] | 1 | package aQute.bnd.maven; |
| 2 | |
| 3 | import java.io.*; |
| 4 | import java.util.*; |
| 5 | import java.util.jar.*; |
| 6 | |
| 7 | import aQute.bnd.build.*; |
| 8 | import aQute.bnd.service.*; |
| 9 | import aQute.lib.osgi.*; |
| 10 | import aQute.libg.command.*; |
| 11 | import aQute.libg.header.*; |
| 12 | import aQute.libg.reporter.*; |
| 13 | |
| 14 | public class MavenDeploy implements Deploy, Plugin { |
| 15 | |
| 16 | String repository; |
| 17 | String url; |
| 18 | String homedir; |
| 19 | String keyname; |
| 20 | |
| 21 | String passphrase; |
| 22 | Reporter reporter; |
| 23 | |
| 24 | public void setProperties(Map<String, String> map) { |
| 25 | repository = map.get("repository"); |
| 26 | url = map.get("url"); |
| 27 | passphrase = map.get("passphrase"); |
| 28 | homedir = map.get("homedir"); |
| 29 | keyname = map.get("keyname"); |
| 30 | |
| 31 | if (url == null) |
| 32 | throw new IllegalArgumentException("MavenDeploy plugin must get a repository URL"); |
| 33 | if (repository == null) |
| 34 | throw new IllegalArgumentException("MavenDeploy plugin must get a repository name"); |
| 35 | } |
| 36 | |
| 37 | public void setReporter(Reporter processor) { |
| 38 | this.reporter = processor; |
| 39 | } |
| 40 | |
| 41 | /** |
| 42 | */ |
| 43 | public boolean deploy(Project project, Jar original) throws Exception { |
| 44 | Parameters deploy = project.parseHeader(project |
| 45 | .getProperty(Constants.DEPLOY)); |
| 46 | |
| 47 | Map<String, String> maven = deploy.get(repository); |
| 48 | if (maven == null) |
| 49 | return false; // we're not playing for this bundle |
| 50 | |
| 51 | project.progress("deploying %s to Maven repo: %s", original, repository); |
| 52 | File target = project.getTarget(); |
| 53 | File tmp = Processor.getFile(target, repository); |
| 54 | tmp.mkdirs(); |
| 55 | |
| 56 | Manifest manifest = original.getManifest(); |
| 57 | if (manifest == null) |
| 58 | project.error("Jar has no manifest: %s", original); |
| 59 | else { |
| 60 | project.progress("Writing pom.xml"); |
| 61 | PomResource pom = new PomResource(manifest); |
| 62 | pom.setProperties(maven); |
| 63 | File pomFile = write(tmp, pom, "pom.xml"); |
| 64 | |
| 65 | Jar main = new Jar("main"); |
| 66 | Jar src = new Jar("src"); |
| 67 | try { |
| 68 | split(original, main, src); |
| 69 | Parameters exports = project.parseHeader(manifest |
| 70 | .getMainAttributes().getValue(Constants.EXPORT_PACKAGE)); |
| 71 | File jdoc = new File(tmp, "jdoc"); |
| 72 | jdoc.mkdirs(); |
| 73 | project.progress("Generating Javadoc for: " + exports.keySet()); |
| 74 | Jar javadoc = javadoc(jdoc, project, exports.keySet()); |
| 75 | project.progress("Writing javadoc jar"); |
| 76 | File javadocFile = write(tmp, new JarResource(javadoc), "javadoc.jar"); |
| 77 | project.progress("Writing main file"); |
| 78 | File mainFile = write(tmp, new JarResource(main), "main.jar"); |
| 79 | project.progress("Writing sources file"); |
| 80 | File srcFile = write(tmp, new JarResource(main), "src.jar"); |
| 81 | |
| 82 | project.progress("Deploying main file"); |
| 83 | maven_gpg_sign_and_deploy(project, mainFile, null, pomFile); |
| 84 | project.progress("Deploying main sources file"); |
| 85 | maven_gpg_sign_and_deploy(project, srcFile, "sources", null); |
| 86 | project.progress("Deploying main javadoc file"); |
| 87 | maven_gpg_sign_and_deploy(project, javadocFile, "javadoc", null); |
| 88 | |
| 89 | } finally { |
| 90 | main.close(); |
| 91 | src.close(); |
| 92 | } |
| 93 | } |
| 94 | return true; |
| 95 | } |
| 96 | |
| 97 | private void split(Jar original, Jar main, Jar src) { |
| 98 | for (Map.Entry<String, Resource> e : original.getResources().entrySet()) { |
| 99 | String path = e.getKey(); |
| 100 | if (path.startsWith("OSGI-OPT/src/")) { |
| 101 | src.putResource(path.substring("OSGI-OPT/src/".length()), e.getValue()); |
| 102 | } else { |
| 103 | main.putResource(path, e.getValue()); |
| 104 | } |
| 105 | } |
| 106 | } |
| 107 | |
| 108 | // gpg:sign-and-deploy-file \ |
| 109 | // -Durl=http://oss.sonatype.org/service/local/staging/deploy/maven2 |
| 110 | // \ |
| 111 | // -DrepositoryId=sonatype-nexus-staging \ |
| 112 | // -DupdateReleaseInfo=true \ |
| 113 | // -DpomFile=pom.xml \ |
| 114 | // -Dfile=/Ws/bnd/biz.aQute.bndlib/tmp/biz.aQute.bndlib.jar \ |
| 115 | // -Dpassphrase=a1k3v3t5x3 |
| 116 | |
| 117 | private void maven_gpg_sign_and_deploy(Project b, File file, String classifier, File pomFile) |
| 118 | throws Exception { |
| 119 | Command command = new Command(); |
| 120 | command.setTrace(); |
| 121 | command.add(b.getProperty("mvn", "mvn")); |
| 122 | command.add("gpg:sign-and-deploy-file", "-DreleaseInfo=true", "-DpomFile=pom.xml"); |
| 123 | command.add("-Dfile=" + file.getAbsolutePath()); |
| 124 | command.add("-DrepositoryId=" + repository); |
| 125 | command.add("-Durl=" + url); |
| 126 | optional(command, "passphrase", passphrase); |
| 127 | optional(command, "keyname", keyname); |
| 128 | optional(command, "homedir", homedir); |
| 129 | optional(command, "classifier", classifier); |
| 130 | optional(command, "pomFile", pomFile == null ? null : pomFile.getAbsolutePath()); |
| 131 | |
| 132 | StringBuilder stdout = new StringBuilder(); |
| 133 | StringBuilder stderr = new StringBuilder(); |
| 134 | |
| 135 | int result = command.execute(stdout, stderr); |
| 136 | if (result != 0) { |
| 137 | b.error("Maven deploy to %s failed to sign and transfer %s because %s", repository, |
| 138 | file, "" + stdout + stderr); |
| 139 | } |
| 140 | } |
| 141 | |
| 142 | private void optional(Command command, String key, String value) { |
| 143 | if (value == null) |
| 144 | return; |
| 145 | |
| 146 | command.add("-D=" + value); |
| 147 | } |
| 148 | |
| 149 | private Jar javadoc(File tmp, Project b, Set<String> exports) throws Exception { |
| 150 | Command command = new Command(); |
| 151 | |
| 152 | command.add(b.getProperty("javadoc", "javadoc")); |
| 153 | command.add("-d"); |
| 154 | command.add(tmp.getAbsolutePath()); |
| 155 | command.add("-sourcepath"); |
| 156 | command.add( Processor.join(b.getSourcePath(),File.pathSeparator)); |
| 157 | |
| 158 | for (String packageName : exports) { |
| 159 | command.add(packageName); |
| 160 | } |
| 161 | |
| 162 | StringBuilder out = new StringBuilder(); |
| 163 | StringBuilder err = new StringBuilder(); |
| 164 | Command c = new Command(); |
| 165 | c.setTrace(); |
| 166 | int result = c.execute(out, err); |
| 167 | if (result == 0) { |
| 168 | Jar jar = new Jar(tmp); |
| 169 | b.addClose(jar); |
| 170 | return jar; |
| 171 | } |
| 172 | b.error("Error during execution of javadoc command: %s / %s", out, err); |
| 173 | return null; |
| 174 | } |
| 175 | |
| 176 | private File write(File base, Resource r, String fileName) throws Exception { |
| 177 | File f = Processor.getFile(base, fileName); |
| 178 | OutputStream out = new FileOutputStream(f); |
| 179 | try { |
| 180 | r.write(out); |
| 181 | } finally { |
| 182 | out.close(); |
| 183 | } |
| 184 | return f; |
| 185 | } |
| 186 | |
| 187 | } |