aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--BUILD2
-rw-r--r--src/main/java/com/google/devtools/build/lib/BUILD15
-rwxr-xr-xsrc/main/java/com/google/devtools/build/lib/merge_licenses.sh28
-rw-r--r--src/main/java/com/google/devtools/build/lib/runtime/BuiltinCommandModule.java5
-rw-r--r--src/main/java/com/google/devtools/build/lib/runtime/commands/LicenseCommand.java60
-rw-r--r--src/main/java/com/google/devtools/build/lib/util/ResourceFileLoader.java28
6 files changed, 127 insertions, 11 deletions
diff --git a/BUILD b/BUILD
index d87c426ba7..cecc206099 100644
--- a/BUILD
+++ b/BUILD
@@ -1,5 +1,7 @@
package(default_visibility = ["//scripts/release:__pkg__"])
+exports_files(["LICENSE"])
+
filegroup(
name = "git",
srcs = glob([".git/**"]),
diff --git a/src/main/java/com/google/devtools/build/lib/BUILD b/src/main/java/com/google/devtools/build/lib/BUILD
index 8be69a6b48..2ffe989c1f 100644
--- a/src/main/java/com/google/devtools/build/lib/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/BUILD
@@ -1089,12 +1089,25 @@ java_library(
],
)
+genrule(
+ name = "merge_licenses",
+ srcs = [
+ "//:LICENSE",
+ "//third_party:srcs",
+ ],
+ outs = ["runtime/commands/LICENSE"],
+ cmd = "$(location merge_licenses.sh) $(SRCS) > \"$@\"",
+ tools = ["merge_licenses.sh"],
+)
+
java_library(
name = "bazel",
resources = glob([
"runtime/commands/*.txt",
"runtime/mobileinstall/*.txt",
- ]),
+ ]) + [
+ ":runtime/commands/LICENSE",
+ ],
exports = [":runtime"],
)
diff --git a/src/main/java/com/google/devtools/build/lib/merge_licenses.sh b/src/main/java/com/google/devtools/build/lib/merge_licenses.sh
new file mode 100755
index 0000000000..f2d72e4b89
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/merge_licenses.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+#
+# Copyright 2017 The Bazel Authors. 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.
+#
+
+set -eu
+
+for src in "$@"; do
+ for substr in 'ASSEMBLY_EXCEPTION' 'DISCLAIMER' 'LICENSE' 'license' 'THIRD_PARTY_README'; do
+ if [ -z "${src##*$substr*}" ]; then
+ echo "===== $src ====="
+ cat "$src"
+ echo; echo
+ fi
+ done
+done
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/BuiltinCommandModule.java b/src/main/java/com/google/devtools/build/lib/runtime/BuiltinCommandModule.java
index 3e5a2a5b9d..3f6703efa4 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/BuiltinCommandModule.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/BuiltinCommandModule.java
@@ -20,6 +20,7 @@ import com.google.devtools.build.lib.runtime.commands.CoverageCommand;
import com.google.devtools.build.lib.runtime.commands.DumpCommand;
import com.google.devtools.build.lib.runtime.commands.HelpCommand;
import com.google.devtools.build.lib.runtime.commands.InfoCommand;
+import com.google.devtools.build.lib.runtime.commands.LicenseCommand;
import com.google.devtools.build.lib.runtime.commands.ProfileCommand;
import com.google.devtools.build.lib.runtime.commands.QueryCommand;
import com.google.devtools.build.lib.runtime.commands.RunCommand;
@@ -48,5 +49,9 @@ public final class BuiltinCommandModule extends BlazeModule {
new ShutdownCommand(),
new TestCommand(),
new VersionCommand());
+ // Only enable the "license" command when this binary has an embedded LICENSE file.
+ if (LicenseCommand.isSupported()) {
+ builder.addCommands(new LicenseCommand());
+ }
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/commands/LicenseCommand.java b/src/main/java/com/google/devtools/build/lib/runtime/commands/LicenseCommand.java
new file mode 100644
index 0000000000..5dc8a3a1b2
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/runtime/commands/LicenseCommand.java
@@ -0,0 +1,60 @@
+// Copyright 2017 The Bazel Authors. 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.runtime.commands;
+
+import com.google.devtools.build.lib.analysis.NoBuildEvent;
+import com.google.devtools.build.lib.runtime.BlazeCommand;
+import com.google.devtools.build.lib.runtime.Command;
+import com.google.devtools.build.lib.runtime.CommandEnvironment;
+import com.google.devtools.build.lib.util.ExitCode;
+import com.google.devtools.build.lib.util.ResourceFileLoader;
+import com.google.devtools.build.lib.util.io.OutErr;
+import com.google.devtools.common.options.OptionsParser;
+import com.google.devtools.common.options.OptionsProvider;
+import java.io.IOException;
+
+/** A command that prints an embedded license text. */
+@Command(
+ name = "license",
+ allowResidue = true,
+ mustRunInWorkspace = false,
+ shortDescription = "Prints the license of this software.",
+ help = "Prints the license of this software.\n\n%{options}"
+)
+public class LicenseCommand implements BlazeCommand {
+
+ public static boolean isSupported() {
+ return ResourceFileLoader.resourceExists(LicenseCommand.class, "LICENSE");
+ }
+
+ @Override
+ public ExitCode exec(CommandEnvironment env, OptionsProvider options) {
+ env.getEventBus().post(new NoBuildEvent());
+ OutErr outErr = env.getReporter().getOutErr();
+
+ outErr.printOutLn("Licenses of all components included in this binary:\n");
+
+ try {
+ outErr.printOutLn(ResourceFileLoader.loadResource(this.getClass(), "LICENSE"));
+ } catch (IOException e) {
+ throw new IllegalStateException(
+ "I/O error while trying to print 'LICENSE' resource: " + e.getMessage(), e);
+ }
+
+ return ExitCode.SUCCESS;
+ }
+
+ @Override
+ public void editOptions(CommandEnvironment env, OptionsParser optionsParser) {}
+}
diff --git a/src/main/java/com/google/devtools/build/lib/util/ResourceFileLoader.java b/src/main/java/com/google/devtools/build/lib/util/ResourceFileLoader.java
index 8fde6890f9..a773f4ad41 100644
--- a/src/main/java/com/google/devtools/build/lib/util/ResourceFileLoader.java
+++ b/src/main/java/com/google/devtools/build/lib/util/ResourceFileLoader.java
@@ -16,7 +16,6 @@ package com.google.devtools.build.lib.util;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.common.io.ByteStreams;
-
import java.io.IOException;
import java.io.InputStream;
@@ -29,6 +28,14 @@ public final class ResourceFileLoader {
private ResourceFileLoader() {}
+ public static boolean resourceExists(Class<?> relativeToClass, String resourceName) {
+ try (InputStream resourceStream = getResourceAsStream(relativeToClass, resourceName)) {
+ return resourceStream != null;
+ } catch (IOException e) {
+ return false;
+ }
+ }
+
/**
* Loads a text resource that is located in a directory on the Java classpath that
* corresponds to the package of <code>relativeToClass</code> using UTF8 encoding.
@@ -38,20 +45,21 @@ public final class ResourceFileLoader {
*/
public static String loadResource(Class<?> relativeToClass, String resourceName)
throws IOException {
+ try (InputStream stream = getResourceAsStream(relativeToClass, resourceName)) {
+ if (stream == null) {
+ throw new IOException(resourceName + " not found.");
+ }
+ return new String(ByteStreams.toByteArray(stream), UTF_8);
+ }
+ }
+
+ private static InputStream getResourceAsStream(Class<?> relativeToClass, String resourceName) {
ClassLoader loader = relativeToClass.getClassLoader();
// TODO(bazel-team): use relativeToClass.getPackage().getName().
String className = relativeToClass.getName();
String packageName = className.substring(0, className.lastIndexOf('.'));
String path = packageName.replace('.', '/');
String resource = path + '/' + resourceName;
- InputStream stream = loader.getResourceAsStream(resource);
- if (stream == null) {
- throw new IOException(resourceName + " not found.");
- }
- try {
- return new String(ByteStreams.toByteArray(stream), UTF_8);
- } finally {
- stream.close();
- }
+ return loader.getResourceAsStream(resource);
}
}