Skip to content

Commit

Permalink
Move forc's fmt command support into a dedicated forc-fmt plugi…
Browse files Browse the repository at this point in the history
…n crate (FuelLabs#1196)

* Add a new `forc-fmt` forc plugin for running the Sway code formatter

In preparation for removing internal support for formatting from `forc`
as a part of an ongoing effort toward slimming down `forc`'s dependency
graph.

* forc: Remove `fmt` command in favour of new `forc-fmt` plugin crate
  • Loading branch information
mitchmindtree authored Apr 8, 2022
1 parent 800c33c commit b9aeebf
Show file tree
Hide file tree
Showing 10 changed files with 67 additions and 98 deletions.
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ jobs:
cargo install toml-cli
./.github/workflows/scripts/verify_tag.sh ${{ github.ref_name }} forc/Cargo.toml
./.github/workflows/scripts/verify_tag.sh ${{ github.ref_name }} forc-explore/Cargo.toml
./.github/workflows/scripts/verify_tag.sh ${{ github.ref_name }} forc-fmt/Cargo.toml
./.github/workflows/scripts/verify_tag.sh ${{ github.ref_name }} forc-lsp/Cargo.toml
./.github/workflows/scripts/verify_tag.sh ${{ github.ref_name }} forc-pkg/Cargo.toml
./.github/workflows/scripts/verify_tag.sh ${{ github.ref_name }} forc-util/Cargo.toml
Expand Down
16 changes: 13 additions & 3 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ members = [
"examples/build-all-examples",
"forc",
"forc-explore",
"forc-fmt",
"forc-lsp",
"forc-pkg",
"forc-util",
Expand Down
18 changes: 18 additions & 0 deletions forc-fmt/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[package]
name = "forc-fmt"
version = "0.9.2"
authors = ["Fuel Labs <[email protected]>"]
edition = "2021"
homepage = "https://fuel.network/"
license = "Apache-2.0"
repository = "https://github.com/FuelLabs/sway"
description = "A `forc` plugin for running the Sway code formatter."

[dependencies]
anyhow = "1"
clap = { version = "3", features = ["derive"] }
forc-util = { version = "0.9.2", path = "../forc-util" }
prettydiff = "0.5"
sway-fmt = { version = "0.9.2", path = "../sway-fmt" }
sway-utils = { version = "0.9.2", path = "../sway-utils" }
taplo = "0.7"
96 changes: 33 additions & 63 deletions forc/src/ops/forc_fmt.rs → forc-fmt/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,39 @@
use crate::cli::{BuildCommand, FormatCommand};
use crate::ops::forc_build;
//! A `forc` plugin for running the Sway code formatter.
use anyhow::{bail, Result};
use clap::Parser;
use forc_util::{find_manifest_dir, println_green, println_red};
use prettydiff::{basic::DiffOp, diff_lines};
use std::default::Default;
use std::{fmt, fs, io, path::Path, sync::Arc};
use std::{fs, path::Path, sync::Arc};
use sway_fmt::{get_formatted_data, FormattingOptions};
use sway_utils::{constants, get_sway_files};
use taplo::formatter as taplo_fmt;

pub fn format(command: FormatCommand) -> Result<(), FormatError> {
let build_command = BuildCommand::default();

match forc_build::build(build_command) {
// build is successful, continue to formatting
Ok(_) => format_after_build(command),

// forc_build will print all the errors/warnings
Err(err) => Err(err.into()),
}
#[derive(Debug, Parser)]
#[clap(
name = "forc-fmt",
about = "Forc plugin for running the Sway code formatter.",
version
)]
pub struct App {
/// Run in 'check' mode.
///
/// - Exits with `0` if input is formatted correctly.
/// - Exits with `1` and prints a diff if formatting is required.
#[clap(short, long)]
pub check: bool,
}

fn format_after_build(command: FormatCommand) -> Result<(), FormatError> {
let curr_dir = std::env::current_dir()?;
fn main() -> Result<()> {
let app = App::parse();
let dir = std::env::current_dir()?;
format_pkg_at_dir(app, &dir)
}

match find_manifest_dir(&curr_dir) {
/// Format the package at the given directory.
fn format_pkg_at_dir(app: App, dir: &Path) -> Result<()> {
match find_manifest_dir(dir) {
Some(path) => {
let mut manifest_file = path.clone();
manifest_file.push(constants::MANIFEST_FILE_NAME);
Expand All @@ -37,7 +47,7 @@ fn format_after_build(command: FormatCommand) -> Result<(), FormatError> {
let file_content: Arc<str> = Arc::from(file_content);
match get_formatted_data(file_content.clone(), formatting_options) {
Ok((_, formatted_content)) => {
if command.check {
if app.check {
if *file_content != *formatted_content {
contains_edits = true;
println!("\n{:?}\n", file);
Expand All @@ -62,7 +72,7 @@ fn format_after_build(command: FormatCommand) -> Result<(), FormatError> {
..Default::default()
};
let formatted_content = taplo_fmt::format(&file_content, taplo_alphabetize);
if !command.check {
if !app.check {
format_file(&manifest_file, &formatted_content)?;
} else if formatted_content != file_content {
contains_edits = true;
Expand All @@ -73,10 +83,10 @@ fn format_after_build(command: FormatCommand) -> Result<(), FormatError> {
}
}

if command.check {
if app.check {
if contains_edits {
// One or more files are not formatted, exit with error
Err("Files contain formatting violations.".into())
bail!("Files contain formatting violations.");
} else {
// All files are formatted, exit cleanly
Ok(())
Expand All @@ -85,11 +95,11 @@ fn format_after_build(command: FormatCommand) -> Result<(), FormatError> {
Ok(())
}
}
_ => Err("Manifest file does not exist".into()),
_ => bail!("Manifest file does not exist"),
}
}

fn display_file_diff(file_content: &str, formatted_content: &str) -> Result<(), FormatError> {
fn display_file_diff(file_content: &str, formatted_content: &str) -> Result<()> {
let changeset = diff_lines(file_content, formatted_content);
let mut count_of_updates = 0;
for diff in changeset.diff() {
Expand Down Expand Up @@ -129,52 +139,12 @@ fn display_file_diff(file_content: &str, formatted_content: &str) -> Result<(),
Result::Ok(())
}

fn format_file(file: &Path, formatted_content: &str) -> Result<(), FormatError> {
fn format_file(file: &Path, formatted_content: &str) -> Result<()> {
fs::write(file, formatted_content)?;

Ok(())
}

pub struct FormatError {
pub message: String,
}

impl fmt::Display for FormatError {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
write!(f, "{}", self)
}
}

impl From<&str> for FormatError {
fn from(s: &str) -> Self {
FormatError {
message: s.to_string(),
}
}
}

impl From<String> for FormatError {
fn from(s: String) -> Self {
FormatError { message: s }
}
}

impl From<io::Error> for FormatError {
fn from(e: io::Error) -> Self {
FormatError {
message: e.to_string(),
}
}
}

impl From<anyhow::Error> for FormatError {
fn from(e: anyhow::Error) -> Self {
FormatError {
message: e.to_string(),
}
}
}

#[cfg(test)]
mod tests {
use super::taplo_fmt;
Expand Down
3 changes: 0 additions & 3 deletions forc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,11 @@ fuel-tx = "0.7"
fuel-vm = "0.6"
futures = "0.3"
hex = "0.4.3"
prettydiff = "0.5.0"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0.73"
sway-core = { version = "0.9.2", path = "../sway-core" }
sway-fmt = { version = "0.9.2", path = "../sway-fmt" }
sway-types = { version = "0.9.2", path = "../sway-types" }
sway-utils = { version = "0.9.2", path = "../sway-utils" }
taplo = "0.7"
term-table = "1.3"
tokio = { version = "1.8.0", features = ["macros", "rt-multi-thread", "process"] }
toml = "0.5"
Expand Down
21 changes: 0 additions & 21 deletions forc/src/cli/commands/format.rs

This file was deleted.

1 change: 0 additions & 1 deletion forc/src/cli/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ pub mod build;
pub mod clean;
pub mod completions;
pub mod deploy;
pub mod format;
pub mod init;
pub mod json_abi;
pub mod parse_bytecode;
Expand Down
7 changes: 1 addition & 6 deletions forc/src/cli/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use self::commands::{
addr2line, build, clean, completions, deploy, format, init, json_abi, parse_bytecode, run,
test, update,
addr2line, build, clean, completions, deploy, init, json_abi, parse_bytecode, run, test, update,
};
use addr2line::Command as Addr2LineCommand;
use anyhow::{anyhow, Result};
Expand All @@ -9,7 +8,6 @@ use clap::Parser;
pub use clean::Command as CleanCommand;
pub use completions::Command as CompletionsCommand;
pub use deploy::Command as DeployCommand;
pub use format::Command as FormatCommand;
pub use init::Command as InitCommand;
pub use json_abi::Command as JsonAbiCommand;
use parse_bytecode::Command as ParseBytecodeCommand;
Expand Down Expand Up @@ -37,8 +35,6 @@ enum Forc {
#[clap(after_help = completions::COMPLETIONS_HELP)]
Completions(CompletionsCommand),
Deploy(DeployCommand),
#[clap(name = "fmt")]
Format(FormatCommand),
Init(InitCommand),
ParseBytecode(ParseBytecodeCommand),
Run(RunCommand),
Expand All @@ -65,7 +61,6 @@ pub async fn run_cli() -> Result<()> {
Forc::Clean(command) => clean::exec(command),
Forc::Completions(command) => completions::exec(command),
Forc::Deploy(command) => deploy::exec(command).await,
Forc::Format(command) => format::exec(command),
Forc::Init(command) => init::exec(command),
Forc::ParseBytecode(command) => parse_bytecode::exec(command),
Forc::Run(command) => run::exec(command).await,
Expand Down
1 change: 0 additions & 1 deletion forc/src/ops/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ pub mod forc_abi_json;
pub mod forc_build;
pub mod forc_clean;
pub mod forc_deploy;
pub mod forc_fmt;
pub mod forc_init;
pub mod forc_run;
pub mod forc_update;

0 comments on commit b9aeebf

Please sign in to comment.