Skip to content
This repository was archived by the owner on Nov 5, 2019. It is now read-only.

Commit cf0fbde

Browse files
committed
Add back in pgp signing for maven publish
Because we need it
1 parent e0fe873 commit cf0fbde

File tree

4 files changed

+77
-18
lines changed

4 files changed

+77
-18
lines changed

src/com/facebook/buck/cli/PublishCommand.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,10 @@ public class PublishCommand extends BuildCommand {
102102
@Nullable
103103
private String password = null;
104104

105+
@Option(
106+
name = "--signing-passphrase",
107+
usage = "Passphrase to use for signing published artifacts")
108+
private String pgpPassphrase;
105109

106110
@Override
107111
public int runWithoutHelp(CommandRunnerParams params) throws IOException, InterruptedException {
@@ -126,7 +130,7 @@ public int runWithoutHelp(CommandRunnerParams params) throws IOException, Interr
126130

127131
private boolean publishTargets(
128132
ImmutableList<BuildTarget> buildTargets,
129-
CommandRunnerParams params) {
133+
CommandRunnerParams params) throws InterruptedException {
130134
ImmutableSet.Builder<MavenPublishable> publishables = ImmutableSet.builder();
131135
boolean success = true;
132136
for (BuildTarget buildTarget : buildTargets) {
@@ -163,6 +167,7 @@ private boolean publishTargets(
163167
Optional.ofNullable(remoteRepo),
164168
Optional.ofNullable(username),
165169
Optional.ofNullable(password),
170+
Optional.ofNullable(pgpPassphrase),
166171
dryRun);
167172

168173
try {

src/com/facebook/buck/maven/BUCK

+2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ java_library(
2828
"//src/com/facebook/buck/log:api",
2929
"//src/com/facebook/buck/model:model",
3030
"//src/com/facebook/buck/rules:build_rule",
31+
"//src/com/facebook/buck/util:exceptions",
32+
"//src/com/facebook/buck/util:process_executor",
3133
"//src/com/facebook/buck/util:util",
3234
"//src/com/facebook/buck/util/concurrent:concurrent",
3335
"//third-party/java/args4j:args4j",

src/com/facebook/buck/maven/Publisher.java

+67-16
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,13 @@
2222
import com.facebook.buck.model.UnflavoredBuildTarget;
2323
import com.facebook.buck.rules.BuildRule;
2424
import com.facebook.buck.rules.SourcePathResolver;
25+
import com.facebook.buck.util.Ansi;
26+
import com.facebook.buck.util.Console;
27+
import com.facebook.buck.util.DefaultProcessExecutor;
28+
import com.facebook.buck.util.HumanReadableException;
29+
import com.facebook.buck.util.ProcessExecutor;
30+
import com.facebook.buck.util.ProcessExecutorParams;
31+
import com.facebook.buck.util.Verbosity;
2532
import com.google.common.base.Joiner;
2633
import com.google.common.base.Preconditions;
2734
import com.google.common.base.StandardSystemProperty;
@@ -45,8 +52,10 @@
4552
import org.eclipse.aether.spi.locator.ServiceLocator;
4653
import org.eclipse.aether.util.artifact.SubArtifact;
4754

55+
import java.io.ByteArrayOutputStream;
4856
import java.io.File;
4957
import java.io.IOException;
58+
import java.io.PrintStream;
5059
import java.net.MalformedURLException;
5160
import java.net.URL;
5261
import java.nio.file.Path;
@@ -68,20 +77,12 @@ public class Publisher {
6877
}
6978
private static final Logger LOG = Logger.get(Publisher.class);
7079

80+
private final Optional<String> pgpPassphrase;
7181
private final ServiceLocator locator;
7282
private final LocalRepository localRepo;
7383
private final RemoteRepository remoteRepo;
7484
private final boolean dryRun;
7585

76-
public Publisher(
77-
ProjectFilesystem repositoryFilesystem,
78-
Optional<URL> remoteRepoUrl,
79-
Optional<String> username,
80-
Optional<String> password,
81-
boolean dryRun) {
82-
this(repositoryFilesystem.getRootPath(), remoteRepoUrl, username, password, dryRun);
83-
}
84-
8586
/**
8687
* @param localRepoPath Typically obtained as
8788
* {@link com.facebook.buck.io.ProjectFilesystem#getRootPath}
@@ -90,23 +91,25 @@ public Publisher(
9091
* constructed {@link DeployRequest}. No actual publishing will happen
9192
*/
9293
public Publisher(
93-
Path localRepoPath,
94+
ProjectFilesystem localRepoPath,
9495
Optional<URL> remoteRepoUrl,
9596
Optional<String> username,
9697
Optional<String> password,
98+
Optional<String> pgpPassphrase,
9799
boolean dryRun) {
98-
this.localRepo = new LocalRepository(localRepoPath.toFile());
100+
this.localRepo = new LocalRepository(localRepoPath.getRootPath().toFile());
99101
this.remoteRepo = AetherUtil.toRemoteRepository(
100102
remoteRepoUrl.orElse(MAVEN_CENTRAL),
101103
username,
102104
password);
105+
this.pgpPassphrase = pgpPassphrase;
103106
this.locator = AetherUtil.initServiceLocator();
104107
this.dryRun = dryRun;
105108
}
106109

107110
public ImmutableSet<DeployResult> publish(
108111
SourcePathResolver pathResolver,
109-
ImmutableSet<MavenPublishable> publishables) throws DeploymentException {
112+
ImmutableSet<MavenPublishable> publishables) throws DeploymentException, InterruptedException {
110113
ImmutableListMultimap<UnflavoredBuildTarget, UnflavoredBuildTarget> duplicateBuiltinBuileRules =
111114
checkForDuplicatePackagedDeps(publishables);
112115
if (duplicateBuiltinBuileRules.size() > 0) {
@@ -198,7 +201,7 @@ public DeployResult publish(
198201
String artifactId,
199202
String version,
200203
List<File> toPublish)
201-
throws DeploymentException {
204+
throws DeploymentException, InterruptedException {
202205
return publish(new DefaultArtifact(groupId, artifactId, "", version), toPublish);
203206
}
204207

@@ -211,7 +214,7 @@ public DeployResult publish(
211214
* extension of each given file will be used as a maven "extension" coordinate
212215
*/
213216
public DeployResult publish(Artifact descriptor, List<File> toPublish)
214-
throws DeploymentException {
217+
throws DeploymentException, InterruptedException {
215218
String providedExtension = descriptor.getExtension();
216219
if (!providedExtension.isEmpty()) {
217220
LOG.warn(
@@ -236,7 +239,7 @@ public DeployResult publish(Artifact descriptor, List<File> toPublish)
236239
* coordinates in the corresponding {@link Artifact}.
237240
* @see Artifact#setFile
238241
*/
239-
public DeployResult publish(List<Artifact> toPublish) throws DeploymentException {
242+
public DeployResult publish(List<Artifact> toPublish) throws DeploymentException, InterruptedException {
240243
RepositorySystem repoSys = Preconditions.checkNotNull(
241244
locator.getService(RepositorySystem.class));
242245

@@ -255,15 +258,63 @@ public DeployResult publish(List<Artifact> toPublish) throws DeploymentException
255258
}
256259
}
257260

258-
private DeployRequest createDeployRequest(List<Artifact> toPublish) {
261+
private DeployRequest createDeployRequest(List<Artifact> toPublish) throws InterruptedException {
259262
DeployRequest deployRequest = new DeployRequest().setRepository(remoteRepo);
260263
for (Artifact artifact : toPublish) {
261264
File file = artifact.getFile();
262265
Preconditions.checkNotNull(file);
263266
Preconditions.checkArgument(file.exists(), "No such file: %s", file.getAbsolutePath());
264267

265268
deployRequest.addArtifact(artifact);
269+
270+
if (pgpPassphrase.isPresent()) {
271+
deployRequest.addArtifact(sign(artifact, file));
272+
}
266273
}
267274
return deployRequest;
268275
}
276+
277+
private SubArtifact sign(Artifact descriptor, File file) throws InterruptedException {
278+
// Run gpg
279+
try (PrintStream stdout = new PrintStream(new ByteArrayOutputStream());
280+
PrintStream stderr = new PrintStream(new ByteArrayOutputStream())) {
281+
File expectedOutput = new File(file.getAbsolutePath() + ".asc");
282+
if (expectedOutput.exists() && !expectedOutput.delete()) {
283+
throw new HumanReadableException(
284+
"Existing signature exists, but cannot be deleted: %s",
285+
file);
286+
}
287+
288+
ProcessExecutor processExecutor = new DefaultProcessExecutor(
289+
new Console(
290+
Verbosity.SILENT,
291+
stdout,
292+
stderr,
293+
Ansi.withoutTty()));
294+
ProcessExecutorParams args = ProcessExecutorParams.builder()
295+
.addCommand(
296+
"gpg",
297+
"-ab",
298+
"--batch",
299+
"--passphrase", pgpPassphrase.get(),
300+
file.getAbsolutePath())
301+
.build();
302+
ProcessExecutor.Result result = processExecutor.launchAndExecute(args);
303+
if (result.getExitCode() != 0) {
304+
throw new HumanReadableException("Unable to sign %s", file);
305+
}
306+
307+
if (!expectedOutput.exists()) {
308+
throw new HumanReadableException("Unable to find signature for %s", file);
309+
}
310+
311+
return new SubArtifact(
312+
descriptor,
313+
descriptor.getClassifier(),
314+
"*.asc",
315+
expectedOutput);
316+
} catch (IOException e) {
317+
throw new HumanReadableException(e, "Unable to generate signauture for %s", file);
318+
}
319+
}
269320
}

test/com/facebook/buck/maven/PublisherTest.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,11 @@ public class PublisherTest {
5757
public void setUp() {
5858
ProjectFilesystem filesystem = new FakeProjectFilesystem();
5959
publisher = new Publisher(
60-
filesystem,
60+
filesystem.getRootPath(),
6161
/* remoteRepoUrl */ Optional.empty(),
6262
/* username */ Optional.empty(),
6363
/* password */ Optional.empty(),
64+
/* pgp passphrase */ Optional.empty(),
6465
/* dryRun */ true);
6566
}
6667

0 commit comments

Comments
 (0)