diff options
author | Daniel Wagner-Hall <danielwh@google.com> | 2015-04-06 22:39:03 +0000 |
---|---|---|
committer | Damien Martin-Guillerez <dmarting@google.com> | 2015-04-08 08:45:47 +0000 |
commit | d99b27b12437fd7f12c80f1ecebb66e4abf3d754 (patch) | |
tree | ece803489693357692795fcbd243b6240d64f683 /src/main/java | |
parent | b893421171f70c7948a73da335e59f65b200bf3c (diff) |
objc: Pass --embed_label to iOS application Info.plist files
--
MOS_MIGRATED_REVID=90455131
Diffstat (limited to 'src/main/java')
8 files changed, 194 insertions, 12 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/BuildInfo.java b/src/main/java/com/google/devtools/build/lib/analysis/BuildInfo.java new file mode 100644 index 0000000000..4177e56d93 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/analysis/BuildInfo.java @@ -0,0 +1,26 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed 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 com.google.devtools.build.lib.analysis; + +/** + * A class to hold and query the build information and support methods to read + * it from disk. + */ +public class BuildInfo { + /** + * Named constants for the BuildInfo keys. + */ + public static final String BUILD_EMBED_LABEL = "BUILD_EMBED_LABEL"; +} diff --git a/src/main/java/com/google/devtools/build/lib/analysis/WorkspaceStatusAction.java b/src/main/java/com/google/devtools/build/lib/analysis/WorkspaceStatusAction.java index 986b085f65..12b477b3f3 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/WorkspaceStatusAction.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/WorkspaceStatusAction.java @@ -25,6 +25,8 @@ import com.google.devtools.build.lib.actions.ArtifactOwner; import com.google.devtools.build.lib.actions.Executor.ActionContext; import com.google.devtools.build.lib.vfs.FileSystemUtils; import com.google.devtools.build.lib.vfs.Path; +import com.google.devtools.common.options.Option; +import com.google.devtools.common.options.OptionsBase; import java.io.IOException; import java.util.HashMap; @@ -49,6 +51,17 @@ import java.util.UUID; public abstract class WorkspaceStatusAction extends AbstractAction { /** + * Options controlling the workspace status command. + */ + public static class Options extends OptionsBase { + @Option(name = "embed_label", + defaultValue = "", + category = "misc", + help = "Embed source control revision or release label in binary") + public String embedLabel; + } + + /** * The type of a workspace status action key. */ public enum KeyType { diff --git a/src/main/java/com/google/devtools/build/lib/bazel/BazelWorkspaceStatusModule.java b/src/main/java/com/google/devtools/build/lib/bazel/BazelWorkspaceStatusModule.java index dda983d8cc..21cb0c8c17 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/BazelWorkspaceStatusModule.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/BazelWorkspaceStatusModule.java @@ -16,6 +16,7 @@ package com.google.devtools.build.lib.bazel; import com.google.common.base.Supplier; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import com.google.common.eventbus.Subscribe; import com.google.devtools.build.lib.actions.ActionContextProvider; import com.google.devtools.build.lib.actions.ActionExecutionContext; import com.google.devtools.build.lib.actions.ActionExecutionException; @@ -36,28 +37,35 @@ import com.google.devtools.build.lib.analysis.WorkspaceStatusAction.Key; import com.google.devtools.build.lib.runtime.BlazeModule; import com.google.devtools.build.lib.runtime.BlazeRuntime; import com.google.devtools.build.lib.runtime.Command; +import com.google.devtools.build.lib.runtime.GotOptionsEvent; import com.google.devtools.build.lib.vfs.FileSystemUtils; import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.common.options.OptionsBase; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.util.Map; import java.util.Objects; import java.util.UUID; +import java.util.concurrent.atomic.AtomicReference; /** - * Workspace status information for Bazel. - * - * <p>Currently only a stub. + * Provides information about the workspace (e.g. source control context, current machine, current + * user, etc). */ public class BazelWorkspaceStatusModule extends BlazeModule { private static class BazelWorkspaceStatusAction extends WorkspaceStatusAction { private final Artifact stableStatus; private final Artifact volatileStatus; + private final AtomicReference<Options> options; private BazelWorkspaceStatusAction( - Artifact stableStatus, Artifact volatileStatus) { + AtomicReference<WorkspaceStatusAction.Options> options, + Artifact stableStatus, + Artifact volatileStatus) { super(BuildInfoHelper.BUILD_INFO_ACTION_OWNER, Artifact.NO_ARTIFACTS, ImmutableList.of(stableStatus, volatileStatus)); + this.options = options; this.stableStatus = stableStatus; this.volatileStatus = volatileStatus; } @@ -71,7 +79,9 @@ public class BazelWorkspaceStatusModule extends BlazeModule { public void execute(ActionExecutionContext actionExecutionContext) throws ActionExecutionException { try { - FileSystemUtils.writeContent(stableStatus.getPath(), new byte[] {}); + String embedLabelLine = String.format("BUILD_EMBED_LABEL %s\n", options.get().embedLabel); + FileSystemUtils.writeContent( + stableStatus.getPath(), embedLabelLine.getBytes(StandardCharsets.UTF_8)); FileSystemUtils.writeContent(volatileStatus.getPath(), new byte[] {}); } catch (IOException e) { throw new ActionExecutionException(e, this, true); @@ -111,6 +121,16 @@ public class BazelWorkspaceStatusModule extends BlazeModule { } @Override + public boolean executeUnconditionally() { + return true; + } + + @Override + public boolean isVolatile() { + return true; + } + + @Override public Artifact getVolatileStatus() { return volatileStatus; } @@ -137,7 +157,7 @@ public class BazelWorkspaceStatusModule extends BlazeModule { Artifact volatileArtifact = factory.getConstantMetadataArtifact( new PathFragment("volatile-status.txt"), root, artifactOwner); - return new BazelWorkspaceStatusAction(stableArtifact, volatileArtifact); + return new BazelWorkspaceStatusAction(options, stableArtifact, volatileArtifact); } } @@ -178,10 +198,24 @@ public class BazelWorkspaceStatusModule extends BlazeModule { } private BlazeRuntime runtime; + private AtomicReference<WorkspaceStatusAction.Options> options = new AtomicReference<>(); @Override public void beforeCommand(BlazeRuntime runtime, Command command) { this.runtime = runtime; + runtime.getEventBus().register(this); + } + + @Override + public Iterable<Class<? extends OptionsBase>> getCommandOptions(Command command) { + return command.builds() + ? ImmutableList.<Class<? extends OptionsBase>>of(WorkspaceStatusAction.Options.class) + : ImmutableList.<Class<? extends OptionsBase>>of(); + } + + @Subscribe + public void gotOptionsEvent(GotOptionsEvent event) { + options.set(event.getOptions().getOptions(WorkspaceStatusAction.Options.class)); } @Override diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java index 4ee294d211..94e64fff55 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java @@ -80,6 +80,7 @@ import com.google.devtools.build.lib.rules.objc.IosDeviceRule; import com.google.devtools.build.lib.rules.objc.IosExtensionBinaryRule; import com.google.devtools.build.lib.rules.objc.IosExtensionRule; import com.google.devtools.build.lib.rules.objc.ObjcBinaryRule; +import com.google.devtools.build.lib.rules.objc.ObjcBuildInfoFactory; import com.google.devtools.build.lib.rules.objc.ObjcBundleLibraryRule; import com.google.devtools.build.lib.rules.objc.ObjcBundleRule; import com.google.devtools.build.lib.rules.objc.ObjcCommandLineOptions; @@ -192,6 +193,7 @@ public class BazelRuleClassProvider { public static void setup(ConfiguredRuleClassProvider.Builder builder) { builder .addBuildInfoFactory(new BazelJavaBuildInfoFactory()) + .addBuildInfoFactory(new ObjcBuildInfoFactory()) .setConfigurationCollectionFactory(new BazelConfigurationCollection()) .setPrerequisiteValidator(new BazelPrerequisiteValidator()) .setSkylarkAccessibleJavaClasses(skylarkBuiltinJavaObects); diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/BundleSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/BundleSupport.java index 676e273fb8..8d51f5752d 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/BundleSupport.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/BundleSupport.java @@ -48,6 +48,13 @@ import java.util.Set; * <p>Methods on this class can be called in any order without impacting the result. */ final class BundleSupport { + + static class ExtraMergePlists extends IterableWrapper<Artifact> { + ExtraMergePlists(Artifact... inputs) { + super(inputs); + } + } + private final RuleContext ruleContext; private final Set<TargetDeviceFamily> targetDeviceFamilies; private final ExtraActoolArgs extraActoolArgs; @@ -62,17 +69,22 @@ final class BundleSupport { * rule's * @param optionsProvider provider containing options and plist settings for this rule and its * dependencies + * @param extraMergePlists additional plist files to merge */ - static InfoplistMerging infoPlistMerging(RuleContext ruleContext, - ObjcProvider objcProvider, OptionsProvider optionsProvider) { + static InfoplistMerging infoPlistMerging( + RuleContext ruleContext, + ObjcProvider objcProvider, + OptionsProvider optionsProvider, + ExtraMergePlists extraMergePlists) { IntermediateArtifacts intermediateArtifacts = ObjcRuleClasses.intermediateArtifacts(ruleContext); - + return new InfoplistMerging.Builder(ruleContext) .setIntermediateArtifacts(intermediateArtifacts) .setInputPlists(NestedSetBuilder.<Artifact>stableOrder() .addTransitive(optionsProvider.getInfoplists()) .addAll(actoolPartialInfoplist(ruleContext, objcProvider).asSet()) + .addAll(extraMergePlists) .build()) .setPlmerge(ruleContext.getExecutablePrerequisite("$plmerge", Mode.HOST)) .build(); @@ -282,6 +294,15 @@ final class BundleSupport { } } + /** + * Validates any rule attributes and dependencies related to this bundle. + * + * @return this bundle support + */ + BundleSupport validateAttributes() { + return this; + } + private void registerMergeInfoplistAction() { // TODO(bazel-team): Move action implementation from InfoplistMerging to this class. ruleContext.registerAction(bundling.getInfoplistMerging().getMergeAction()); diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBuildInfoFactory.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBuildInfoFactory.java new file mode 100644 index 0000000000..eaf7678071 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBuildInfoFactory.java @@ -0,0 +1,52 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed 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 com.google.devtools.build.lib.rules.objc; + +import com.google.common.collect.ImmutableList; +import com.google.devtools.build.lib.actions.Action; +import com.google.devtools.build.lib.actions.Artifact; +import com.google.devtools.build.lib.analysis.buildinfo.BuildInfoCollection; +import com.google.devtools.build.lib.analysis.buildinfo.BuildInfoFactory; +import com.google.devtools.build.lib.analysis.config.BuildConfiguration; + +/** + * Objc build info creation - passes on BuildInfo output file for consumption from Objc rules. + */ +public class ObjcBuildInfoFactory implements BuildInfoFactory { + + public static final BuildInfoKey KEY = new BuildInfoKey("ObjC"); + + /** + * Returns no actions, exactly the one BuildInfo artifact, and no buildChangelist artifacts. + */ + @Override + public BuildInfoCollection create(BuildInfoContext context, BuildConfiguration config, + Artifact buildInfo, Artifact buildChangelist) { + return new BuildInfoCollection( + ImmutableList.<Action>of(), + ImmutableList.of(buildInfo), + ImmutableList.of(buildInfo)); + } + + @Override + public BuildInfoKey getKey() { + return KEY; + } + + @Override + public boolean isEnabled(BuildConfiguration config) { + return config.hasFragment(ObjcConfiguration.class); + } +} diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBundleLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBundleLibrary.java index 1c8f7c1faa..7e4c48c15a 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBundleLibrary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBundleLibrary.java @@ -88,7 +88,8 @@ public class ObjcBundleLibrary implements RuleConfiguredTargetFactory { .setBundleDirFormat("%s.bundle") .setObjcProvider(common.getObjcProvider()) .setInfoplistMerging( - BundleSupport.infoPlistMerging(ruleContext, common.getObjcProvider(), optionsProvider)) + BundleSupport.infoPlistMerging(ruleContext, common.getObjcProvider(), optionsProvider, + new BundleSupport.ExtraMergePlists())) .setIntermediateArtifacts(intermediateArtifacts) .build(); } diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingSupport.java index 34f82e7319..912d066edc 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingSupport.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingSupport.java @@ -22,7 +22,9 @@ import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Joiner; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; import com.google.devtools.build.lib.actions.Artifact; +import com.google.devtools.build.lib.analysis.BuildInfo; import com.google.devtools.build.lib.analysis.FilesToRunProvider; import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode; import com.google.devtools.build.lib.analysis.RuleContext; @@ -232,6 +234,8 @@ public final class ReleaseBundlingSupport { maybeSignedIpa = registerBundleSigningActions(ipaOutput); } + registerEmbedLabelPlistAction(); + BundleMergeControlBytes bundleMergeControlBytes = new BundleMergeControlBytes( bundling, maybeSignedIpa, objcConfiguration, families); registerBundleMergeActions( @@ -240,6 +244,29 @@ public final class ReleaseBundlingSupport { return this; } + private void registerEmbedLabelPlistAction() { + Artifact buildInfo = Iterables.getOnlyElement( + ruleContext.getAnalysisEnvironment().getBuildInfo(ruleContext, ObjcBuildInfoFactory.KEY)); + ruleContext.registerAction(new SpawnAction.Builder() + .setMnemonic("ObjcVersionPlist") + .setExecutable(new PathFragment("/bin/bash")) + .setCommandLine(new CustomCommandLine.Builder() + .add("-c") + .add( + "VERSION=\"$(" + + "grep \"^" + BuildInfo.BUILD_EMBED_LABEL + "\" " + buildInfo.getExecPathString() + + " | cut -d' ' -f2- | sed -e 's#\"#\\\"#g')\" && " + + " for KEY in CFBundleVersion CFBundleShortVersionString; do" + + " echo \"${KEY}=\\\"${VERSION}\\\";\" >> " + + getGeneratedVersionPlist().getExecPathString() + + " ; done" + ) + .build()) + .addInput(buildInfo) + .addOutput(getGeneratedVersionPlist()) + .build(ruleContext)); + } + private Artifact registerBundleSigningActions(Artifact ipaOutput) { PathFragment entitlementsDirectory = ruleContext.getUniqueDirectory("entitlements"); Artifact teamPrefixFile = @@ -366,7 +393,7 @@ public final class ReleaseBundlingSupport { return new ExtraActoolArgs(extraArgs.build()); } - private static Bundling bundling( + private Bundling bundling( RuleContext ruleContext, ObjcProvider objcProvider, OptionsProvider optionsProvider, String bundleDirFormat) { ImmutableList<BundleableFile> extraBundleFiles; @@ -396,7 +423,8 @@ public final class ReleaseBundlingSupport { .addExtraBundleFiles(extraBundleFiles) .setObjcProvider(objcProvider) .setInfoplistMerging( - BundleSupport.infoPlistMerging(ruleContext, objcProvider, optionsProvider)) + BundleSupport.infoPlistMerging(ruleContext, objcProvider, optionsProvider, + new BundleSupport.ExtraMergePlists(getGeneratedVersionPlist()))) .setIntermediateArtifacts(ObjcRuleClasses.intermediateArtifacts(ruleContext)) .setPrimaryBundleId(primaryBundleId) .setFallbackBundleId(fallbackBundleId) @@ -612,6 +640,11 @@ public final class ReleaseBundlingSupport { appDir); } + private Artifact getGeneratedVersionPlist() { + return ruleContext.getRelatedArtifact( + ruleContext.getUniqueDirectory("plists"), "-version.plist"); + } + /** * Logic to access attributes required by application support. Attributes are required and * guaranteed to return a value or throw unless they are annotated with {@link Nullable} in which |