Skip to content

Commit

Permalink
Var init refactoring (#21)
Browse files Browse the repository at this point in the history
* Unbreak the tool. `global_variables` were accessed incorrectly in package.py

* Resolved some tests warnings

* Unbroken some (but not all!) tests.
Upgraded version of packages in tests to correspond to Ubuntu 20.10.
Refactored calling subprocesses a bit and moved them into the main package - we will need them later.

* Implemented automatic retrieval of some vars. Moved some necessary funcs from tests to main package. Trying to fix tests.
  • Loading branch information
KOLANICH authored Feb 7, 2021
1 parent 5e13e38 commit af8e698
Show file tree
Hide file tree
Showing 6 changed files with 211 additions and 64 deletions.
26 changes: 17 additions & 9 deletions pykg_config/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,22 +185,30 @@ def main():
CORRESPONDING_VERSION))
sys.exit(0)

global_variables = {}

zip_name = 'python{0}{1}.zip'.format(sys.version_info[0],
sys.version_info[1])
for path in sys.path:
if path.endswith('64/' + zip_name):
Options().set_option('is_64bit', True)
break

if getenv('PKG_CONFIG_SYSROOT_DIR'):
global_variables['pc_sysrootdir'] = getenv('PKG_CONFIG_SYSROOT_DIR')
if getenv('PKG_CONFIG_TOP_BUILD_DIR'):
global_variables['pc_topbuilddir'] = getenv('PKG_CONFIG_TOP_BUILD_DIR')
if getenv('PKG_CONFIG_LIBDIR'):
global_variables["config_libdir"] = getenv('PKG_CONFIG_LIBDIR').split(self._split_char())

def splitSerializedList(ls):
return ls.split(self._split_char())

variable_init_spec = {
("pc_sysrootdir", str),
("pc_topbuilddir", str),
("pc_path", splitSerializedList),
("config_libdir", splitSerializedList),
}

global_variables = {}

for var_name, postprocessor in variable_init_spec:
r = look_up_var_in_env(var_name)
if r:
global_variables[var_name] = postprocessor(r)

if getenv('PKG_CONFIG_DISABLE_UNINSTALLED'):
Options().set_option('prefer_uninstalled', False)
if getenv('PKG_CONFIG_ALLOW_SYSTEM_LIBS'):
Expand Down
55 changes: 55 additions & 0 deletions pykg_config/envVars2VarsRemap.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Copyright (c) 2009, Geoffrey Biggs
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of the Geoffrey Biggs nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

# File: envVars2VarsRemap.py
# Author: KOLANICH
# Part of pykg-config.

__version__ = "$Revision: $"
# $Source$

env_var_prefix = "PKG_CONFIG_PATH"

envVars2VarsRemap = {
"PATH": "pc_path",
"SYSROOT_DIR": "pc_sysrootdir",
"TOP_BUILD_DIR": "pc_topbuilddir",
"LIBDIR": "config_libdir",
}

envVars2VarsRemap = {
(k + env_var_prefix): v for k, v in envVars2VarsRemap.items()
}
vars2EnvVarsRemap = {v: k for k, v in envVars2VarsRemap.items()}

def look_up_var_in_env(var_name, default=None):
from os import environ

return environ.get(vars2EnvVarsRemap[var_name], default=default)


# vim: tw=79
4 changes: 2 additions & 2 deletions pykg_config/package.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ def _parse_cflags(self, value, global_variables):
if flag[2:] not in \
Options().get_option('forbidden_cflags'):
# Prepend pc_sysrootdir if necessary
pc_sysrootdir = global_variables['pc_sysrootdir']
pc_sysrootdir = global_variables.get('pc_sysrootdir', None)
if pc_sysrootdir:
# Strip the leading slashes from the flag path
# because os.path.join() will ignore
Expand Down Expand Up @@ -243,7 +243,7 @@ def _parse_libs(self, value, global_variables, dest=''):
if lib[2:] not in \
Options().get_option('forbidden_libdirs'):
# Prepend pc_sysrootdir if necessary
pc_sysrootdir = global_variables['pc_sysrootdir']
pc_sysrootdir = global_variables.get('pc_sysrootdir', None)
if pc_sysrootdir:
# Strip the leading slashes from the flag path
# because os.path.join() will ignore
Expand Down
107 changes: 107 additions & 0 deletions pykg_config/pkgconfig.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# Copyright (c) 2009-2012, Geoffrey Biggs
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of the Geoffrey Biggs nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

# File: pkgconfig.py
# Author: KOLANICH
# Part of pykg-config.

"""Used to extract some required info (such as compiled-in paths) from real pkg-config installed in a system.
"""

__version__ = "$Revision: $"
# $Source$

import os
import re
import subprocess
import sys
from shutil import which

pykg_config_package_name = "pykg_config"

defaultImplsList = ["pkgconf", "pkg-config"]

def discover_pkg_config_impl(path=None, impls=None):
if impls is None:
impls = defaultImplsList

for impl in impls:
res = which(impl, path=path)
if res:
return res
raise FileNotFoundError("No pkg-config impl is installed in your system")


discovered_pkg_config_command = None

def _get_pkg_config_impl():
global discovered_pkg_config_command
if discovered_pkg_config_command is None:
discovered_pkg_config_command = discover_pkg_config_impl()
return discovered_pkg_config_command

class Env:
__slots__ = ("patch", "backup")
def __init__(self, **kwargs):
self.patch = kwargs
self.backup = None
def __enter__(self):
self.backup = os.environ.copy()
os.environ.update(self.patch)
return self
def __exit__(self, exc_type, exc_value, traceback):
os.environ = self.backup

def _call_process(args):
process = subprocess.Popen(
args, stdout=subprocess.PIPE, stderr=subprocess.PIPE
)
output = process.communicate()
output = (
output[0].strip().decode("utf-8"),
output[1].strip().decode("utf-8"),
)
return_code = process.returncode
return output[0], output[1], return_code

def call_process(args, **env):
if env:
with Env(**env):
return _call_process(args)
else:
return _call_process(args)

def call_pkgconfig(*args, **env):
return call_process((_get_pkg_config_impl(),) + args, **env)

def call_pykgconfig(*args, **env):
return call_process(
(sys.executable, "-m", pykg_config_package_name) + args, **env
)


# vim: tw=79
24 changes: 9 additions & 15 deletions test/test_compatibility.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,18 @@
import subprocess
import sys
import unittest
import os

from pykg_config.pkgconfig import call_pykgconfig, call_pkgconfig


class TestCompatibility(unittest.TestCase):
def setUp(self):
self.packages = [('dbus-1', '1.4.16'),
('openssl', '1.0.0g'),
('libxml-2.0', '2.7.8'),
self.packages = [('dbus-1', '1.12.20'),
('openssl', '1.1.1f'),
('libxml-2.0', '2.9.10'),
('QtCore', '4.7.4')]
self.error_package = 'thisisabadpkg'
self.pykg_config_command = '../pykg-config.py'
self.pkg_config_command = 'pkg-config'

def get_random_package(self):
return random.choice(self.packages)[0]
Expand All @@ -76,17 +78,9 @@ def get_random_package_with_decremented_version(self):
version = [version[0], str(int(version[1]) - 1)] + version[2:]
return (pkg[0], '.'.join(version))

def call_process(self, args):
process = subprocess.Popen(args, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
output = process.communicate()
output = (output[0].strip(), output[1].strip())
return_code = process.returncode
return output[0], output[1], return_code

def run_test_case(self, args):
lhs_result = self.call_process([self.pykg_config_command] + args)
rhs_result = self.call_process([self.pkg_config_command] + args)
lhs_result = call_pykgconfig(*args, PYTHONPATH="../")
rhs_result = call_pkgconfig(*args)
return lhs_result, rhs_result

def build_error_msg(self, args, lhs, rhs):
Expand Down
59 changes: 21 additions & 38 deletions test/test_unittests.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,7 @@
from pykg_config import substitute
from pykg_config import dependency
from pykg_config import version


def call_process(args):
env = os.environ
env['PKG_CONFIG_PATH'] = '{0}:{1}'.format(os.getcwd(),
env['PKG_CONFIG_PATH'])
process = subprocess.Popen(args, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
output = process.communicate()
output = (output[0].strip(), output[1].strip())
return_code = process.returncode
return output[0], output[1], return_code
from pykg_config.pkgconfig import call_pykgconfig


class TestVersion(unittest.TestCase):
Expand All @@ -72,22 +61,22 @@ def test_comparisons(self):
versions = []
for verstring in self.strings:
versions.append(version.Version(verstring))
self.assert_(versions[0] < versions[1])
self.assert_(versions[0] < versions[5])
self.assert_(versions[0] < versions[6])
self.assert_(versions[0] <= versions[0])
self.assert_(versions[0] <= versions[1])
self.assert_(versions[0] <= versions[4])
self.assert_(versions[0] == versions[0])
self.assert_(versions[0] == versions[4])
self.assert_(versions[1] == versions[1])
self.assert_(versions[0] != versions[1])
self.assert_(versions[0] != versions[2])
self.assert_(versions[0] != versions[3])
self.assert_(versions[0] > versions[2])
self.assert_(versions[0] >= versions[0])
self.assert_(versions[0] >= versions[2])
self.assert_(versions[0] >= versions[4])
self.assertTrue(versions[0] < versions[1])
self.assertTrue(versions[0] < versions[5])
self.assertTrue(versions[0] < versions[6])
self.assertTrue(versions[0] <= versions[0])
self.assertTrue(versions[0] <= versions[1])
self.assertTrue(versions[0] <= versions[4])
self.assertTrue(versions[0] == versions[0])
self.assertTrue(versions[0] == versions[4])
self.assertTrue(versions[1] == versions[1])
self.assertTrue(versions[0] != versions[1])
self.assertTrue(versions[0] != versions[2])
self.assertTrue(versions[0] != versions[3])
self.assertTrue(versions[0] > versions[2])
self.assertTrue(versions[0] >= versions[0])
self.assertTrue(versions[0] >= versions[2])
self.assertTrue(versions[0] >= versions[4])

self.assertFalse(versions[0] < versions[2])
self.assertFalse(versions[0] <= versions[2])
Expand Down Expand Up @@ -119,7 +108,6 @@ def test_parse_package_spec_list(self):

class TestSubstitutions(unittest.TestCase):
def setUp(self):
self.pykg_config_cmd = '../pykg-config.py'
self.vars = {'blag1': 'not recursive',
'blag2': 'references ${blag1} variable',
'blag3': 'recursive with ${blag3}'}
Expand All @@ -136,32 +124,27 @@ def test_substitute(self):

def test_get_to_replace_re(self):
self.assertEqual(substitute.get_to_replace_re('blag'),
re.compile ('(?<!\$)\$\{blag\}', re.U))
re.compile ('(?<!\\$)\\$\\{blag\\}', re.U))

def test_get_all_substitutions(self):
nameful = '${lots} of ${names} ${reffed}.'
self.assertEqual(substitute.get_all_substitutions(nameful),
['lots', 'names', 'reffed'])

def test_undefined_var(self):
args = ['--cflags', 'global_var']
stdout, stderr, ret_code = call_process([self.pykg_config_cmd] + args)
stdout, stderr, ret_code = call_pykgconfig('--cflags', 'global_var')
self.assertEqual(ret_code, 1)

def test_global_var(self):
args = ['--cflags', 'global_var', '--define-variable=global_var=blurg']
stdout, stderr, ret_code = call_process([self.pykg_config_cmd] + args)
stdout, stderr, ret_code = call_pykgconfig('--cflags', 'global_var', '--define-variable=global_var=blurg')
self.assertEqual(stdout, '-Iblurg')
self.assertEqual(ret_code, 0)


class TestQuoteEscapes(unittest.TestCase):
def setUp(self):
self.pykg_config_cmd = '../pykg-config.py'

def test_maintain_escaping(self):
args = ['--cflags', 'unittests1']
stdout, stderr, ret_code = call_process([self.pykg_config_cmd] + args)
stdout, stderr, ret_code = call_pykgconfig('--cflags', 'unittests1')
self.assertEqual(stdout, r'-DPATH=\"/opt/shaders/\"')
self.assertEqual(ret_code, 0)

Expand Down

0 comments on commit af8e698

Please sign in to comment.