Use byte-encoded UTF-8 for sourced environment in Python 2 (#3489)
- Fixes recurring errors on develop with unicode commit characters. - still Python3-proof: python3 will use str instead of bytestrings.
This commit is contained in:
parent
a0ab3c2523
commit
1297e47463
@ -26,6 +26,7 @@
|
|||||||
import inspect
|
import inspect
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
import os.path
|
import os.path
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
@ -268,8 +269,8 @@ def from_sourcing_files(*args, **kwargs):
|
|||||||
:param \*args: list of files to be sourced
|
:param \*args: list of files to be sourced
|
||||||
:rtype: instance of EnvironmentModifications
|
:rtype: instance of EnvironmentModifications
|
||||||
"""
|
"""
|
||||||
|
|
||||||
env = EnvironmentModifications()
|
env = EnvironmentModifications()
|
||||||
|
|
||||||
# Check if the files are actually there
|
# Check if the files are actually there
|
||||||
files = [line.split(' ')[0] for line in args]
|
files = [line.split(' ')[0] for line in args]
|
||||||
non_existing = [file for file in files if not os.path.isfile(file)]
|
non_existing = [file for file in files if not os.path.isfile(file)]
|
||||||
@ -277,6 +278,7 @@ def from_sourcing_files(*args, **kwargs):
|
|||||||
message = 'trying to source non-existing files\n'
|
message = 'trying to source non-existing files\n'
|
||||||
message += '\n'.join(non_existing)
|
message += '\n'.join(non_existing)
|
||||||
raise RuntimeError(message)
|
raise RuntimeError(message)
|
||||||
|
|
||||||
# Relevant kwd parameters and formats
|
# Relevant kwd parameters and formats
|
||||||
info = dict(kwargs)
|
info = dict(kwargs)
|
||||||
info.setdefault('shell', '/bin/bash')
|
info.setdefault('shell', '/bin/bash')
|
||||||
@ -309,11 +311,17 @@ def from_sourcing_files(*args, **kwargs):
|
|||||||
if proc.returncode != 0:
|
if proc.returncode != 0:
|
||||||
raise RuntimeError('sourcing files returned a non-zero exit code')
|
raise RuntimeError('sourcing files returned a non-zero exit code')
|
||||||
output = ''.join([line for line in proc.stdout])
|
output = ''.join([line for line in proc.stdout])
|
||||||
# Construct a dictionary with all the variables in the new environment
|
|
||||||
after_source_env = dict(
|
# Construct a dictionaries of the environment before and after
|
||||||
(k, v.decode('utf8')) for k, v in json.loads(output).items())
|
# sourcing the files, so that we can diff them.
|
||||||
this_environment = dict(
|
this_environment = dict(os.environ)
|
||||||
(k, v.decode('utf8')) for k, v in os.environ.items())
|
after_source_env = json.loads(output)
|
||||||
|
|
||||||
|
# If we're in python2, convert to str objects instead of unicode
|
||||||
|
# like json gives us. We can't put unicode in os.environ anyway.
|
||||||
|
if sys.version_info[0] < 3:
|
||||||
|
after_source_env = dict((k.encode('utf-8'), v.encode('utf-8'))
|
||||||
|
for k, v in after_source_env.items())
|
||||||
|
|
||||||
# Filter variables that are not related to sourcing a file
|
# Filter variables that are not related to sourcing a file
|
||||||
to_be_filtered = 'SHLVL', '_', 'PWD', 'OLDPWD'
|
to_be_filtered = 'SHLVL', '_', 'PWD', 'OLDPWD'
|
||||||
@ -364,6 +372,7 @@ def return_separator_if_any(first_value, second_value):
|
|||||||
start = modified_list.index(remaining_list[0])
|
start = modified_list.index(remaining_list[0])
|
||||||
end = modified_list.index(remaining_list[-1])
|
end = modified_list.index(remaining_list[-1])
|
||||||
search = sep.join(modified_list[start:end + 1])
|
search = sep.join(modified_list[start:end + 1])
|
||||||
|
|
||||||
if search not in current:
|
if search not in current:
|
||||||
# We just need to set the variable to the new value
|
# We just need to set the variable to the new value
|
||||||
env.set(x, after_source_env[x])
|
env.set(x, after_source_env[x])
|
||||||
|
34
lib/spack/spack/test/data/sourceme_unicode.sh
Normal file
34
lib/spack/spack/test/data/sourceme_unicode.sh
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC.
|
||||||
|
# Produced at the Lawrence Livermore National Laboratory.
|
||||||
|
#
|
||||||
|
# This file is part of Spack.
|
||||||
|
# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
|
||||||
|
# LLNL-CODE-647188
|
||||||
|
#
|
||||||
|
# For details, see https://github.com/llnl/spack
|
||||||
|
# Please also see the LICENSE file for our notice and the LGPL.
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License (as
|
||||||
|
# published by the Free Software Foundation) version 2.1, February 1999.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful, but
|
||||||
|
# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
|
||||||
|
# conditions of the GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public
|
||||||
|
# License along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# Set an environment variable with some unicode in it to ensure that
|
||||||
|
# Spack can decode it.
|
||||||
|
#
|
||||||
|
# This has caused squashed commits on develop to break, as some
|
||||||
|
# committers use unicode in their messages, and Travis sets the
|
||||||
|
# current commit message in an environment variable.
|
||||||
|
export UNICODE_VAR='don\xe2\x80\x99t'
|
@ -96,7 +96,8 @@ def files_to_be_sourced():
|
|||||||
files = [
|
files = [
|
||||||
os.path.join(datadir, 'sourceme_first.sh'),
|
os.path.join(datadir, 'sourceme_first.sh'),
|
||||||
os.path.join(datadir, 'sourceme_second.sh'),
|
os.path.join(datadir, 'sourceme_second.sh'),
|
||||||
os.path.join(datadir, 'sourceme_parameters.sh intel64')
|
os.path.join(datadir, 'sourceme_parameters.sh intel64'),
|
||||||
|
os.path.join(datadir, 'sourceme_unicode.sh')
|
||||||
]
|
]
|
||||||
|
|
||||||
return files
|
return files
|
||||||
@ -230,7 +231,6 @@ def test_source_files(files_to_be_sourced):
|
|||||||
"""Tests the construction of a list of environment modifications that are
|
"""Tests the construction of a list of environment modifications that are
|
||||||
the result of sourcing a file.
|
the result of sourcing a file.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
env = EnvironmentModifications.from_sourcing_files(*files_to_be_sourced)
|
env = EnvironmentModifications.from_sourcing_files(*files_to_be_sourced)
|
||||||
modifications = env.group_by_name()
|
modifications = env.group_by_name()
|
||||||
|
|
||||||
@ -238,7 +238,7 @@ def test_source_files(files_to_be_sourced):
|
|||||||
# spurious entries for things like PS1
|
# spurious entries for things like PS1
|
||||||
#
|
#
|
||||||
# TODO: figure out how to make a bit more robust.
|
# TODO: figure out how to make a bit more robust.
|
||||||
assert len(modifications) >= 4
|
assert len(modifications) >= 5
|
||||||
|
|
||||||
# Set new variables
|
# Set new variables
|
||||||
assert len(modifications['NEW_VAR']) == 1
|
assert len(modifications['NEW_VAR']) == 1
|
||||||
|
Loading…
Reference in New Issue
Block a user