Skip to content
Merged
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: 3 additions & 37 deletions Cargo.lock

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

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ crate-type = ["rlib"]
default = ["bundler", "grid", "nodejs", "sourcemap"]
browserslist = ["browserslist-rs"]
bundler = ["dashmap", "sourcemap", "rayon"]
cli = ["clap", "serde_json", "browserslist", "jemallocator"]
cli = ["atty", "clap", "serde_json", "browserslist", "jemallocator"]
grid = []
jsonschema = ["schemars", "serde", "parcel_selectors/jsonschema"]
nodejs = ["dep:serde"]
Expand All @@ -51,6 +51,7 @@ lazy_static = "1.4.0"
const-str = "0.3.1"
pathdiff = "0.2.1"
# CLI deps
atty = { version = "0.2", optional = true }
clap = { version = "3.0.6", features = ["derive"], optional = true }
browserslist-rs = { version = "0.7.0", optional = true }
rayon = { version = "1.5.1", optional = true }
Expand Down
2 changes: 1 addition & 1 deletion rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[toolchain]
channel = "1.63.0"
channel = "1.65.0"
components = ["rustfmt", "clippy"]
42 changes: 33 additions & 9 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use atty::Stream;
use clap::{ArgGroup, Parser};
use lightningcss::bundler::{Bundler, FileProvider};
use lightningcss::stylesheet::{MinifyOptions, ParserOptions, PrinterOptions, StyleSheet};
Expand All @@ -18,9 +19,9 @@ static GLOBAL: jemallocator::Jemalloc = jemallocator::Jemalloc;
.args(&["targets", "browserslist"]),
))]
struct CliArgs {
/// Target CSS file
/// Target CSS file (default: stdin)
#[clap(value_parser)]
input_file: String,
input_file: Option<String>,
/// Destination file for the output
#[clap(short, long, group = "output_file", value_parser)]
output_file: Option<String>,
Expand Down Expand Up @@ -67,13 +68,36 @@ struct SourceMapJson<'a> {

pub fn main() -> Result<(), std::io::Error> {
let cli_args = CliArgs::parse();
let source = fs::read_to_string(&cli_args.input_file)?;

let project_root = std::env::current_dir()?;
let absolute_path = fs::canonicalize(&cli_args.input_file)?;
let filename = pathdiff::diff_paths(absolute_path, &project_root).unwrap();
let filename = filename.to_str().unwrap();

// If we're given an input file, read from it and adjust its name.
//
// If we're not given an input file and stdin was redirected, read
// from it and create a fake name. Return an error if stdin was not
// redirected (otherwise the program will hang waiting for input).
//
let (filename, source) = match &cli_args.input_file {
Some(f) => {
let absolute_path = fs::canonicalize(f)?;
let filename = pathdiff::diff_paths(absolute_path, &project_root).unwrap();
let filename = filename.to_string_lossy().into_owned();
let contents = fs::read_to_string(f)?;
(filename, contents)
}
None => {
// Don't silently wait for input if stdin was not redirected.
if atty::is(Stream::Stdin) {
return Err(io::Error::new(
io::ErrorKind::Other,
"Not reading from stdin as it was not redirected",
));
}
let filename = format!("stdin-{}", std::process::id());
let contents = io::read_to_string(io::stdin())?;
(filename, contents)
}
};

let css_modules = if let Some(_) = cli_args.css_modules {
let pattern = if let Some(pattern) = cli_args.css_modules_pattern.as_ref() {
match lightningcss::css_modules::Pattern::parse(pattern) {
Expand Down Expand Up @@ -121,13 +145,13 @@ pub fn main() -> Result<(), std::io::Error> {

let mut stylesheet = if cli_args.bundle {
let mut bundler = Bundler::new(&fs, source_map.as_mut(), options);
bundler.bundle(Path::new(&cli_args.input_file)).unwrap()
bundler.bundle(Path::new(&filename)).unwrap()
} else {
if let Some(sm) = &mut source_map {
sm.add_source(&filename);
let _ = sm.set_source_content(0, &source);
}
options.filename = filename.to_owned();
options.filename = filename;
StyleSheet::parse(&source, options).unwrap()
};

Expand Down
10 changes: 0 additions & 10 deletions tests/cli_integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,16 +154,6 @@ fn valid_input_file() -> Result<(), Box<dyn std::error::Error>> {
Ok(())
}

#[test]
fn no_input_file() -> Result<(), Box<dyn std::error::Error>> {
let mut cmd = Command::cargo_bin("lightningcss")?;
cmd.assert().failure().stderr(predicate::str::contains(
"The following required arguments were not provided:\n <INPUT_FILE>",
));

Ok(())
}

#[test]
fn empty_input_file() -> Result<(), Box<dyn std::error::Error>> {
let file = assert_fs::NamedTempFile::new("test.css")?;
Expand Down