Skip to content

Commit

Permalink
[WIP] develop formatting command
Browse files Browse the repository at this point in the history
  • Loading branch information
JamieMason committed Sep 29, 2024
1 parent d39372b commit 369d9d7
Show file tree
Hide file tree
Showing 8 changed files with 536 additions and 147 deletions.
2 changes: 1 addition & 1 deletion justfile
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ run-fluid:
set -euxo pipefail
cd fixtures/fluid-framework
RUST_BACKTRACE=1 cargo run -- lint --versions
RUST_BACKTRACE=1 cargo run -- lint --format --versions

# Run the release rust binary against a clone of microsoft/FluidFramework
run-fluid-prod:
Expand Down
59 changes: 42 additions & 17 deletions src/effects.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use serde_json::Value;

use crate::{
context::InstancesById, dependency::Dependency, group_selector::GroupSelector, instance::InstanceId,
package_json::PackageJson, packages::Packages, specifier::Specifier,
packages::Packages, specifier::Specifier,
};

pub mod fix;
Expand All @@ -15,7 +17,7 @@ pub mod mock;
/// side effects are handled by the command-specific structs which implement
/// this trait.
pub trait Effects {
fn on(&mut self, event: Event, instances_by_id: &mut InstancesById);
fn on(&mut self, event: Event);
fn on_instance(&mut self, event: InstanceEvent, instances_by_id: &mut InstancesById);
fn get_packages(&mut self) -> Packages;
fn set_packages(&mut self, packages: Packages);
Expand All @@ -34,11 +36,11 @@ pub enum Event<'a> {
EnterFormat,
/// Linting/fixing of formatting of a package.json file has completed and the
/// package was already valid
FormatMatch(&'a FormatEvent<'a>),
PackageFormatMatch(String),
/// Linting/fixing of formatting of a package.json file has completed and the
/// package was initially invalid. In the case of fixing, they are now valid
/// but were invalid beforehand
FormatMismatch(&'a FormatEvent<'a>),
PackageFormatMismatch(PackageFormatEvent),
/// Linting/fixing has completed
ExitCommand,
}
Expand Down Expand Up @@ -109,18 +111,41 @@ pub struct InstanceEvent<'a> {
pub variant: InstanceEventVariant,
}

#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub enum FormatEventVariant {
/// ✓ `rcFile.formatBugs` is enabled
/// ✘ The `bugs` property is not formatted
BugsPropertyIsNotFormatted,
/// ✓ `rcFile.formatRepository` is enabled
/// ✘ The `repository` property is not formatted
RepositoryPropertyIsNotFormatted,
/// ✓ `rcFile.sortAz` is enabled
/// ✘ This property is not sorted alphabetically
PropertyIsNotSortedAz,
/// ✓ `rcFile.sortPackages` is enabled
/// ✘ This package.json's properties are not sorted
PackagePropertiesAreNotSorted,
/// ✓ `rcFile.sortExports` is enabled
/// ✘ The `exports` property is not sorted
ExportsPropertyIsNotSorted,
}

#[derive(Debug)]
pub struct PackageFormatEvent {
/// The name of the package.json file with formatting issues
pub package_name: String,
/// Each formatting issue in this file
pub formatting_mismatches: Vec<FormatEvent>,
}

#[derive(Debug)]
pub struct FormatEvent<'a> {
/// The package.json file being linted
pub package_json: &'a PackageJson,
/// Whether `rcfile.format_bugs` is enabled and matches
pub format_bugs_is_valid: Option<bool>,
/// Whether `rcfile.format_repository` is enabled and matches
pub format_repository_is_valid: Option<bool>,
/// Whether `rcfile.sort_az` is enabled and matches
pub sort_az_is_valid: Option<bool>,
/// Whether `rcfile.sort_first` is enabled and matches
pub sort_first_is_valid: Option<bool>,
/// Whether `rcfile.sort_exports` is enabled and matches
pub sort_exports_is_valid: Option<bool>,
pub struct FormatEvent {
/// The formatted value
pub expected: Value,
/// The name of the package.json file being linted
pub package_name: String,
/// The path to the property that was linted
pub property_path: String,
/// The broken linting rule
pub variant: FormatEventVariant,
}
38 changes: 34 additions & 4 deletions src/effects/fix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ use crate::{
packages::Packages,
};

use super::FormatEventVariant;

/// The implementation of the `fix` command's side effects
pub struct FixEffects<'a> {
pub config: &'a Config,
Expand Down Expand Up @@ -39,7 +41,7 @@ impl Effects for FixEffects<'_> {
self.packages = Some(packages);
}

fn on(&mut self, event: Event, instances_by_id: &mut InstancesById) {
fn on(&mut self, event: Event) {
match &event {
Event::EnterVersionsAndRanges => {
info!("{}", "= SEMVER RANGES AND VERSION MISMATCHES".dimmed());
Expand All @@ -62,13 +64,41 @@ impl Effects for FixEffects<'_> {
Event::DependencyValid(dependency, expected) => { /*NOOP*/ }
Event::DependencyInvalid(dependency, expected) => { /*NOOP*/ }
Event::DependencyWarning(dependency, expected) => { /*NOOP*/ }
Event::FormatMatch(_) => {
Event::PackageFormatMatch(_) => {
// @TODO
}
Event::FormatMismatch(_) => {
// @TODO
Event::PackageFormatMismatch(event) => {
let packages = self.packages.as_mut().unwrap();
let package = packages.by_name.get_mut(&event.package_name).unwrap();
let file_path = package.get_relative_file_path(&self.config.cwd);

event.formatting_mismatches.iter().for_each(|mismatch| {
let property_path = &mismatch.property_path;
let expected = &mismatch.expected;
match &mismatch.variant {
FormatEventVariant::BugsPropertyIsNotFormatted => {
package.set_prop(mismatch.property_path.as_str(), mismatch.expected.clone());
}
FormatEventVariant::RepositoryPropertyIsNotFormatted => {
package.set_prop(mismatch.property_path.as_str(), mismatch.expected.clone());
}
FormatEventVariant::ExportsPropertyIsNotSorted => {
package.set_prop(mismatch.property_path.as_str(), mismatch.expected.clone());
}
FormatEventVariant::PropertyIsNotSortedAz => {
package.set_prop(mismatch.property_path.as_str(), mismatch.expected.clone());
}
FormatEventVariant::PackagePropertiesAreNotSorted => {
package.set_prop(mismatch.property_path.as_str(), mismatch.expected.clone());
}
}
});
}
Event::ExitCommand => {
let mut packages = self.get_packages();
for package in packages.by_name.values_mut() {
package.write_to_disk(self.config);
}
if self.is_valid {
let icon = icon_valid();
info!("\n{icon} valid");
Expand Down
47 changes: 41 additions & 6 deletions src/effects/lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ use crate::{
version_group::Variant,
};

use super::FormatEventVariant;

/// The implementation of the `lint` command's side effects
pub struct LintEffects<'a> {
pub config: &'a Config,
Expand Down Expand Up @@ -39,7 +41,7 @@ impl Effects for LintEffects<'_> {
self.packages = Some(packages);
}

fn on(&mut self, event: Event, instances_by_id: &mut InstancesById) {
fn on(&mut self, event: Event) {
match &event {
Event::EnterVersionsAndRanges => {
info!("{}", "= SEMVER RANGES AND VERSION MISMATCHES".dimmed());
Expand Down Expand Up @@ -77,11 +79,44 @@ impl Effects for LintEffects<'_> {
let hint = "has name or specifiers unsupported by syncpack".dimmed();
info!("{count} {name} {hint}");
}
Event::FormatMatch(_) => {
// @TODO
}
Event::FormatMismatch(_) => {
// @TODO
Event::PackageFormatMatch(package_name) => {
let packages = self.packages.as_mut().unwrap();
let package = packages.by_name.get_mut(package_name).unwrap();
let file_path = package.get_relative_file_path(&self.config.cwd);
info!("{} {file_path}", icon_valid());
}
Event::PackageFormatMismatch(event) => {
let packages = self.packages.as_mut().unwrap();
let package = packages.by_name.get_mut(&event.package_name).unwrap();
let file_path = package.get_relative_file_path(&self.config.cwd);
info!("{} {file_path}", icon_fixable());
event.formatting_mismatches.iter().for_each(|mismatch| {
let property_path = &mismatch.property_path.dimmed();
let expected = &mismatch.expected;
match &mismatch.variant {
FormatEventVariant::BugsPropertyIsNotFormatted => {
let message = "is not in shorthand format".dimmed();
info!(" {property_path} {message}");
}
FormatEventVariant::RepositoryPropertyIsNotFormatted => {
let message = "is not in shorthand format".dimmed();
info!(" {property_path} {message}");
}
FormatEventVariant::ExportsPropertyIsNotSorted => {
let message = "is not sorted".dimmed();
info!(" {property_path} {message}");
}
FormatEventVariant::PropertyIsNotSortedAz => {
let message = "is not sorted alphabetically".dimmed();
info!(" {property_path} {message}");
}
FormatEventVariant::PackagePropertiesAreNotSorted => {
let message = "root properties are not sorted".dimmed();
info!(" {message}");
}
}
});
self.is_valid = false;
}
Event::ExitCommand => {
if self.is_valid {
Expand Down
10 changes: 7 additions & 3 deletions src/effects/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ pub struct EventsByType {
pub dependency_warning: Vec<()>,
pub format_match: Vec<()>,
pub format_mismatch: Vec<()>,
pub package_format_match: Vec<()>,
pub package_format_mismatch: Vec<()>,
pub exit_command: Vec<()>,
}

Expand All @@ -37,6 +39,8 @@ impl EventsByType {
dependency_warning: vec![],
format_match: vec![],
format_mismatch: vec![],
package_format_match: vec![],
package_format_mismatch: vec![],
exit_command: vec![],
}
}
Expand Down Expand Up @@ -80,16 +84,16 @@ impl Effects for MockEffects<'_> {
self.packages = Some(packages);
}

fn on(&mut self, event: Event, instances_by_id: &mut InstancesById) {
fn on(&mut self, event: Event) {
match &event {
Event::EnterVersionsAndRanges => self.events.enter_versions_and_ranges.push(()),
Event::EnterFormat => self.events.enter_format.push(()),
Event::GroupVisited(_) => self.events.group_visited.push(()),
Event::DependencyValid(_, _) => self.events.dependency_valid.push(()),
Event::DependencyInvalid(_, _) => self.events.dependency_invalid.push(()),
Event::DependencyWarning(_, _) => self.events.dependency_warning.push(()),
Event::FormatMatch(_) => self.events.format_match.push(()),
Event::FormatMismatch(_) => self.events.format_mismatch.push(()),
Event::PackageFormatMatch(_) => self.events.package_format_match.push(()),
Event::PackageFormatMismatch(_) => self.events.package_format_mismatch.push(()),
Event::ExitCommand => self.events.exit_command.push(()),
};
}
Expand Down
Loading

0 comments on commit 369d9d7

Please sign in to comment.