// 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.rules.python; import com.google.devtools.build.lib.analysis.config.BuildOptions; import com.google.devtools.build.lib.analysis.config.transitions.PatchTransition; import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; /** * A configuration transition that sets the Python version by setting {@link * PythonOptions#forcePython}. */ @AutoCodec public class PythonVersionTransition implements PatchTransition { private final PythonVersion defaultVersion; /** * Creates a new transition that sets the given version if not already specified by * {@link PythonOptions#forcePython}. */ PythonVersionTransition(PythonVersion defaultVersion) { this.defaultVersion = defaultVersion; } @Override public BuildOptions patch(BuildOptions options) { PythonOptions pyOptions = options.get(PythonOptions.class); // The current Python version is either explicitly set by --force_python or a // build-wide default. PythonVersion currentVersion = pyOptions.getPythonVersion(); // The new Python version is either explicitly set by --force_python or this transition's // default. PythonVersion newVersion = pyOptions.getPythonVersion(defaultVersion); if (currentVersion == newVersion) { return options; } // forcePython must be one of PY2 or PY3 because these are the only values Blaze's output // directories can safely distinguish. In other words, a configuration with forcePython=PY2 // would have the same output directory prefix as another with forcePython=PY2AND3, which is a // major correctness failure. // // Even though this transition doesn't enforce the above, it only gets called on // "default_python_version" attribute values, which happen to honor this. Proper enforcement is // done in PythonConfiguration#getOutputDirectoryName. BuildOptions newOptions = options.clone(); newOptions.get(PythonOptions.class).forcePython = newVersion; return newOptions; } }