Skip to content

Commit

Permalink
feat(prepare): move to one-file-per-query for offline mode
Browse files Browse the repository at this point in the history
Co-authored-by: Jonas Platte <[email protected]>
  • Loading branch information
2 people authored and Aandreba committed Mar 31, 2023
1 parent 019a879 commit 0eeca2f
Show file tree
Hide file tree
Showing 9 changed files with 395 additions and 375 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 7 additions & 12 deletions sqlx-cli/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use std::io;
use std::time::Duration;

use anyhow::Result;
use futures::{Future, TryFutureExt};

use sqlx::{AnyConnection, Connection};
use std::io;
use std::time::Duration;

use crate::opt::{Command, ConnectOpts, DatabaseCommand, MigrateCommand};

Expand Down Expand Up @@ -61,18 +63,11 @@ pub async fn run(opt: Opt) -> Result<()> {
},

Command::Prepare {
check: false,
merged,
args,
check,
workspace,
connect_opts,
} => prepare::run(&connect_opts, merged, args).await?,

Command::Prepare {
check: true,
merged,
args,
connect_opts,
} => prepare::check(&connect_opts, merged, args).await?,
} => prepare::run(check, workspace, connect_opts, args).await?,
};

Ok(())
Expand Down
55 changes: 49 additions & 6 deletions sqlx-cli/src/metadata.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
use anyhow::{Context, Result};
use cargo_metadata::{
Metadata as CargoMetadata, Package as MetadataPackage, PackageId as MetadataId,
};

use std::{
collections::{btree_map, BTreeMap, BTreeSet},
ffi::OsStr,
path::{Path, PathBuf},
process::Command,
str::FromStr,
};

use anyhow::Context;
use cargo_metadata::{
Metadata as CargoMetadata, Package as MetadataPackage, PackageId as MetadataId,
};

/// The minimal amount of package information we care about
///
/// The package's `name` is used to `cargo clean -p` specific crates while the `src_paths` are
Expand Down Expand Up @@ -50,6 +52,8 @@ pub struct Metadata {
packages: BTreeMap<MetadataId, Package>,
/// All of the crates in the current workspace
workspace_members: Vec<MetadataId>,
/// Workspace root path.
workspace_root: PathBuf,
/// Maps each dependency to its set of dependents
reverse_deps: BTreeMap<MetadataId, BTreeSet<MetadataId>>,
/// The target directory of the project
Expand All @@ -62,6 +66,19 @@ pub struct Metadata {
}

impl Metadata {
/// Parse the manifest from the current working directory using `cargo metadata`.
pub fn from_current_directory(cargo: &OsStr) -> anyhow::Result<Self> {
let output = Command::new(cargo)
.args(["metadata", "--format-version=1"])
.output()
.context("Could not fetch metadata")?;

std::str::from_utf8(&output.stdout)
.context("Invalid `cargo metadata` output")?
.parse()
.context("Issue parsing `cargo metadata` output - consider manually running it to check for issues")
}

pub fn package(&self, id: &MetadataId) -> Option<&Package> {
self.packages.get(id)
}
Expand All @@ -74,6 +91,10 @@ impl Metadata {
&self.workspace_members
}

pub fn workspace_root(&self) -> &Path {
&self.workspace_root
}

pub fn target_directory(&self) -> &Path {
&self.target_directory
}
Expand All @@ -97,7 +118,7 @@ impl Metadata {
if let Some(immediate_dependents) = self.reverse_deps.get(id) {
for immediate_dependent in immediate_dependents {
if dependents.insert(immediate_dependent) {
self.all_dependents_of_helper(&immediate_dependent, dependents);
self.all_dependents_of_helper(immediate_dependent, dependents);
}
}
}
Expand All @@ -117,6 +138,7 @@ impl FromStr for Metadata {
let CargoMetadata {
packages: metadata_packages,
workspace_members,
workspace_root,
resolve,
target_directory,
..
Expand All @@ -142,14 +164,35 @@ impl FromStr for Metadata {
}
}

let workspace_root = workspace_root.into_std_path_buf();
let target_directory = target_directory.into_std_path_buf();

Ok(Self {
packages,
workspace_members,
workspace_root,
reverse_deps,
target_directory,
current_package,
})
}
}

/// The absolute path to the directory containing the `Cargo.toml` manifest.
/// Depends on the current working directory.
pub(crate) fn manifest_dir(cargo: &OsStr) -> anyhow::Result<PathBuf> {
let stdout = Command::new(cargo)
.args(["locate-project", "--message-format=plain"])
.output()
.context("could not locate manifest directory")?
.stdout;

let mut manifest_path: PathBuf = std::str::from_utf8(&stdout)
.context("output of `cargo locate-project` was not valid UTF-8")?
// remove trailing newline
.trim()
.into();

manifest_path.pop();
Ok(manifest_path)
}
11 changes: 7 additions & 4 deletions sqlx-cli/src/opt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ pub enum Command {

/// Generate query metadata to support offline compile-time verification.
///
/// Saves metadata for all invocations of `query!` and related macros to `sqlx-data.json`
/// in the current directory, overwriting if needed.
/// Saves metadata for all invocations of `query!` and related macros to a `.sqlx` directory
/// in the current directory (or workspace root with `--workspace`), overwriting if needed.
///
/// During project compilation, the absence of the `DATABASE_URL` environment variable or
/// the presence of `SQLX_OFFLINE` (with a value of `true` or `1`) will constrain the
Expand All @@ -29,9 +29,12 @@ pub enum Command {
#[clap(long)]
check: bool,

/// Generate a single top-level `sqlx-data.json` file when using a cargo workspace.
/// Generate a single workspace-level `.sqlx` folder.
///
/// This option is intended for workspaces where multiple crates use SQLx. If there is only
/// one, it is better to run `cargo sqlx prepare` without this option inside that crate.
#[clap(long)]
merged: bool,
workspace: bool,

/// Arguments to be passed to `cargo rustc ...`.
#[clap(last = true)]
Expand Down
Loading

0 comments on commit 0eeca2f

Please sign in to comment.