Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Support for input via STDIN via fake path - (hyphen) #17

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 27 additions & 13 deletions src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
//! The low-level build commands are defined in [`crate::command`].

use crate::{
cli::InputPath,
command::{self, ExternCrate, Flags, Strictness},
data::{CrateName, CrateNameCow, CrateNameRef, CrateType, Edition},
diagnostic::{Diagnostic, IntoDiagnostic, error},
Expand All @@ -16,7 +17,7 @@ use std::{borrow::Cow, cell::LazyCell, mem, path::Path};

pub(crate) fn build<'a>(
mode: BuildMode,
path: &Path,
path: InputPath<'_>,
crate_name: CrateNameRef<'a>,
crate_type: CrateType,
edition: Edition,
Expand All @@ -30,7 +31,7 @@ pub(crate) fn build<'a>(
}

fn build_default<'a>(
path: &Path,
path: InputPath<'_>,
crate_name: CrateNameRef<'a>,
crate_type: CrateType,
edition: Edition,
Expand All @@ -50,7 +51,7 @@ fn build_default<'a>(
}

fn build_cross_crate(
path: &Path,
path: InputPath<'_>,
crate_name: CrateNameRef<'_>,
crate_type: CrateType,
edition: Edition,
Expand All @@ -67,8 +68,12 @@ fn build_cross_crate(
)?;

let dependent_crate_name = CrateName::new_unchecked(format!("u_{crate_name}"));
let dependent_crate_path =
path.with_file_name(dependent_crate_name.as_str()).with_extension("rs");
let dependent_crate_path = match path {
InputPath::Path(path) => path,
InputPath::Stdin => Path::new("."),
}
.with_file_name(dependent_crate_name.as_str())
.with_extension("rs");

if !flags.program.dry_run && !dependent_crate_path.exists() {
// While we could omit the `extern crate` declaration in `edition >= Edition::Edition2018`,
Expand Down Expand Up @@ -106,14 +111,17 @@ fn extern_prelude_for(crate_type: CrateType) -> &'static [ExternCrate<'static>]
}

fn build_compiletest<'a>(
path: &Path,
path: InputPath<'_>,
crate_name: CrateNameRef<'a>,
_edition: Edition, // FIXME: should we respect the edition or should we reject it with `clap`?
flags: Flags<'_>,
) -> Result<CrateNameCow<'a>> {
// FIXME: Add a flag `--all-revs`.
// FIXME: Make sure `//@ compile-flags: --extern name` works as expected
let source = std::fs::read_to_string(path)?;
let source = match path {
InputPath::Path(path) => std::fs::read_to_string(path)?,
InputPath::Stdin => todo!(), // FIXME
};
let directives = Directives::parse(&source);

// FIXME: We should also store Cargo-like features here after having converted them to
Expand All @@ -137,8 +145,14 @@ fn build_compiletest<'a>(

let mut directives = directives.into_instantiated(&revisions);

// FIXME: unwrap
let auxiliary_base_path = LazyCell::new(|| path.parent().unwrap().join("auxiliary"));
let auxiliary_base_path = LazyCell::new(|| {
match path {
// FIXME: unwrap
InputPath::Path(path) => path.parent().unwrap(),
InputPath::Stdin => Path::new("."),
}
.join("auxiliary")
});

let dependencies: Vec<_> = directives
.dependencies
Expand Down Expand Up @@ -187,7 +201,7 @@ fn build_compiletest_auxiliary<'a>(
let source = std::fs::read_to_string(&path);

// FIXME: unwrap
let crate_name = CrateName::adjust_and_parse_file_path(&path).unwrap();
let crate_name = CrateName::parse_from_path(&path).unwrap();

// FIXME: What about instantiation???
let mut directives =
Expand All @@ -199,7 +213,7 @@ fn build_compiletest_auxiliary<'a>(
let flags = Flags { verbatim: verbatim_flags.as_ref(), ..flags };

command::compile(
&path,
InputPath::Path(&path), // FIXME: create From-impl
crate_name.as_ref(),
// FIXME: Verify this works with `@compile-flags:--crate-type=proc-macro`
// FIXME: I don't think it works rn
Expand All @@ -213,7 +227,7 @@ fn build_compiletest_auxiliary<'a>(
// FIXME: Is this how `//@ build-aux-docs` is supposed to work?
if document {
command::document(
&path,
InputPath::Path(&path), // FIXME: create From-impl
crate_name.as_ref(),
// FIXME: Verify this works with `@compile-flags:--crate-type=proc_macro`
// FIXME: I don't think it works rn
Expand All @@ -232,7 +246,7 @@ fn build_compiletest_auxiliary<'a>(
// FIXME: For some reason `compiletest` doesn't support `//@ aux-crate: name=../`
ExternCrate::Named { name, .. } => {
// FIXME: unwrap
let crate_name = CrateName::adjust_and_parse_file_path(&path).unwrap();
let crate_name = CrateName::parse_from_path(&path).unwrap();

ExternCrate::Named {
name,
Expand Down
29 changes: 27 additions & 2 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
use crate::data::{CrateNameBuf, CrateType, Edition};
use clap::{ColorChoice, Parser};
use joinery::JoinableIterator;
use std::{ffi::OsString, path::PathBuf};
use std::{
ffi::OsString,
path::{self, Path, PathBuf},
};

// FIXME: Improve the signature (smh. incorporate the toolchain).
pub(crate) fn parse() -> (Arguments, Option<OsString>) {
Expand Down Expand Up @@ -145,7 +148,7 @@ impl Edition {

impl CrateNameBuf {
fn parse_cli_style(source: &str) -> Result<Self, &'static str> {
Self::adjust_and_parse(source).map_err(|()| "not a non-empty alphanumeric string")
Self::parse_relaxed(source).map_err(|()| "not a non-empty alphanumeric string")
}
}

Expand All @@ -161,3 +164,25 @@ fn possible_values(values: impl IntoIterator<Item: std::fmt::Display, IntoIter:
values.into_iter().map(|value| format!("`{value}`")).join_with(", ")
)
}

// FIXME: move to mod data
#[derive(Clone, Copy)]
pub(crate) enum InputPath<'a> {
Path(&'a Path),
Stdin,
}

impl<'a> InputPath<'a> {
const STDIN_MARKER: &'static str = "-";

pub(crate) fn parse(path: &'a Path) -> Self {
if path.as_os_str() == Self::STDIN_MARKER { Self::Stdin } else { Self::Path(path) }
}

pub(crate) fn into_inner(self) -> &'a Path {
match self {
InputPath::Path(path) => path,
InputPath::Stdin => Path::new(Self::STDIN_MARKER),
}
}
}
17 changes: 8 additions & 9 deletions src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
// as well as those passed via the `RUST{,DOC}FLAGS` env vars.

use crate::{
cli,
data::{CrateName, CrateNameRef, CrateType, Edition},
cli::{self, InputPath},
data::{CrateNameCow, CrateNameRef, CrateType, Edition},
diagnostic::info,
error::Result,
utility::default,
Expand All @@ -22,14 +22,13 @@ use std::{
ffi::OsStr,
fmt,
ops::{Deref, DerefMut},
path::Path,
process,
};

mod environment;

pub(crate) fn compile(
path: &Path,
path: InputPath<'_>,
crate_name: CrateNameRef<'_>,
crate_type: CrateType,
edition: Edition,
Expand All @@ -39,7 +38,7 @@ pub(crate) fn compile(
) -> Result {
let mut command = Command::new("rustc", flags.program, strictness);
command.set_toolchain(flags);
command.arg(path);
command.arg(path.into_inner()); // rustc supports `-`

command.set_crate_type(crate_type);
command.set_crate_name(crate_name, path);
Expand Down Expand Up @@ -69,7 +68,7 @@ pub(crate) fn compile(
}

pub(crate) fn document(
path: &Path,
path: InputPath<'_>,
crate_name: CrateNameRef<'_>,
crate_type: CrateType,
edition: Edition,
Expand All @@ -79,7 +78,7 @@ pub(crate) fn document(
) -> Result {
let mut command = Command::new("rustdoc", flags.program, strictness);
command.set_toolchain(flags);
command.arg(path);
command.arg(path.into_inner()); // rustdoc supports `-`

command.set_crate_name(crate_name, path);
command.set_crate_type(crate_type);
Expand Down Expand Up @@ -220,8 +219,8 @@ impl<'a> Command<'a> {
}
}

fn set_crate_name(&mut self, crate_name: CrateNameRef<'_>, path: &Path) {
if let Ok(fiducial_crate_name) = CrateName::adjust_and_parse_file_path(path)
fn set_crate_name(&mut self, crate_name: CrateNameRef<'_>, path: InputPath<'_>) {
if let Ok(fiducial_crate_name) = CrateNameCow::parse_from_input_path(path)
&& crate_name == fiducial_crate_name.as_ref()
{
return;
Expand Down
29 changes: 22 additions & 7 deletions src/data.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
use std::{borrow::Cow, fmt, path::Path, str::FromStr};
use std::{
borrow::Cow,
fmt,
path::{self, Path},
str::FromStr,
};

use crate::cli::InputPath;

#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default)]
pub(crate) enum Edition {
Expand Down Expand Up @@ -128,14 +135,11 @@ impl<'src> CrateNameRef<'src> {
}

impl CrateNameBuf {
pub(crate) fn adjust_and_parse_file_path(path: &Path) -> Result<Self, ()> {
path.file_stem()
.and_then(|name| name.to_str())
.ok_or(())
.and_then(Self::adjust_and_parse)
pub(crate) fn parse_from_path(path: &Path) -> Result<Self, ()> {
path.file_stem().and_then(|name| name.to_str()).ok_or(()).and_then(Self::parse_relaxed)
}

pub(crate) fn adjust_and_parse(source: &str) -> Result<Self, ()> {
pub(crate) fn parse_relaxed(source: &str) -> Result<Self, ()> {
// NB: See the comment over in `CrateNameRef::parse` for why this makes sense.
if !source.is_empty()
&& source.chars().all(|char| char.is_alphanumeric() || char == '_' || char == '-')
Expand All @@ -147,6 +151,17 @@ impl CrateNameBuf {
}
}

impl<'src> CrateNameCow<'src> {
const FALLBACK_CRATE_NAME: &'static str = "rust_out";

pub(crate) fn parse_from_input_path(path: InputPath<'_>) -> Result<Self, ()> {
match path {
InputPath::Path(path) => CrateNameBuf::parse_from_path(path).map(Into::into),
InputPath::Stdin => Ok(CrateName::new_unchecked(Self::FALLBACK_CRATE_NAME).into()),
}
}
}

impl<T: AsRef<str>> CrateName<T> {
pub(crate) fn as_ref(&self) -> CrateNameRef<'_> {
CrateName(self.0.as_ref())
Expand Down
22 changes: 15 additions & 7 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@

use attribute::Attributes;
use builder::BuildMode;
use data::{CrateNameBuf, CrateNameCow, CrateType, Edition};
use cli::InputPath;
use data::{CrateName, CrateNameBuf, CrateNameCow, CrateType, Edition};
use diagnostic::IntoDiagnostic;
use std::{path::Path, process::ExitCode};

Expand Down Expand Up @@ -57,8 +58,12 @@ fn try_main() -> error::Result {
clap::ColorChoice::Auto => {}
}

// FIXME: Smh. move this into `cli::parse`.
let path = cli::InputPath::parse(&path);

// FIXME: eagerly lower `-f`s to `--cfg`s here, so we properly support them in `compiletest`+command

// FIXME: Smh. move this into `cli::parse`.
let build_mode = compute_build_mode(cross_crate, compiletest);

let edition = edition.unwrap_or_else(|| match build_mode {
Expand All @@ -71,7 +76,7 @@ fn try_main() -> error::Result {
crate_name,
crate_type,
build_mode,
&path,
path,
edition,
&build_flags.cfgs,
&program_flags,
Expand All @@ -90,7 +95,7 @@ fn try_main() -> error::Result {
};

let crate_name =
builder::build(build_mode, &path, crate_name.as_ref(), crate_type, edition, flags)?;
builder::build(build_mode, path, crate_name.as_ref(), crate_type, edition, flags)?;

if open {
command::open(crate_name.as_ref(), &program_flags)?;
Expand All @@ -112,7 +117,7 @@ fn compute_crate_name_and_type<'src>(
crate_name: Option<CrateNameBuf>,
crate_type: Option<CrateType>,
build_mode: BuildMode,
path: &Path,
path: InputPath<'_>,
edition: Edition,
cfgs: &[String],
program_flags: &cli::ProgramFlags,
Expand All @@ -123,7 +128,10 @@ fn compute_crate_name_and_type<'src>(
(crate_name, crate_type) => {
let (crate_name, crate_type): (Option<CrateNameCow<'_>>, _) = match build_mode {
BuildMode::Default | BuildMode::CrossCrate => {
*source = std::fs::read_to_string(path)?;
*source = match path {
InputPath::Path(path) => std::fs::read_to_string(path)?,
InputPath::Stdin => todo!(), // FIXME
};
let attributes = Attributes::parse(
source,
// FIXME: doesn't contain `-f`s; eagerly expand them into `--cfg`s in main
Expand All @@ -142,8 +150,8 @@ fn compute_crate_name_and_type<'src>(
};

// FIXME: unwrap
let crate_name = crate_name
.unwrap_or_else(|| CrateNameBuf::adjust_and_parse_file_path(path).unwrap().into());
let crate_name =
crate_name.unwrap_or_else(|| CrateNameCow::parse_from_input_path(path).unwrap());
let crate_type = crate_type.unwrap_or_default();

(crate_name, crate_type)
Expand Down