Skip to content

Commit

Permalink
Update the way with handle different paths in single project config f…
Browse files Browse the repository at this point in the history
…ile.

Summary:
In `SingleProjectConfig` we don't have an explicit `root` settings, so we were assuming that the `current_dir` is the `root`.

And the basic path normalization were just stripping the `root_dir` from configs paths (sources, schemas, artifacts). But this approach isn't working for cases where some paths are outside of `current_dir`. Like in the issue: #3673

This diff fixes the issue by changing the way we detect `root_dir` for the project.

1) we create canonical paths from `current_dir` + `path`
2) we detect a common path between all config paths (src, schema, extensions, artifactsDirectory) - this common path is the `root_dir`.
3) we strip `root_dir` from all config paths when creating an instance of MultiProjectConfig.

Reviewed By: rbalicki2

Differential Revision: D32931262

fbshipit-source-id: f1940fc9ce975f7811c3f8f5a4d56790bd2bc74a
  • Loading branch information
alunyov authored and facebook-github-bot committed Dec 8, 2021
1 parent f906565 commit 6eea5a8
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* LICENSE file in the root directory of this source tree.
*/

use common::{FeatureFlags, SourceLocationKey};
use common::SourceLocationKey;
use fixture_tests::Fixture;
use graphql_ir::{build, Program};
use graphql_syntax::parse_executable;
Expand Down
1 change: 1 addition & 0 deletions compiler/crates/relay-compiler/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ path = "tests/compile_relay_artifacts_test.rs"
async-trait = "0.1.51"
bincode = "1.3.3"
common = { path = "../common" }
common-path = "1.0.0"
dashmap = { version = "4.0.2", features = ["rayon", "serde"] }
dependency-analyzer = { path = "../dependency-analyzer" }
env_logger = "0.7"
Expand Down
99 changes: 77 additions & 22 deletions compiler/crates/relay-compiler/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,22 +116,26 @@ pub enum FileSourceKind {
Glob,
}

/// In the configs we may have a various values: with or without './' prefix at the beginning
/// This function will use `root_dir` to construct full path, canonicalize it, and then
/// it will remove the `root_dir` prefix.
fn normalize_path_from_config(root_dir: PathBuf, path_from_config: PathBuf) -> PathBuf {
let mut src = root_dir.clone();
src.push(path_from_config);
fn normalize_path_from_config(
current_dir: PathBuf,
common_path: PathBuf,
path_from_config: PathBuf,
) -> PathBuf {
let mut src = current_dir.join(path_from_config.clone());

src = src
.canonicalize()
.map_err(|err| format!("Unable to canonicalize file {:?}. Error: {:?}", &src, err))
.unwrap();

if !src.exists() {
panic!("Path '{:?}' does not exits.", &src);
}

src.iter().skip(root_dir.iter().count()).collect()
.unwrap_or_else(|err| panic!("Unable to canonicalize file {:?}. Error: {:?}", &src, err));

src.strip_prefix(common_path.clone())
.unwrap_or_else(|_| {
panic!(
"Expect to be able to strip common_path from {:?} {:?}",
&src,
&common_path.clone(),
);
})
.to_path_buf()
}

impl From<SingleProjectConfigFile> for Config {
Expand Down Expand Up @@ -690,19 +694,66 @@ impl Default for SingleProjectConfigFile {
}
}

impl SingleProjectConfigFile {
fn get_common_root(&self, root_dir: PathBuf) -> Option<PathBuf> {
let mut paths = vec![];
if let Some(artifact_directory_path) = self.artifact_directory.clone() {
paths.push(join_and_canonicalize(
root_dir.clone(),
artifact_directory_path,
));
}
paths.push(join_and_canonicalize(root_dir.clone(), self.src.clone()));
paths.push(join_and_canonicalize(root_dir.clone(), self.schema.clone()));
paths.extend(
self.schema_extensions
.iter()
.map(|dir| join_and_canonicalize(root_dir.clone(), dir.clone())),
);
common_path::common_path_all(paths.iter().map(|path| path.as_path()))
}
}

fn join_and_canonicalize(root: PathBuf, path: PathBuf) -> PathBuf {
root.clone()
.join(path.clone())
.canonicalize()
.unwrap_or_else(|err| {
panic!(
"Expected to create a valid path from {:?} and {:?}. Error {:?}",
root, path, err
);
})
}

impl From<SingleProjectConfigFile> for MultiProjectConfigFile {
fn from(oss_config: SingleProjectConfigFile) -> MultiProjectConfigFile {
let root_dir = std::env::current_dir().unwrap();
let current_dir = std::env::current_dir().unwrap();
let common_root_dir = oss_config.get_common_root(current_dir.clone()).expect(
"Could not find a common root directory for project sources, schemas, and extensions.",
);

let default_project_name = "default".intern();
let project_config = ConfigFileProject {
output: oss_config
.artifact_directory
.map(|dir| normalize_path_from_config(root_dir.clone(), dir)),
output: oss_config.artifact_directory.map(|dir| {
normalize_path_from_config(current_dir.clone(), common_root_dir.clone(), dir)
}),
schema: Some(normalize_path_from_config(
root_dir.clone(),
current_dir.clone(),
common_root_dir.clone(),
oss_config.schema,
)),
schema_extensions: oss_config.schema_extensions,
schema_extensions: oss_config
.schema_extensions
.iter()
.map(|dir| {
normalize_path_from_config(
current_dir.clone(),
common_root_dir.clone(),
dir.clone(),
)
})
.collect(),
persist: oss_config.persist_config,
typegen_config: TypegenConfig {
language: oss_config.language.unwrap_or(TypegenLanguage::TypeScript),
Expand All @@ -721,12 +772,16 @@ impl From<SingleProjectConfigFile> for MultiProjectConfigFile {
projects.insert(default_project_name, project_config);

let mut sources = FnvIndexMap::default();
let src = normalize_path_from_config(root_dir.clone(), oss_config.src);
let src = normalize_path_from_config(
current_dir.clone(),
common_root_dir.clone(),
oss_config.src,
);

sources.insert(src, SourceSet::SourceSetName(default_project_name));

MultiProjectConfigFile {
root: Some(root_dir),
root: Some(common_root_dir),
projects,
sources,
excludes: oss_config.excludes,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* LICENSE file in the root directory of this source tree.
*/

use common::{DiagnosticsResult, FeatureFlags};
use common::DiagnosticsResult;
use fixture_tests::Fixture;
use graphql_ir::Program;
use graphql_test_helpers::apply_transform_for_test;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* LICENSE file in the root directory of this source tree.
*/

use common::{ConsoleLogger, FeatureFlag, FeatureFlags, SourceLocationKey};
use common::{ConsoleLogger, FeatureFlags, SourceLocationKey};
use fixture_tests::Fixture;
use fnv::FnvHashMap;
use graphql_ir::{build, Program};
Expand Down

0 comments on commit 6eea5a8

Please sign in to comment.