~ted/click/desktop-hook-ual

« back to all changes in this revision

Viewing changes to click/framework.py

  • Committer: Colin Watson
  • Date: 2014-05-08 13:06:40 UTC
  • mfrom: (418.2.2 mvo)
  • Revision ID: cjwatson@canonical.com-20140508130640-iw0q2r0h14brxbt9
mergeĀ lp:~mvo/click/multiple-frameworks

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2014 Canonical Ltd.
 
2
# Author: Michael Vogt <michael.vogt@canonical.com>
 
3
 
 
4
# This program is free software: you can redistribute it and/or modify
 
5
# it under the terms of the GNU General Public License as published by
 
6
# the Free Software Foundation; version 3 of the License.
 
7
#
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
15
 
 
16
"""Pure python click framework handling support."""
 
17
 
 
18
import logging
 
19
import os
 
20
import re
 
21
 
 
22
try:
 
23
    import apt_pkg
 
24
except:
 
25
    pass
 
26
 
 
27
 
 
28
class ClickFrameworkInvalid(Exception):
 
29
    pass
 
30
 
 
31
 
 
32
# FIXME: use native lib if available
 
33
#from gi.repository import Click
 
34
#click_framework_get_base_version = Click.framework_get_base_version
 
35
#click_framework_has_framework = Click.has_framework
 
36
 
 
37
 
 
38
# python version of the vala parse_deb822_file()
 
39
def parse_deb822_file(filename):
 
40
    data = {}
 
41
    with open(filename) as f:
 
42
        for line in f:
 
43
            line = line.strip()
 
44
            # from deb822.vala
 
45
            field_re_posix = r'^([^:[:space:]]+)[[:space:]]*:[[:space:]]'\
 
46
                       '([^[:space:]].*?)[[:space:]]*$'
 
47
            # python does not do posix char classes
 
48
            field_re = field_re_posix.replace("[:space:]", "\s")
 
49
            blank_re_posix = r'^[[:space:]]*$'
 
50
            blank_re = blank_re_posix.replace("[:space:]", "\s")
 
51
            if re.match(blank_re, line):
 
52
                break
 
53
            match = re.match(field_re, line)
 
54
            if match and match.group(1) and match.group(2):
 
55
                data[match.group(1).lower()] = match.group(2)
 
56
    return data
 
57
 
 
58
 
 
59
# python version of vala get_frameworks_dir
 
60
def get_frameworks_dir(framework_name):
 
61
    # FIXME: get via configure.in etc?
 
62
    frameworks_dir = os.environ.get(
 
63
        "CLICK_FRAMEWORKS_DIR", "/usr/share/click/frameworks")
 
64
    framework_path = os.path.join(
 
65
        frameworks_dir, framework_name+".framework")
 
66
    return framework_path
 
67
 
 
68
 
 
69
# python version of the vala click_framework_get_base_version()
 
70
def click_framework_get_base_version(framework_name):
 
71
    deb822 = parse_deb822_file(get_frameworks_dir(framework_name))
 
72
    return deb822.get("base-version", None)
 
73
 
 
74
 
 
75
# python version of the vala click_framework_has_framework
 
76
def click_framework_has_framework(framework_name):
 
77
    return os.path.exists(get_frameworks_dir(framework_name))
 
78
 
 
79
 
 
80
def validate_framework(framework_string, ignore_missing_frameworks=False):
 
81
    try:
 
82
        apt_pkg
 
83
    except NameError:
 
84
        logging.warning("No apt_pkg module, skipping validate_framework")
 
85
        return
 
86
 
 
87
    try:
 
88
        parsed_framework = apt_pkg.parse_depends(framework_string)
 
89
    except ValueError:
 
90
        raise ClickFrameworkInvalid(
 
91
            'Could not parse framework "%s"' % framework_string)
 
92
 
 
93
    framework_base_versions = set()
 
94
    missing_frameworks = []
 
95
    for or_dep in parsed_framework:
 
96
        if len(or_dep) > 1:
 
97
            raise ClickFrameworkInvalid(
 
98
                'Alternative dependencies in framework "%s" not yet '
 
99
                'allowed' % framework_string)
 
100
        if or_dep[0][1] or or_dep[0][2]:
 
101
            raise ClickFrameworkInvalid(
 
102
                'Version relationship in framework "%s" not yet allowed' %
 
103
                framework_string)
 
104
        # now verify that different base versions are not mixed
 
105
        framework_name = or_dep[0][0]
 
106
        if not click_framework_has_framework(framework_name):
 
107
            missing_frameworks.append(framework_name)
 
108
            continue
 
109
        framework_base_version = click_framework_get_base_version(
 
110
                framework_name)
 
111
        framework_base_versions.add(framework_base_version)
 
112
 
 
113
    if not ignore_missing_frameworks:
 
114
        if len(missing_frameworks) > 1:
 
115
            raise ClickFrameworkInvalid(
 
116
                'Frameworks %s not present on system (use '
 
117
                '--force-missing-framework option to override)' %
 
118
                ", ".join('"%s"' % f for f in missing_frameworks))
 
119
        elif missing_frameworks:
 
120
            raise ClickFrameworkInvalid(
 
121
                'Framework "%s" not present on system (use '
 
122
                '--force-missing-framework option to override)' %
 
123
                missing_frameworks[0])
 
124
    else:
 
125
        if len(missing_frameworks) > 1:
 
126
            logging.warning("Ignoring missing frameworks %s" % (
 
127
                ", ".join('"%s"' % f for f in missing_frameworks)))
 
128
        elif missing_frameworks:
 
129
            logging.warning('Ignoring missing framework "%s"' % (
 
130
                missing_frameworks[0]))
 
131
 
 
132
    if len(framework_base_versions) > 1:
 
133
        raise ClickFrameworkInvalid(
 
134
            'Multiple frameworks with different base versions are not '
 
135
            'allowed. Found: {0}'.format(framework_base_versions))