/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/config.py

  • Committer: INADA Naoki
  • Date: 2011-05-18 06:27:34 UTC
  • mfrom: (5887 +trunk)
  • mto: This revision was merged to the branch mainline in revision 5894.
  • Revision ID: songofacandy@gmail.com-20110518062734-1ilhll0rrqyyp8um
merge from lp:bzr and resolve conflicts.

Show diffs side-by-side

added added

removed removed

Lines of Context:
978
978
        number of path components in the section name, section is the section
979
979
        name and extra_path is the difference between location and the section
980
980
        name.
 
981
 
 
982
    ``location`` will always be a local path and never a 'file://' url but the
 
983
    section names themselves can be in either form.
981
984
    """
982
985
    location_parts = location.rstrip('/').split('/')
983
986
 
984
987
    for section in sections:
985
 
        # location is a local path if possible, so we need
986
 
        # to convert 'file://' urls to local paths if necessary.
987
 
 
988
 
        # FIXME: I don't think the above comment is still up to date,
989
 
        # LocationConfig is always instantiated with an url -- vila 2011-04-07
 
988
        # location is a local path if possible, so we need to convert 'file://'
 
989
        # urls in section names to local paths if necessary.
990
990
 
991
991
        # This also avoids having file:///path be a more exact
992
992
        # match than '/path'.
993
993
 
994
 
        # FIXME: Not sure about the above either, but since the path components
995
 
        # are compared in sync, adding two empty components (//) is likely to
996
 
        # trick the comparison and also trick the check on the number of
997
 
        # components, so we *should* take only the relevant part of the url. On
998
 
        # the other hand, this means 'file://' urls *can't* be used in sections
999
 
        # so more work is probably needed -- vila 2011-04-07
 
994
        # FIXME: This still raises an issue if a user defines both file:///path
 
995
        # *and* /path. Should we raise an error in this case -- vila 20110505
1000
996
 
1001
997
        if section.startswith('file://'):
1002
998
            section_path = urlutils.local_path_from_url(section)
2270
2266
        :returns: An iterable of (name, dict).
2271
2267
        """
2272
2268
        # We need a loaded store
2273
 
        self.load()
 
2269
        try:
 
2270
            self.load()
 
2271
        except errors.NoSuchFile:
 
2272
            # If the file doesn't exist, there is no sections
 
2273
            return
2274
2274
        cobj = self._config_obj
2275
2275
        if cobj.scalars:
2276
2276
            yield self.readonly_section_class(None, cobj)
2409
2409
 
2410
2410
    def __init__(self, store, location):
2411
2411
        super(LocationMatcher, self).__init__(store)
 
2412
        if location.startswith('file://'):
 
2413
            location = urlutils.local_path_from_url(location)
2412
2414
        self.location = location
2413
2415
 
2414
 
    def get_sections(self):
2415
 
        # Override the default implementation as we want to change the order
2416
 
 
2417
 
        # The following is a bit hackish but ensures compatibility with
2418
 
        # LocationConfig by reusing the same code
2419
 
        sections = list(self.store.get_sections())
 
2416
    def _get_matching_sections(self):
 
2417
        """Get all sections matching ``location``."""
 
2418
        # We slightly diverge from LocalConfig here by allowing the no-name
 
2419
        # section as the most generic one and the lower priority.
 
2420
        no_name_section = None
 
2421
        sections = []
 
2422
        # Filter out the no_name_section so _iter_for_location_by_parts can be
 
2423
        # used (it assumes all sections have a name).
 
2424
        for section in self.store.get_sections():
 
2425
            if section.id is None:
 
2426
                no_name_section = section
 
2427
            else:
 
2428
                sections.append(section)
 
2429
        # Unfortunately _iter_for_location_by_parts deals with section names so
 
2430
        # we have to resync.
2420
2431
        filtered_sections = _iter_for_location_by_parts(
2421
2432
            [s.id for s in sections], self.location)
2422
2433
        iter_sections = iter(sections)
2423
2434
        matching_sections = []
 
2435
        if no_name_section is not None:
 
2436
            matching_sections.append(
 
2437
                LocationSection(no_name_section, 0, self.location))
2424
2438
        for section_id, extra_path, length in filtered_sections:
2425
2439
            # a section id is unique for a given store so it's safe to iterate
2426
2440
            # again
2428
2442
            if section_id == section.id:
2429
2443
                matching_sections.append(
2430
2444
                    LocationSection(section, length, extra_path))
 
2445
        return matching_sections
 
2446
 
 
2447
    def get_sections(self):
 
2448
        # Override the default implementation as we want to change the order
 
2449
        matching_sections = self._get_matching_sections()
2431
2450
        # We want the longest (aka more specific) locations first
2432
2451
        sections = sorted(matching_sections,
2433
2452
                          key=lambda section: (section.length, section.id),
2476
2495
        """
2477
2496
        # FIXME: No caching of options nor sections yet -- vila 20110503
2478
2497
 
2479
 
        # Ensuring lazy loading is achieved by delaying section matching until
2480
 
        # it can be avoided anymore by using callables to describe (possibly
2481
 
        # empty) section lists.
 
2498
        # Ensuring lazy loading is achieved by delaying section matching (which
 
2499
        # implies querying the persistent storage) until it can't be avoided
 
2500
        # anymore by using callables to describe (possibly empty) section
 
2501
        # lists.
2482
2502
        for section_or_callable in self.sections_def:
2483
2503
            # Each section can expand to multiple ones when a callable is used
2484
2504
            if callable(section_or_callable):
2498
2518
        This is where we guarantee that the mutable section is lazily loaded:
2499
2519
        this means we won't load the corresponding store before setting a value
2500
2520
        or deleting an option. In practice the store will often be loaded but
2501
 
        this allows catching some programming errors.
 
2521
        this allows helps catching some programming errors.
2502
2522
        """
2503
2523
        section = self.store.get_mutable_section(self.mutable_section_name)
2504
2524
        return section
2518
2538
        return "<config.%s(%s)>" % (self.__class__.__name__, id(self))
2519
2539
 
2520
2540
 
 
2541
class GlobalStack(Stack):
 
2542
 
 
2543
    def __init__(self):
 
2544
        # Get a GlobalStore
 
2545
        gstore = GlobalStore()
 
2546
        super(GlobalStack, self).__init__([gstore.get_sections], gstore)
 
2547
 
 
2548
 
 
2549
class LocationStack(Stack):
 
2550
 
 
2551
    def __init__(self, location):
 
2552
        lstore = LocationStore()
 
2553
        matcher = LocationMatcher(lstore, location)
 
2554
        gstore = GlobalStore()
 
2555
        super(LocationStack, self).__init__(
 
2556
            [matcher.get_sections, gstore.get_sections], lstore)
 
2557
 
 
2558
 
 
2559
class BranchStack(Stack):
 
2560
 
 
2561
    def __init__(self, branch):
 
2562
        bstore = BranchStore(branch)
 
2563
        lstore = LocationStore()
 
2564
        matcher = LocationMatcher(lstore, branch.base)
 
2565
        gstore = GlobalStore()
 
2566
        super(BranchStack, self).__init__(
 
2567
            [matcher.get_sections, bstore.get_sections, gstore.get_sections],
 
2568
            bstore)
 
2569
 
 
2570
 
2521
2571
class cmd_config(commands.Command):
2522
2572
    __doc__ = """Display, set or remove a configuration option.
2523
2573