Exemple #1
0
 def merging_dict_into_nondict_raises_error(self):
     # TODO: or...should it?! If a user really wants to take a pre-existing
     # config path and make it 'deeper' by overwriting e.g. a string with a
     # dict of strings (or whatever)...should they be allowed to?
     d1 = {'foo': 'bar'}
     d2 = {'foo': {'uh': 'oh'}}
     merge_dicts(d1, d2)
Exemple #2
0
 def merging_dict_into_nondict_raises_error(self):
     # TODO: or...should it?! If a user really wants to take a pre-existing
     # config path and make it 'deeper' by overwriting e.g. a string with a
     # dict of strings (or whatever)...should they be allowed to?
     d1 = {'foo': 'bar'}
     d2 = {'foo': {'uh': 'oh'}}
     merge_dicts(d1, d2)
 def merging_dict_into_nondict_raises_error(self):
     # TODO: or...should it?! If a user really wants to take a pre-existing
     # config path and make it 'deeper' by overwriting e.g. a string with a
     # dict of strings (or whatever)...should they be allowed to?
     d1 = {"foo": "bar"}
     d2 = {"foo": {"uh": "oh"}}
     with raises(AmbiguousMergeError):
         merge_dicts(d1, d2)
Exemple #4
0
 def global_defaults():
     defaults = FabConfig.global_defaults()
     ours = {
         'platform': 'Win64',
         'configuration': 'DevelopmentEditor',
         'type': 'Editor',
     }
     merge_dicts(defaults, ours)
     return defaults
 def mixed_branch_levels_merges_ok(self):
     d1 = {"foo": {"bar": {"biz": "baz"}}, "meh": 17, "myown": "ok"}
     d2 = {"foo": {"bar": {"biz": "notbaz"}}, "meh": 25}
     merge_dicts(d1, d2)
     expected = {
         "foo": {"bar": {"biz": "notbaz"}},
         "meh": 25,
         "myown": "ok",
     }
     assert d1 == expected
Exemple #6
0
 def mixed_branch_levels_merges_ok(self):
     d1 = {'foo': {'bar': {'biz': 'baz'}}, 'meh': 17, 'myown': 'ok'}
     d2 = {'foo': {'bar': {'biz': 'notbaz'}}, 'meh': 25}
     merge_dicts(d1, d2)
     expected = {
         'foo': {'bar': {'biz': 'notbaz'}},
         'meh': 25,
         'myown': 'ok',
     }
     assert d1 == expected
Exemple #7
0
 def global_defaults():
     defaults = FabConfig.global_defaults()
     ours = {
         'tasks': {
             'search_root': 'fub',
             'collection_name': 'tasks',
         },
     }
     merge_dicts(defaults, ours)
     return defaults
Exemple #8
0
    def global_defaults():
        """
        Default configuration values and behavior toggles.

        Fabric only extends this method in order to make minor adjustments and
        additions to Invoke's `~invoke.config.Config.global_defaults`; see its
        documentation for the base values, such as the config subtrees
        controlling behavior of ``run`` or how ``tasks`` behave.

        For Fabric-specific modifications and additions to the Invoke-level
        defaults, see our own config docs at :ref:`default-values`.

        .. versionadded:: 2.0
        """
        # TODO: hrm should the run-related things actually be derived from the
        # runner_class? E.g. Local defines local stuff, Remote defines remote
        # stuff? Doesn't help with the final config tree tho...
        # TODO: as to that, this is a core problem, Fabric wants split
        # local/remote stuff, eg replace_env wants to be False for local and
        # True remotely; shell wants to differ depending on target (and either
        # way, does not want to use local interrogation for remote)
        # TODO: is it worth moving all of our 'new' settings to a discrete
        # namespace for cleanliness' sake? e.g. ssh.port, ssh.user etc.
        # It wouldn't actually simplify this code any, but it would make it
        # easier for users to determine what came from which library/repo.
        defaults = InvokeConfig.global_defaults()
        ours = {
            # New settings
            "connect_kwargs": {},
            "forward_agent": False,
            "gateway": None,
            # TODO 3.0: change to True and update all docs accordingly.
            "inline_ssh_env": False,
            "load_ssh_configs": True,
            "port": 22,
            "run": {
                "replace_env": True
            },
            "runners": {
                "remote": Remote
            },
            "ssh_config_path": None,
            "tasks": {
                "collection_name": "fabfile"
            },
            # TODO: this becomes an override/extend once Invoke grows execution
            # timeouts (which should be timeouts.execute)
            "timeouts": {
                "connect": None
            },
            "user": get_local_user(),
        }
        merge_dicts(defaults, ours)
        return defaults
Exemple #9
0
    def global_defaults():
        """
        Default configuration values and behavior toggles.

        Fabric only extends this method in order to make minor adjustments and
        additions to Invoke's `~invoke.config.Config.global_defaults`; see its
        documentation for the base values, such as the config subtrees
        controlling behavior of ``run`` or how ``tasks`` behave.

        For Fabric-specific modifications and additions to the Invoke-level
        defaults, see our own config docs at :ref:`default-values`.

        .. versionadded:: 2.0
        """
        # TODO: hrm should the run-related things actually be derived from the
        # runner_class? E.g. Local defines local stuff, Remote defines remote
        # stuff? Doesn't help with the final config tree tho...
        # TODO: as to that, this is a core problem, Fabric wants split
        # local/remote stuff, eg replace_env wants to be False for local and
        # True remotely; shell wants to differ depending on target (and either
        # way, does not want to use local interrogation for remote)
        # TODO: is it worth moving all of our 'new' settings to a discrete
        # namespace for cleanliness' sake? e.g. ssh.port, ssh.user etc.
        # It wouldn't actually simplify this code any, but it would make it
        # easier for users to determine what came from which library/repo.
        defaults = InvokeConfig.global_defaults()
        ours = {
            # New settings
            'connect_kwargs': {},
            'forward_agent': False,
            'gateway': None,
            'load_ssh_configs': True,
            'port': 22,
            'run': {
                'replace_env': True,
            },
            'runners': {
                'remote': Remote,
            },
            'ssh_config_path': None,
            'tasks': {
                'collection_name': 'fabfile',
            },
            # TODO: this becomes an override/extend once Invoke grows execution
            # timeouts (which should be timeouts.execute)
            'timeouts': {
                'connect': None,
            },
            'user': get_local_user(),
        }
        merge_dicts(defaults, ours)
        return defaults
Exemple #10
0
 def mixed_branch_levels_merges_ok(self):
     d1 = {'foo': {'bar': {'biz': 'baz'}}, 'meh': 17, 'myown': 'ok'}
     d2 = {'foo': {'bar': {'biz': 'notbaz'}}, 'meh': 25}
     merge_dicts(d1, d2)
     expected = {
         'foo': {
             'bar': {
                 'biz': 'notbaz'
             }
         },
         'meh': 25,
         'myown': 'ok',
     }
     assert d1 == expected
Exemple #11
0
 def global_defaults():
     their_defaults = Config.global_defaults()
     my_defaults = {
         "run": {
             # "config": "cmake_build.yaml",
             "echo": True,
         },
     }
     return merge_dicts(their_defaults, my_defaults)
Exemple #12
0
 def global_defaults():
     base_defaults = Config.global_defaults()
     overrides = {
         "tasks": {"collection_name": PROG_NAME},
         "run": {
             "shell": "C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
             "echo": True,
             "debug": True,
         },
     }
     return merge_dicts(base=base_defaults, updates=overrides)
Exemple #13
0
 def dict_value_merges_are_not_references(self):
     core = {}
     coll = {'foo': {'bar': {'biz': 'coll value'}}}
     proj = {'foo': {'bar': {'biz': 'proj value'}}}
     # Initial merge - when bug present, this sets core['foo'] to the entire
     # 'foo' dict in 'proj' as a reference - meaning it 'links' back to the
     # 'proj' dict whenever other things are merged into it
     merge_dicts(core, proj)
     eq_(core, {'foo': {'bar': {'biz': 'proj value'}}})
     eq_(proj['foo']['bar']['biz'], 'proj value')
     # Identity tests can also prove the bug early
     ok_(core['foo'] is not proj['foo'], "Core foo is literally proj foo!")
     # Subsequent merge - just overwrites leaf values this time (thus no
     # real change, but this is what real config merge code does, so why
     # not)
     merge_dicts(core, proj)
     eq_(core, {'foo': {'bar': {'biz': 'proj value'}}})
     eq_(proj['foo']['bar']['biz'], 'proj value')
     # The problem merge - when bug present, core['foo'] references 'foo'
     # inside 'proj', so this ends up tweaking "core" but it actually
     # affects "proj" as well!
     merge_dicts(core, coll)
     # Expect that the core dict got the update from 'coll'...
     eq_(core, {'foo': {'bar': {'biz': 'coll value'}}})
     # BUT that 'proj' remains UNTOUCHED
     eq_(proj['foo']['bar']['biz'], 'proj value')
 def dict_value_merges_are_not_references(self):
     core = {}
     coll = {"foo": {"bar": {"biz": "coll value"}}}
     proj = {"foo": {"bar": {"biz": "proj value"}}}
     # Initial merge - when bug present, this sets core['foo'] to the entire
     # 'foo' dict in 'proj' as a reference - meaning it 'links' back to the
     # 'proj' dict whenever other things are merged into it
     merge_dicts(core, proj)
     assert core == {"foo": {"bar": {"biz": "proj value"}}}
     assert proj["foo"]["bar"]["biz"] == "proj value"
     # Identity tests can also prove the bug early
     assert (
         core["foo"] is not proj["foo"]
     ), "Core foo is literally proj foo!"  # noqa
     # Subsequent merge - just overwrites leaf values this time (thus no
     # real change, but this is what real config merge code does, so why
     # not)
     merge_dicts(core, proj)
     assert core == {"foo": {"bar": {"biz": "proj value"}}}
     assert proj["foo"]["bar"]["biz"] == "proj value"
     # The problem merge - when bug present, core['foo'] references 'foo'
     # inside 'proj', so this ends up tweaking "core" but it actually
     # affects "proj" as well!
     merge_dicts(core, coll)
     # Expect that the core dict got the update from 'coll'...
     assert core == {"foo": {"bar": {"biz": "coll value"}}}
     # BUT that 'proj' remains UNTOUCHED
     assert proj["foo"]["bar"]["biz"] == "proj value"
Exemple #15
0
 def dict_value_merges_are_not_references(self):
     core = {}
     coll = {'foo': {'bar': {'biz': 'coll value'}}}
     proj = {'foo': {'bar': {'biz': 'proj value'}}}
     # Initial merge - when bug present, this sets core['foo'] to the entire
     # 'foo' dict in 'proj' as a reference - meaning it 'links' back to the
     # 'proj' dict whenever other things are merged into it
     merge_dicts(core, proj)
     eq_(core, {'foo': {'bar': {'biz': 'proj value'}}})
     eq_(proj['foo']['bar']['biz'], 'proj value')
     # Identity tests can also prove the bug early
     ok_(core['foo'] is not proj['foo'], "Core foo is literally proj foo!")
     # Subsequent merge - just overwrites leaf values this time (thus no
     # real change, but this is what real config merge code does, so why
     # not)
     merge_dicts(core, proj)
     eq_(core, {'foo': {'bar': {'biz': 'proj value'}}})
     eq_(proj['foo']['bar']['biz'], 'proj value')
     # The problem merge - when bug present, core['foo'] references 'foo'
     # inside 'proj', so this ends up tweaking "core" but it actually
     # affects "proj" as well!
     merge_dicts(core, coll)
     # Expect that the core dict got the update from 'coll'...
     eq_(core, {'foo': {'bar': {'biz': 'coll value'}}})
     # BUT that 'proj' remains UNTOUCHED
     eq_(proj['foo']['bar']['biz'], 'proj value')
Exemple #16
0
    def global_defaults() -> dict:
        """Set the global default configuration, before loading any other config."""
        defaults = Config.global_defaults()

        # Load default configuration
        with open_text('roberto', 'default_config.yaml') as f:
            defaults = merge_dicts(defaults, yaml.safe_load(f))

        # Git version and branch information
        try:
            git_describe = subprocess.run(['git', 'describe', '--tags'],
                                          stdout=subprocess.PIPE,
                                          stderr=subprocess.DEVNULL,
                                          check=True).stdout.decode('utf-8')
        except subprocess.CalledProcessError:
            # May fail, e.g. when there are no tags.
            git_describe = '0.0.0-0-notag'
        defaults['git'].update(parse_git_describe(git_describe))

        # First try to get a decent branch name
        branch = subprocess.run(["git", "rev-parse", "--abbrev-ref", "HEAD"],
                                stdout=subprocess.PIPE,
                                stderr=subprocess.DEVNULL,
                                check=True).stdout.decode('utf-8').strip()
        # If that failed, try to get the tag
        if branch == 'HEAD':
            try:
                branch = subprocess.run(
                    ["git", "describe", "--tags", "--exact-match"],
                    stdout=subprocess.PIPE,
                    stderr=subprocess.DEVNULL,
                    check=True).stdout.decode('utf-8').strip()
            except subprocess.CalledProcessError:
                # Final attempt, just the sha.
                try:
                    branch = subprocess.run(
                        ["git", "rev-parse", "HEAD"],
                        stdout=subprocess.PIPE,
                        stderr=subprocess.DEVNULL,
                        check=True).stdout.decode('utf-8').strip()
                except subprocess.CalledProcessError:
                    branch = '__nogit__'
        defaults['git']['branch'] = branch

        return defaults
Exemple #17
0
 def global_defaults():
     hkn_defaults = {
         'deploy': {
             'name': 'default',
             'host': 'apphost.ocf.berkeley.edu',
             'path': {
                 'root': '/home/h/hk/hkn/hknweb',
                 'repo': 'repo',
                 'releases': 'releases',
                 'current': 'current',
                 'shared': 'shared',
             },
             'repo_url': 'https://github.com/compserv/hknweb.git',
             'branch': 'master',
             'linked_files': [],
             'linked_dirs': [],
             'keep_releases': 10,
         },
     }
     return merge_dicts(Config.global_defaults(), hkn_defaults)
Exemple #18
0
 def global_defaults():
     hkn_defaults = {
         "deploy": {
             "name": "default",
             "user": "******",
             "host": "apphost.ocf.berkeley.edu",
             "path": {
                 "root": "/home/h/hk/hkn/hknweb",
                 "repo": "repo",
                 "releases": "releases",
                 "current": "current",
                 "shared": "shared",
             },
             "repo_url": "https://github.com/compserv/hknweb.git",
             "branch": "master",
             "linked_files": [],
             "linked_dirs": [],
             "keep_releases": 10,
         },
     }
     return merge_dicts(Config.global_defaults(), hkn_defaults)
 def updating_with_None_acts_like_merging_empty_dict(self):
     # When bug present, AttributeError is raised on a None.items()
     d1 = {"my": "data"}
     d2 = None
     merge_dicts(d1, d2)
     assert d1 == {"my": "data"}
 def merge_file_types_by_reference(self):
     d1 = {}
     d2 = {"foo": open(__file__)}
     merge_dicts(d1, d2)
     assert d1["foo"].closed is False
Exemple #21
0
 def nested_leaf_values_merge_ok(self):
     d1 = {'foo': {'bar': {'biz': 'baz'}}}
     d2 = {'foo': {'bar': {'biz': 'notbaz'}}}
     merge_dicts(d1, d2)
     eq_(d1, {'foo': {'bar': {'biz': 'notbaz'}}})
Exemple #22
0
 def orthogonal_data_merges(self):
     d1 = {'foo': 'bar'}
     d2 = {'biz': 'baz'}
     merge_dicts(d1, d2)
     eq_(d1, {'foo': 'bar', 'biz': 'baz'})
 def non_dict_type_mismatch_overwrites_ok(self):
     d1 = {"foo": "bar"}
     d2 = {"foo": [1, 2, 3]}
     merge_dicts(d1, d2)
     assert d1 == {"foo": [1, 2, 3]}
 def merging_nondict_into_dict_raises_error(self):
     d1 = {"foo": {"uh": "oh"}}
     d2 = {"foo": "bar"}
     with raises(AmbiguousMergeError):
         merge_dicts(d1, d2)
Exemple #25
0
 def merging_nondict_into_dict_raises_error(self):
     d1 = {'foo': {'uh': 'oh'}}
     d2 = {'foo': 'bar'}
     merge_dicts(d1, d2)
Exemple #26
0
 def nested_leaf_values_merge_ok(self):
     d1 = {'foo': {'bar': {'biz': 'baz'}}}
     d2 = {'foo': {'bar': {'biz': 'notbaz'}}}
     merge_dicts(d1, d2)
     eq_(d1, {'foo': {'bar': {'biz': 'notbaz'}}})
Exemple #27
0
 def updates_arg_values_win(self):
     d1 = {'foo': 'bar'}
     d2 = {'foo': 'notbar'}
     merge_dicts(d1, d2)
     eq_(d1, {'foo': 'notbar'})
Exemple #28
0
 def non_dict_type_mismatch_overwrites_ok(self):
     d1 = {'foo': 'bar'}
     d2 = {'foo': [1, 2, 3]}
     merge_dicts(d1, d2)
     eq_(d1, {'foo': [1, 2, 3]})
Exemple #29
0
 def merging_nondict_into_dict_raises_error(self):
     d1 = {'foo': {'uh': 'oh'}}
     d2 = {'foo': 'bar'}
     with raises(AmbiguousMergeError):
         merge_dicts(d1, d2)
Exemple #30
0
 def merging_data_onto_empty_dict(self):
     d1 = {}
     d2 = {'foo': 'bar'}
     merge_dicts(d1, d2)
     eq_(d1, d2)
Exemple #31
0
 def merge_file_types_by_reference(self):
     d1 = {}
     d2 = {'foo': open(__file__)}
     merge_dicts(d1, d2)
     eq_(d1['foo'].closed, False)
 def orthogonal_data_merges(self):
     d1 = {"foo": "bar"}
     d2 = {"biz": "baz"}
     merge_dicts(d1, d2)
     assert d1 == {"foo": "bar", "biz": "baz"}
Exemple #33
0
 def mixed_branch_levels_merges_ok(self):
     d1 = {'foo': {'bar': {'biz': 'baz'}}, 'meh': 17, 'myown': 'ok'}
     d2 = {'foo': {'bar': {'biz': 'notbaz'}}, 'meh': 25}
     merge_dicts(d1, d2)
     eq_(d1, {'foo': {'bar': {'biz': 'notbaz'}}, 'meh': 25, 'myown': 'ok'})
 def updates_arg_values_win(self):
     d1 = {"foo": "bar"}
     d2 = {"foo": "notbar"}
     merge_dicts(d1, d2)
     assert d1 == {"foo": "notbar"}
Exemple #35
0
 def merging_nondict_into_dict_raises_error(self):
     d1 = {'foo': {'uh': 'oh'}}
     d2 = {'foo': 'bar'}
     merge_dicts(d1, d2)
Exemple #36
0
 def updates_arg_values_win(self):
     d1 = {'foo': 'bar'}
     d2 = {'foo': 'notbar'}
     merge_dicts(d1, d2)
     eq_(d1, {'foo': 'notbar'})
Exemple #37
0
 def merging_data_onto_empty_dict(self):
     d1 = {}
     d2 = {'foo': 'bar'}
     merge_dicts(d1, d2)
     eq_(d1, d2)
 def nested_leaf_values_merge_ok(self):
     d1 = {"foo": {"bar": {"biz": "baz"}}}
     d2 = {"foo": {"bar": {"biz": "notbaz"}}}
     merge_dicts(d1, d2)
     assert d1 == {"foo": {"bar": {"biz": "notbaz"}}}
Exemple #39
0
 def non_dict_type_mismatch_overwrites_ok(self):
     d1 = {'foo': 'bar'}
     d2 = {'foo': [1, 2, 3]}
     merge_dicts(d1, d2)
     eq_(d1, {'foo': [1, 2, 3]})
Exemple #40
0
 def merging_nondict_into_dict_raises_error(self):
     d1 = {'foo': {'uh': 'oh'}}
     d2 = {'foo': 'bar'}
     with raises(AmbiguousMergeError):
         merge_dicts(d1, d2)
 def merging_data_onto_empty_dict(self):
     d1 = {}
     d2 = {"foo": "bar"}
     merge_dicts(d1, d2)
     assert d1 == d2
Exemple #42
0
 def orthogonal_data_merges(self):
     d1 = {'foo': 'bar'}
     d2 = {'biz': 'baz'}
     merge_dicts(d1, d2)
     eq_(d1, {'foo': 'bar', 'biz': 'baz'})
Exemple #43
0
 def mixed_branch_levels_merges_ok(self):
     d1 = {'foo': {'bar': {'biz': 'baz'}}, 'meh': 17, 'myown': 'ok'}
     d2 = {'foo': {'bar': {'biz': 'notbaz'}}, 'meh': 25}
     merge_dicts(d1, d2)
     eq_(d1, {'foo': {'bar': {'biz': 'notbaz'}}, 'meh': 25, 'myown': 'ok'})