sapling/eden/integration/info_test.py

60 lines
1.9 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
# Copyright (c) Facebook, Inc. and its affiliates.
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2.
import json
import os
from .lib import testcase
@testcase.eden_repo_test
class InfoTest(testcase.EdenRepoTest):
def populate_repo(self) -> None:
self.repo.write_file("hello", "hola\n")
self.repo.commit("Initial commit.")
def test_relative_path(self) -> None:
"""
Test calling "eden info <relative_path>" and make sure it gives
the expected results.
"""
info = self.eden.run_cmd("info", os.path.relpath(self.mount))
client_info = json.loads(info)
client_dir = os.path.join(
self.eden_dir, "clients", os.path.basename(self.mount)
Change the contents and format for the edenrc file under ~/local/.eden. Summary: The headline changes of this revision are: - Changes the format of the config file from INI to TOML (the `edenrc` file under `~/local/.eden` has been replaced with `config.toml`). This revision includes logic for automatically performing the migration when Eden is restarted. - Inlines data from `/etc/eden/config.d` into the TOML file. Historically, the `edenrc` file for a client would contain the name of the "configuration alias" defined in a config file like `~/.edenrc` or `/etc/eden/config.d/00-defaults`. When Eden loaded a client, it would have to first read the `edenrc` and then reconstitute the rest of the client configuration by looking up the alias in the set of config files that were used to create the client in the first place. This changes things so that all of the data that was being cross-referenced is now inlined in the client's config file. This makes loading a config considerably simpler at the cost of no longer being able to change the config for multiple clients that were cloned from the same configuration alias in one place. It was questionable whether being able to modify a client from a foreign config after it was created was a safe thing to do, anyway. Eliminating the need for a historic link to the configuration alias will make it easier to support running `eden clone` on an arbitrary local Hg or Git repo. So long as `eden clone` can extract enough information from the local repo to create an appropriate config file for the new Eden client, there is no need for a configuration alias to exist a priori. Since we were already changing the data in the config file, this seemed like an appropriate time to make the switch from INI to TOML, as this was something we wanted to do, anyway. In testing, I discovered a discrepancy between how boost's `boost::property_tree::ptree` and Python's `ConfigParser` handled the following section heading: ``` [repository ZtmpZsillyZeden-clone.LIkh32] ``` Apparently `hasSection("repository ZtmpZsillyZeden-clone.LIkh32")` in boost would fail to find this section. Because [[https://stackoverflow.com/questions/13109506/are-hyphens-allowed-in-section-definitions-in-ini-files | there is no spec for INI]], it is not that surprising that boost and `ConfigParser` do not 100% agree on what they accept. Moving to TOML means we have a configuration language with the following desirable properties: - It has a formal spec, unlike INI. This is important because there are parsers in a wide range of programming languages that, in theory, accept a consistent input language. - It is reasonable for humans to write, as it supports comments, unlike JSON. - It supports nested structures, like maps and arrays, without going crazy on the input language it supports, unlike YAML. Eden now depends on the following third-party TOML parsers: * C++ https://github.com/skystrife/cpptoml * Python https://github.com/uiri/toml This revision also changes the organization of `~/local/.eden` slightly. For now, there is still a `config.json` file, but the values are no longer hashes of the realpath of the mount. Instead, we take the basename of the realpath and use that as the name of the directory under `~/local/.eden/clients`. If there is a naming collision, we add the first available integral suffix. Using the basename makes it easier to navigate the `~/local/.eden/clients` directory. Although the `edenrc` file under `~/local/.eden/clients` has been switched from INI to TOML, the other Eden config files (`~/.edenrc` and `/etc/eden/config.d/*`) still use INI. Migrating those to TOML will be done in a future revision. Note this revision allowed us to eliminate `facebook::eden::InterpolatedPropertyTree` as well as a number of uses of boost due to the elimination of `ClientConfig::loadConfigData()` in the C++ code. Because `ClientConfig` no longer does interpolation, a bit of `ClientConfigTest` was deleted as part of this revision because it is no longer relevant. Reviewed By: wez Differential Revision: D6310325 fbshipit-source-id: 2548149c064cdf8e78a3b3ce6fe667ff70f94f84
2017-11-17 00:19:54 +03:00
)
self.assertEqual(
{
"state_dir": client_dir,
"scm_type": self.repo.get_type(),
"mount": self.mount,
"snapshot": self.repo.get_head_hash(),
},
client_info,
Change the contents and format for the edenrc file under ~/local/.eden. Summary: The headline changes of this revision are: - Changes the format of the config file from INI to TOML (the `edenrc` file under `~/local/.eden` has been replaced with `config.toml`). This revision includes logic for automatically performing the migration when Eden is restarted. - Inlines data from `/etc/eden/config.d` into the TOML file. Historically, the `edenrc` file for a client would contain the name of the "configuration alias" defined in a config file like `~/.edenrc` or `/etc/eden/config.d/00-defaults`. When Eden loaded a client, it would have to first read the `edenrc` and then reconstitute the rest of the client configuration by looking up the alias in the set of config files that were used to create the client in the first place. This changes things so that all of the data that was being cross-referenced is now inlined in the client's config file. This makes loading a config considerably simpler at the cost of no longer being able to change the config for multiple clients that were cloned from the same configuration alias in one place. It was questionable whether being able to modify a client from a foreign config after it was created was a safe thing to do, anyway. Eliminating the need for a historic link to the configuration alias will make it easier to support running `eden clone` on an arbitrary local Hg or Git repo. So long as `eden clone` can extract enough information from the local repo to create an appropriate config file for the new Eden client, there is no need for a configuration alias to exist a priori. Since we were already changing the data in the config file, this seemed like an appropriate time to make the switch from INI to TOML, as this was something we wanted to do, anyway. In testing, I discovered a discrepancy between how boost's `boost::property_tree::ptree` and Python's `ConfigParser` handled the following section heading: ``` [repository ZtmpZsillyZeden-clone.LIkh32] ``` Apparently `hasSection("repository ZtmpZsillyZeden-clone.LIkh32")` in boost would fail to find this section. Because [[https://stackoverflow.com/questions/13109506/are-hyphens-allowed-in-section-definitions-in-ini-files | there is no spec for INI]], it is not that surprising that boost and `ConfigParser` do not 100% agree on what they accept. Moving to TOML means we have a configuration language with the following desirable properties: - It has a formal spec, unlike INI. This is important because there are parsers in a wide range of programming languages that, in theory, accept a consistent input language. - It is reasonable for humans to write, as it supports comments, unlike JSON. - It supports nested structures, like maps and arrays, without going crazy on the input language it supports, unlike YAML. Eden now depends on the following third-party TOML parsers: * C++ https://github.com/skystrife/cpptoml * Python https://github.com/uiri/toml This revision also changes the organization of `~/local/.eden` slightly. For now, there is still a `config.json` file, but the values are no longer hashes of the realpath of the mount. Instead, we take the basename of the realpath and use that as the name of the directory under `~/local/.eden/clients`. If there is a naming collision, we add the first available integral suffix. Using the basename makes it easier to navigate the `~/local/.eden/clients` directory. Although the `edenrc` file under `~/local/.eden/clients` has been switched from INI to TOML, the other Eden config files (`~/.edenrc` and `/etc/eden/config.d/*`) still use INI. Migrating those to TOML will be done in a future revision. Note this revision allowed us to eliminate `facebook::eden::InterpolatedPropertyTree` as well as a number of uses of boost due to the elimination of `ClientConfig::loadConfigData()` in the C++ code. Because `ClientConfig` no longer does interpolation, a bit of `ClientConfigTest` was deleted as part of this revision because it is no longer relevant. Reviewed By: wez Differential Revision: D6310325 fbshipit-source-id: 2548149c064cdf8e78a3b3ce6fe667ff70f94f84
2017-11-17 00:19:54 +03:00
)
def test_through_symlink(self) -> None:
"""
Test calling "eden info" through a symlink and make sure it gives
the expected results. This makes sure "eden info" resolves the path
correctly before looking it up in the configuration.
"""
link1 = os.path.join(self.tmp_dir, "link1")
os.symlink(self.mount, link1)
info1 = json.loads(self.eden.run_cmd("info", link1))
self.assertEqual(self.mount, info1["mount"])
# Create a non-normalized symlink pointing to the parent directory
# of the mount
link2 = os.path.join(self.tmp_dir, "mounts_link")
os.symlink(self.mount + "//..", link2)
mount_through_link2 = os.path.join(link2, self.repo_name)
info2 = json.loads(self.eden.run_cmd("info", mount_through_link2))
self.assertEqual(self.mount, info2["mount"])