Normalise path resolution accross migrate! and query_file!

This commit is contained in:
Raphaël Thériault 2020-07-23 17:11:35 -04:00
parent 0eb63b7eae
commit 39b3e4a966
4 changed files with 46 additions and 39 deletions

37
sqlx-macros/src/common.rs Normal file
View File

@ -0,0 +1,37 @@
use proc_macro2::Span;
use std::env;
use std::path::{Path, PathBuf};
pub(crate) fn resolve_path(path: &str, err_span: Span) -> syn::Result<PathBuf> {
let path = Path::new(path);
if path.is_absolute() {
return Err(syn::Error::new(
err_span,
"absolute paths will only work on the current machine",
));
}
// requires `proc_macro::SourceFile::path()` to be stable
// https://github.com/rust-lang/rust/issues/54725
if path.is_relative()
&& !path
.parent()
.map_or(false, |parent| !parent.as_os_str().is_empty())
{
return Err(syn::Error::new(
err_span,
"paths relative to the current file's directory are not currently supported",
));
}
let base_dir = env::var("CARGO_MANIFEST_DIR").map_err(|_| {
syn::Error::new(
err_span,
"CARGO_MANIFEST_DIR is not set; please use Cargo to build",
)
})?;
let base_dir_path = Path::new(&base_dir);
Ok(base_dir_path.join(path))
}

View File

@ -16,6 +16,8 @@ mod database;
mod derives;
mod query;
mod common;
#[cfg(feature = "migrate")]
mod migrate;
@ -88,7 +90,7 @@ pub fn migrate(input: TokenStream) -> TokenStream {
use syn::LitStr;
let input = syn::parse_macro_input!(input as LitStr);
match migrate::expand_migrator_from_dir(input.value()) {
match migrate::expand_migrator_from_dir(input) {
Ok(ts) => ts.into(),
Err(e) => {
if let Some(parse_err) = e.downcast_ref::<syn::Error>() {

View File

@ -3,6 +3,7 @@ use quote::{quote, ToTokens, TokenStreamExt};
use sha2::{Digest, Sha384};
use std::fs;
use std::path::Path;
use syn::LitStr;
struct QuotedMigration {
version: i64,
@ -36,10 +37,10 @@ impl ToTokens for QuotedMigration {
}
// mostly copied from sqlx-core/src/migrate/source.rs
pub(crate) fn expand_migrator_from_dir<P: AsRef<Path>>(
dir: P,
) -> crate::Result<proc_macro2::TokenStream> {
let mut s = fs::read_dir(dir.as_ref().canonicalize()?)?;
pub(crate) fn expand_migrator_from_dir(dir: LitStr) -> crate::Result<proc_macro2::TokenStream> {
let path = crate::common::resolve_path(&dir.value(), dir.span())?;
let mut s = fs::read_dir(path)?;
let mut migrations = Vec::new();
while let Some(entry) = s.next() {

View File

@ -108,40 +108,7 @@ impl QuerySrc {
}
fn read_file_src(source: &str, source_span: Span) -> syn::Result<String> {
use std::path::Path;
let path = Path::new(source);
if path.is_absolute() {
return Err(syn::Error::new(
source_span,
"absolute paths will only work on the current machine",
));
}
// requires `proc_macro::SourceFile::path()` to be stable
// https://github.com/rust-lang/rust/issues/54725
if path.is_relative()
&& !path
.parent()
.map_or(false, |parent| !parent.as_os_str().is_empty())
{
return Err(syn::Error::new(
source_span,
"paths relative to the current file's directory are not currently supported",
));
}
let base_dir = env::var("CARGO_MANIFEST_DIR").map_err(|_| {
syn::Error::new(
source_span,
"CARGO_MANIFEST_DIR is not set; please use Cargo to build",
)
})?;
let base_dir_path = Path::new(&base_dir);
let file_path = base_dir_path.join(path);
let file_path = crate::common::resolve_path(source, source_span)?;
fs::read_to_string(&file_path).map_err(|e| {
syn::Error::new(