sapling/eden/fs/config/CheckoutConfig.h
Xavier Deguillard 8853701e91 path: forbid building non-utf8 paths
Summary:
The world has moved on utf-8 as the default encoding for files and data, but
EdenFS still accepts non utf-8 filenames to be written to it. In fact, most of
the time when a non utf-8 file is written to the working copy, and even though
EdenFS handles it properly, Mercurial ends up freaking out and crash. In all of
these cases, non-utf8 files were not intentional, and thus refusing to create
them wouldn't be a loss of functionality.

Note that this diff makes the asumption that Mercurial's manifest only accept
utf8 path, and thus we only have to protect against files being created in the
working copy that aren't utf8.

The unfortunate part of this diff is that it makes importing trees a bit more
expensive as testing that a path is utf8 valid is not free.

Reviewed By: chadaustin

Differential Revision: D25442975

fbshipit-source-id: 89341a004272736a61639751da43c2e9c673d5b3
2021-02-23 11:35:12 -08:00

145 lines
3.6 KiB
C++

/*
* 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.
*/
#pragma once
#include <folly/dynamic.h>
#include <optional>
#include "eden/fs/model/Hash.h"
#include "eden/fs/model/ParentCommits.h"
#include "eden/fs/utils/PathFuncs.h"
#ifdef _WIN32
#include "eden/fs/utils/Guid.h"
#endif
namespace facebook {
namespace eden {
enum class MountProtocol {
FUSE,
PRJFS,
NFS,
};
/**
* CheckoutConfig contains the configuration state for a single Eden checkout.
*
* This data is stored on disk in the file
* EDEN_DIR/clients/CHECKOUT_NAME/config.toml
*/
class CheckoutConfig {
public:
/**
* Manually construct a CheckoutConfig object.
*
* Note that most callers will probably want to use the
* loadFromClientDirectory() factory function to create a CheckoutConfig
* object from an existing client directory, rather than directly calling this
* constructor.
*/
CheckoutConfig(
AbsolutePathPiece mountPath,
AbsolutePathPiece clientDirectory);
/**
* Load a CheckoutConfig object from the edenrc file in a client directory.
*
* @param mountPath The path where the client is (or will be) mounted.
* @param clientDirectory The eden client data directory, where the client
* configuration file can be found (along with its overlay and other
* data).
*/
static std::unique_ptr<CheckoutConfig> loadFromClientDirectory(
AbsolutePathPiece mountPath,
AbsolutePathPiece clientDirectory);
static folly::dynamic loadClientDirectoryMap(AbsolutePathPiece edenDir);
/**
* Get the parent commit(s) of the working directory.
*/
ParentCommits getParentCommits() const;
/**
* Set the parent commit(s) of the working directory.
*/
void setParentCommits(const ParentCommits& parents) const;
void setParentCommits(
Hash parent1,
std::optional<Hash> parent2 = std::nullopt) const;
const AbsolutePath& getMountPath() const {
return mountPath_;
}
/** @return Path to the directory where overlay information is stored. */
AbsolutePath getOverlayPath() const;
/**
* Get the repository type.
*
* Currently supported types include "git" and "hg".
*/
const std::string& getRepoType() const {
return repoType_;
}
/**
* Get the channel type that this mount should be using.
*/
MountProtocol getMountProtocol() const {
return mountProtocol_;
}
/**
* Get the repository source.
*
* The meaning and format of repository source string depends on the
* repository type. For git and hg repositories, this is the path to the
* git or mercuial repository.
*/
const std::string& getRepoSource() const {
return repoSource_;
}
/** Path to the file where the current commit ID is stored */
AbsolutePath getSnapshotPath() const;
/** Path to the client directory */
const AbsolutePath& getClientDirectory() const;
/** Whether this repository is mounted in case-sensitive mode */
bool getCaseSensitive() const;
/** Whether this repository should allow non-utf8 path */
bool getRequireUtf8Path() const {
return requireUtf8Path_;
}
#ifdef _WIN32
/** Guid for that repository */
Guid getRepoGuid() const {
return repoGuid_;
}
#endif
private:
const AbsolutePath clientDirectory_;
const AbsolutePath mountPath_;
std::string repoType_;
std::string repoSource_;
MountProtocol mountProtocol_;
bool caseSensitive_{!folly::kIsWindows};
bool requireUtf8Path_{true};
#ifdef _WIN32
Guid repoGuid_;
#endif
};
} // namespace eden
} // namespace facebook