Reproducibility.java
/* ====================================================================
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 org.apache.poi.util;
import java.io.IOException;
import org.apache.commons.io.function.IORunnable;
/**
* Helper class for allowing to produce so called
* "reproducible" output.
*
* I.e. multiple runs of the same steps should
* produce the same byte-by-byte result.
*
* This usually means that among other "randomness"
* timestamp should be avoided.
*
* This class provides a few useful bits to allow Apache POI to produce
* reproducible binary files.
*
* See https://reproducible-builds.org/ for more details.
*/
public class Reproducibility {
// Add some support for reproducible output files
// if SOURCE_DATE_EPOCH is set, we use timestamp "0" for
// entries in Zip files
// See https://reproducible-builds.org/docs/source-date-epoch/
// for the specification of SOURCE_DATE_EPOCH
private static boolean IS_SOURCE_DATE_EPOCH =
System.getenv("SOURCE_DATE_EPOCH") != null;
/**
* Check if the environment variable SOURCE_DATE_EPOCH is set.
*
* @return True if set, false otherwise
*/
public static boolean isSourceDateEpoch() {
return IS_SOURCE_DATE_EPOCH;
}
/**
* Execute a runnable with SOURCE_DATE_EPOCH set.
*
* This is mostly only used in tests to check reproducibility
* of documents.
*
* @param r A runnable which executes the wanted steps with
* SOURCE_DATE_EPOCH defined
*
* @throws IOException if executing the runnable throws an IOException
* @throws RuntimeException if executing the runnable throws a RuntimeException
*/
public static void runWithSourceDateEpoch(IORunnable r) throws IOException {
boolean before = IS_SOURCE_DATE_EPOCH;
IS_SOURCE_DATE_EPOCH = true;
try {
r.run();
} finally {
IS_SOURCE_DATE_EPOCH = before;
}
}
}