NCEAS / metacatui

MetacatUI: A client-side web interface for DataONE data repositories
https://nceas.github.io/metacatui
Apache License 2.0
42 stars 24 forks source link

Apply linting & formatting globally #2412

Closed robyngit closed 1 month ago

robyngit commented 1 month ago

This pull request will add and configure prettier and eslint to MetacatUI and apply linting and formatting to all relevant files. Note that this PR is currently in draft mode but I would open the discussion and allow for feedback on the changes sooner rather than later.

Because these changes will impact nearly the entire codebase, incorporating the updates will present a challenge for groups that have extended MetacatUI. There may be similar merge conflicts for us to handle on branches that we've forked off of develop prior to these changes being merged in.

To reduce merge conflict headaches for external groups, I propose that these changes are presented in single independent release, with a series of commits that can be merged individually, and including detailed instructions on how to incorporate the changes into a forked codebase.

Proposed Commits

Roughly, the series of commits would be as follows:

  1. Configure & add prettier (do not apply formatting)
  2. Apply prettier formatting to all applicable files
  3. Configure & add eslint (do not fix linting issues)
  4. Fix linting issues in all applicable files (so far it looks like most issues can't be auto-fixed, so this will be a large number of manual fixes)
  5. Update the CONTRIBUTING guide; add github actions or pre-commit hooks to warn users of linting/formatting issues (this could become more strict in the future, but for the introductory release, I'd suggest a warning only)

Instructions for Incorporating Changes

The instructions for incorporating these changes into a forked codebase would something like:

  1. Ensure that your fork is up-to-date with the previous release, 2.29.0
  2. Pull in changes from commit number 1 run npm install to install prettier
  3. Run npm run format to apply prettier formatting to all files
  4. Pull in changes from commit number 2. Here, there may be merge conflicts to address, but the conflicts should entail only areas where the fork has diverged from the NCEAS MetacatUI, and should exclude the prettier formatting changes.
  5. Proceed with merging changes from the remaining commits. Merge conflicts may arise from commit #4, where files have been fixed to adhere to eslint rules. Ensure that any changes made in your fork are compatible with the eslint rules.
robyngit commented 1 month ago

Initial results from first prettier run

Code style issues found in 437 files

Click to see the list of files formatted ```plaintext .github/FUNDING.yml .github/ISSUE_TEMPLATE/bug_report.md .github/ISSUE_TEMPLATE/feature_request.md .github/workflows/test.js.yml CONTRIBUTING.md docs/_includes/download.html docs/_includes/header.html docs/_includes/nav.html docs/_includes/projects.html docs/_layouts/default.html docs/_layouts/guide.html docs/_sass/_base.scss docs/_sass/_buttons.scss docs/_sass/_card.scss docs/_sass/_colors.scss docs/_sass/_fonts.scss docs/_sass/_homepage.scss docs/_sass/_logo.scss docs/_sass/_nav.scss docs/assets/css/rouge-highlighting.css docs/assets/css/styles.scss docs/assets/images/favicons/manifest.json docs/assets/js/github-functions.js docs/guides/accesspolicy.md docs/guides/catalog-view-config.md docs/guides/editor/funding-autocomplete.md docs/guides/filters/configuring-filters.md docs/guides/index.md docs/guides/maps/cesium-for-portals.md docs/guides/maps/cesium.md docs/guides/themes/citations.md docs/guides/themes/images.md docs/index.md docs/install/apache.md docs/install/configuration/index.md docs/install/configuration/pre-2.12.0.md docs/install/dev-env.md docs/install/index.md docs/install/local.md docs/install/use-with-cn.md docs/jsdoc-templates/metacatui/conf.js docs/jsdoc-templates/metacatui/plugins/classcategory.js docs/jsdoc-templates/metacatui/plugins/screenshot.js docs/jsdoc-templates/metacatui/publish.js docs/jsdoc-templates/metacatui/static/scripts/linenumber.js docs/jsdoc-templates/metacatui/static/styles/jsdoc-default.css docs/jsdoc-templates/metacatui/static/styles/style.css docs/other/build.js docs/README.md docs/releases/release-notes-template.md docs/screenshots/index.md README.md server.js src/css/bootstrap-responsive.css src/css/bootstrap.css src/css/catalog-search-view.css src/css/jquery.sidr.dark.css src/css/jquery.sidr.light.css src/css/map-view.css src/css/metacatui-common.css src/css/metacatui-common.responsive.css src/css/portal-layouts/panels.css src/css/portal-themes/dark.css src/css/portal-themes/light.css src/js/app.js src/js/collections/AccessPolicy.js src/js/collections/bookkeeper/Quotas.js src/js/collections/bookkeeper/Usages.js src/js/collections/Citations.js src/js/collections/DataPackage.js src/js/collections/Filters.js src/js/collections/maps/AssetCategories.js src/js/collections/maps/AssetColors.js src/js/collections/maps/Features.js src/js/collections/maps/Geohashes.js src/js/collections/maps/GeoPoints.js src/js/collections/maps/MapAssets.js src/js/collections/maps/VectorFilters.js src/js/collections/maps/viewfinder/ZoomPresets.js src/js/collections/metadata/eml/EMLAnnotations.js src/js/collections/metadata/eml/EMLMissingValueCodes.js src/js/collections/ObjectFormats.js src/js/collections/ProjectList.js src/js/collections/QualityReport.js src/js/collections/queryFields/QueryFields.js src/js/collections/SolrResults.js src/js/collections/Units.js src/js/collections/UserGroup.js src/js/common/IconUtilities.js src/js/common/Utilities.js src/js/models/AccessRule.js src/js/models/analytics/Analytics.js src/js/models/analytics/GoogleAnalytics.js src/js/models/AppModel.js src/js/models/bookkeeper/Quota.js src/js/models/bookkeeper/Subscription.js src/js/models/bookkeeper/Usage.js src/js/models/CitationModel.js src/js/models/CollectionModel.js src/js/models/connectors/Filters-Map.js src/js/models/connectors/Filters-Search.js src/js/models/connectors/GeoPoints-Cesium.js src/js/models/connectors/GeoPoints-CesiumPoints.js src/js/models/connectors/GeoPoints-CesiumPolygon.js src/js/models/connectors/Map-Search-Filters.js src/js/models/connectors/Map-Search.js src/js/models/DataONEObject.js src/js/models/filters/BooleanFilter.js src/js/models/filters/ChoiceFilter.js src/js/models/filters/DateFilter.js src/js/models/filters/Filter.js src/js/models/filters/FilterGroup.js src/js/models/filters/NumericFilter.js src/js/models/filters/SpatialFilter.js src/js/models/filters/ToggleFilter.js src/js/models/formats/ObjectFormat.js src/js/models/geocoder/GeocodedLocation.js src/js/models/geocoder/GeocoderSearch.js src/js/models/geocoder/GoogleMapsAutocompleter.js src/js/models/geocoder/GoogleMapsGeocoder.js src/js/models/geocoder/Prediction.js src/js/models/LogsSearch.js src/js/models/LookupModel.js src/js/models/Map.js src/js/models/maps/AssetCategory.js src/js/models/maps/AssetColor.js src/js/models/maps/AssetColorPalette.js src/js/models/maps/assets/Cesium3DTileset.js src/js/models/maps/assets/CesiumGeohash.js src/js/models/maps/assets/CesiumImagery.js src/js/models/maps/assets/CesiumTerrain.js src/js/models/maps/assets/CesiumVectorData.js src/js/models/maps/assets/MapAsset.js src/js/models/maps/Feature.js src/js/models/maps/GeoBoundingBox.js src/js/models/maps/Geohash.js src/js/models/maps/GeoPoint.js src/js/models/maps/GeoScale.js src/js/models/maps/GeoUtilities.js src/js/models/maps/Map.js src/js/models/maps/MapInteraction.js src/js/models/maps/VectorFilter.js src/js/models/maps/viewfinder/ExpansionPanelsModel.js src/js/models/maps/viewfinder/ViewfinderModel.js src/js/models/maps/viewfinder/ZoomPresetModel.js src/js/models/metadata/eml/EMLMethodStep.js src/js/models/metadata/eml/EMLSpecializedText.js src/js/models/metadata/eml211/EML211.js src/js/models/metadata/eml211/EMLAnnotation.js src/js/models/metadata/eml211/EMLAttribute.js src/js/models/metadata/eml211/EMLDataTable.js src/js/models/metadata/eml211/EMLDateTimeDomain.js src/js/models/metadata/eml211/EMLDistribution.js src/js/models/metadata/eml211/EMLEntity.js src/js/models/metadata/eml211/EMLGeoCoverage.js src/js/models/metadata/eml211/EMLKeywordSet.js src/js/models/metadata/eml211/EMLMeasurementScale.js src/js/models/metadata/eml211/EMLMethods.js src/js/models/metadata/eml211/EMLMissingValueCode.js src/js/models/metadata/eml211/EMLNonNumericDomain.js src/js/models/metadata/eml211/EMLNumericDomain.js src/js/models/metadata/eml211/EMLOtherEntity.js src/js/models/metadata/eml211/EMLParty.js src/js/models/metadata/eml211/EMLProject.js src/js/models/metadata/eml211/EMLTaxonCoverage.js src/js/models/metadata/eml211/EMLTemporalCoverage.js src/js/models/metadata/eml211/EMLText.js src/js/models/metadata/eml211/EMLUnit.js src/js/models/metadata/eml220/EMLText.js src/js/models/metadata/ScienceMetadata.js src/js/models/MetricsModel.js src/js/models/NodeModel.js src/js/models/PackageModel.js src/js/models/portals/PortalImage.js src/js/models/portals/PortalModel.js src/js/models/portals/PortalSectionModel.js src/js/models/portals/PortalVizSectionModel.js src/js/models/projects/Project.js src/js/models/QualityCheckModel.js src/js/models/queryFields/QueryField.js src/js/models/Search.js src/js/models/SolrHeader.js src/js/models/SolrResult.js src/js/models/Stats.js src/js/models/UserModel.js src/js/polyfill.js src/js/routers/router.js src/js/templates/portals/editor/MarkdownExample.md src/js/themes/arctic/config.js src/js/themes/arctic/css/metacatui.css src/js/themes/arctic/css/metacatui.responsive.css src/js/themes/arctic/img/favicons/manifest.json src/js/themes/arctic/models/Map.js src/js/themes/arctic/routers/router.js src/js/themes/dataone/components/d1website/index.json src/js/themes/dataone/components/d1website/README.md src/js/themes/dataone/components/d1website/site.webmanifest src/js/themes/dataone/config.js src/js/themes/dataone/css/metacatui.css src/js/themes/dataone/css/metacatui.responsive.css src/js/themes/dataone/routers/router.js src/js/themes/default/config.js src/js/themes/default/css/metacatui.css src/js/themes/default/css/metacatui.responsive.css src/js/themes/default/img/favicons/manifest.json src/js/themes/knb/config.js src/js/themes/knb/css/metacatui.css src/js/themes/knb/css/metacatui.responsive.css src/js/themes/knb/img/favicons/manifest.json src/js/themes/knb/routers/router.js src/js/themes/knb/views/TextView.js src/js/views/AccessPolicyView.js src/js/views/AccessRuleView.js src/js/views/AltHeaderView.js src/js/views/AnnotationView.js src/js/views/AppView.js src/js/views/BarChartView.js src/js/views/CircleBadgeView.js src/js/views/CitationHeaderView.js src/js/views/CitationListView.js src/js/views/citations/CitationModalView.js src/js/views/CitationView.js src/js/views/ColorPaletteView.js src/js/views/DataCatalogView.js src/js/views/DataCatalogViewWithFilters.js src/js/views/DataItemView.js src/js/views/DataPackageView.js src/js/views/DataPreviewView.js src/js/views/DatasetView.js src/js/views/DonutChartView.js src/js/views/DownloadButtonView.js src/js/views/DraftsView.js src/js/views/EditCollectionView.js src/js/views/EditorView.js src/js/views/ExpandCollapseListView.js src/js/views/FeaturedDataView.js src/js/views/filters/BooleanFilterView.js src/js/views/filters/ChoiceFilterView.js src/js/views/filters/DateFilterView.js src/js/views/filters/FilterEditorView.js src/js/views/filters/FilterGroupsView.js src/js/views/filters/FilterGroupView.js src/js/views/filters/FilterView.js src/js/views/filters/NumericFilterView.js src/js/views/filters/SemanticFilterView.js src/js/views/filters/ToggleFilterView.js src/js/views/FooterView.js src/js/views/GroupListView.js src/js/views/ImageUploaderView.js src/js/views/IndexView.js src/js/views/LdapView.js src/js/views/LineChartView.js src/js/views/MainContentView.js src/js/views/maps/CesiumWidgetView.js src/js/views/maps/DrawToolView.js src/js/views/maps/FeatureInfoView.js src/js/views/maps/HelpPanelView.js src/js/views/maps/LayerCategoryItemView.js src/js/views/maps/LayerCategoryListView.js src/js/views/maps/LayerDetailsView.js src/js/views/maps/LayerDetailView.js src/js/views/maps/LayerInfoView.js src/js/views/maps/LayerItemView.js src/js/views/maps/LayerListView.js src/js/views/maps/LayerNavigationView.js src/js/views/maps/LayerOpacityView.js src/js/views/maps/LayersPanelView.js src/js/views/maps/LegendView.js src/js/views/maps/MapView.js src/js/views/maps/ScaleBarView.js src/js/views/maps/SearchInputView.js src/js/views/maps/ToolbarView.js src/js/views/maps/viewfinder/ExpansionPanelView.js src/js/views/maps/viewfinder/PredictionsListView.js src/js/views/maps/viewfinder/PredictionView.js src/js/views/maps/viewfinder/SearchView.js src/js/views/maps/viewfinder/ViewfinderView.js src/js/views/maps/viewfinder/ZoomPresetsListView.js src/js/views/maps/viewfinder/ZoomPresetView.js src/js/views/MapsView.js src/js/views/MarkdownEditorView.js src/js/views/MarkdownView.js src/js/views/MdqRunView.js src/js/views/metadata/EML211EditorView.js src/js/views/metadata/EML211MissingValueCodesView.js src/js/views/metadata/EML211MissingValueCodeView.js src/js/views/metadata/EML211View.js src/js/views/metadata/EMLAttributeView.js src/js/views/metadata/EMLEntityView.js src/js/views/metadata/EMLGeoCoverageView.js src/js/views/metadata/EMLMeasurementScaleView.js src/js/views/metadata/EMLMeasurementTypeView.js src/js/views/metadata/EMLMethodsView.js src/js/views/metadata/EMLOtherEntityView.js src/js/views/metadata/EMLPartyView.js src/js/views/metadata/EMLTaxonView.js src/js/views/metadata/EMLTempCoverageView.js src/js/views/metadata/ScienceMetadataView.js src/js/views/MetadataIndexView.js src/js/views/MetadataView.js src/js/views/MetricModalView.js src/js/views/MetricsChartView.js src/js/views/MetricView.js src/js/views/NavbarView.js src/js/views/PackageTableView.js src/js/views/PagerView.js src/js/views/portals/editor/PortalEditorView.js src/js/views/portals/editor/PortEditorDataView.js src/js/views/portals/editor/PortEditorImageView.js src/js/views/portals/editor/PortEditorLogosView.js src/js/views/portals/editor/PortEditorMdSectionView.js src/js/views/portals/editor/PortEditorSectionsView.js src/js/views/portals/editor/PortEditorSectionView.js src/js/views/portals/editor/PortEditorSettingsView.js src/js/views/portals/PortalDataView.js src/js/views/portals/PortalHeaderView.js src/js/views/portals/PortalListView.js src/js/views/portals/PortalLogosView.js src/js/views/portals/PortalMembersView.js src/js/views/portals/PortalMetricsView.js src/js/views/portals/PortalSectionView.js src/js/views/portals/PortalsSearchView.js src/js/views/portals/PortalUsagesView.js src/js/views/portals/PortalView.js src/js/views/portals/PortalVisualizationsView.js src/js/views/projects/ProjectView.js src/js/views/ProvChartView.js src/js/views/ProvEntitySelectView.js src/js/views/ProvStatementView.js src/js/views/queryBuilder/QueryBuilderView.js src/js/views/queryBuilder/QueryRuleView.js src/js/views/RegisterCitationView.js src/js/views/search/CatalogSearchView.js src/js/views/search/SearchResultsPagerView.js src/js/views/search/SearchResultsView.js src/js/views/search/SearchResultView.js src/js/views/search/SorterView.js src/js/views/SearchResultView.js src/js/views/searchSelect/AccountSelectView.js src/js/views/searchSelect/AnnotationFilterView.js src/js/views/searchSelect/NodeSelectView.js src/js/views/searchSelect/ObjectFormatSelectView.js src/js/views/searchSelect/QueryFieldSelectView.js src/js/views/searchSelect/SearchableSelectView.js src/js/views/SignInView.js src/js/views/StatsView.js src/js/views/TableEditorView.js src/js/views/TextView.js src/js/views/TOCView.js src/js/views/UserGroupView.js src/js/views/UserView.js src/loader.js test/config/appconfig.json test/config/tests.json test/index.html test/js/specs/integration/collections/SolrResults.spec.js test/js/specs/integration/models/LookupModel.js test/js/specs/shared/clean-state.js test/js/specs/shared/mock-gmaps-module.js test/js/specs/unit/collections/DataPackage.spec.js test/js/specs/unit/collections/maps/AssetCategories.spec.js test/js/specs/unit/collections/maps/Geohashes.spec.js test/js/specs/unit/collections/maps/GeoPoints.spec.js test/js/specs/unit/collections/metadata/eml/EMLMissingValueCodes.spec.js test/js/specs/unit/collections/ProjectList.spec.js test/js/specs/unit/collections/SolrResults.spec.js test/js/specs/unit/common/IconUtilities.spec.js test/js/specs/unit/common/Utilities.spec.js test/js/specs/unit/models/CitationModel.spec.js test/js/specs/unit/models/connectors/Filters-Map.spec.js test/js/specs/unit/models/connectors/GeoPoints-Cesium.spec.js test/js/specs/unit/models/connectors/GeoPoints-CesiumPoints.spec.js test/js/specs/unit/models/connectors/GeoPoints-CesiumPolygon.spec.js test/js/specs/unit/models/connectors/Map-Search.spec.js test/js/specs/unit/models/DataONEObject.spec.js test/js/specs/unit/models/filters/Filter.spec.js test/js/specs/unit/models/filters/NumericFilter.spec.js test/js/specs/unit/models/filters/SpatialFilter.spec.js test/js/specs/unit/models/geocoder/GeocodedLocation.spec.js test/js/specs/unit/models/geocoder/GeocoderSearch.spec.js test/js/specs/unit/models/geocoder/GoogleMapsAutocompleter.spec.js test/js/specs/unit/models/geocoder/GoogleMapsGeocoder.spec.js test/js/specs/unit/models/geocoder/Prediction.spec.js test/js/specs/unit/models/maps/AssetCategory.spec.js test/js/specs/unit/models/maps/assets/CesiumImagery.spec.js test/js/specs/unit/models/maps/GeoBoundingBox.spec.js test/js/specs/unit/models/maps/Geohash.spec.js test/js/specs/unit/models/maps/GeoPoint.spec.js test/js/specs/unit/models/maps/GeoScale.spec.js test/js/specs/unit/models/maps/GeoUtilities.spec.js test/js/specs/unit/models/maps/Map.spec.js test/js/specs/unit/models/maps/MapInteraction.spec.js test/js/specs/unit/models/maps/viewfinder/ExpansionPanelsModel.spec.js test/js/specs/unit/models/maps/viewfinder/ViewfinderModel.spec.js test/js/specs/unit/models/metadata/eml211/EML211.spec.js test/js/specs/unit/models/metadata/eml211/EMLAttribute.spec.js test/js/specs/unit/models/metadata/eml211/EMLDateTimeDomain.spec.js test/js/specs/unit/models/metadata/eml211/EMLDistribution.spec.js test/js/specs/unit/models/metadata/eml211/EMLEntity.spec.js test/js/specs/unit/models/metadata/eml211/EMLGeoCoverage.spec.js test/js/specs/unit/models/metadata/eml211/EMLMeasurementScale.spec.js test/js/specs/unit/models/metadata/eml211/EMLMethods.spec.js test/js/specs/unit/models/metadata/eml211/EMLMissingValueCode.spec.js test/js/specs/unit/models/metadata/eml211/EMLNonNumericDomain.spec.js test/js/specs/unit/models/metadata/eml211/EMLNumericDomain.spec.js test/js/specs/unit/models/metadata/eml211/EMLOtherEntity.spec.js test/js/specs/unit/models/metadata/eml211/EMLParty.spec.js test/js/specs/unit/models/metadata/eml211/EMLTemporalCoverage.spec.js test/js/specs/unit/models/project/Project.spec.js test/js/specs/unit/models/Search.spec.js test/js/specs/unit/models/SolrResult.spec.js test/js/specs/unit/views/maps/CesiumWidgetView.spec.js test/js/specs/unit/views/maps/LayerCategoryItemView.spec.js test/js/specs/unit/views/maps/LayerCategoryItemViewHarness.js test/js/specs/unit/views/maps/LayerItemView.spec.js test/js/specs/unit/views/maps/LayerItemViewHarness.js test/js/specs/unit/views/maps/LayersPanelView.spec.js test/js/specs/unit/views/maps/MapView.spec.js test/js/specs/unit/views/maps/SearchInputView.spec.js test/js/specs/unit/views/maps/SearchInputViewHarness.js test/js/specs/unit/views/maps/viewfinder/ExpansionPanelView.spec.js test/js/specs/unit/views/maps/viewfinder/ExpansionPanelViewHarness.js test/js/specs/unit/views/maps/viewfinder/PredictionsListView.spec.js test/js/specs/unit/views/maps/viewfinder/PredictionsListViewHarness.js test/js/specs/unit/views/maps/viewfinder/PredictionView.spec.js test/js/specs/unit/views/maps/viewfinder/PredictionViewHarness.js test/js/specs/unit/views/maps/viewfinder/SearchView.spec.js test/js/specs/unit/views/maps/viewfinder/SearchViewHarness.js test/js/specs/unit/views/maps/viewfinder/ViewfinderView.spec.js test/js/specs/unit/views/maps/viewfinder/ViewfinderViewHarness.js test/js/specs/unit/views/maps/viewfinder/ZoomPresetsListView.spec.js test/js/specs/unit/views/maps/viewfinder/ZoomPresetsListViewHarness.js test/js/specs/unit/views/maps/viewfinder/ZoomPresetView.spec.js test/js/specs/unit/views/maps/viewfinder/ZoomPresetViewHarness.js test/README.md test/scripts/README.md test/server.js ```
robyngit commented 1 month ago

Initial ESlint report

1871 problems (1871 errors, 0 warnings), over 228 files

📄 eslint-errors.html.txt

Note, these results are from a run in the src dir only, excluding src/components. We may also want to apply the same or other rules to /tests/ and /docs/

robyngit commented 1 month ago

I've been experimenting with using a publicly available config of linting rules, airbnb-base, which seem to be a popular set of standards to adopt. However, this leads to 30470 errors to fix within the src dir only, with 17659 that can be automatically corrected. These automatic corrections break parts of the site, like the new data catalog view, and it's difficult to track down why.

My plan is to revert back to the more simple eslint config, without airbnb-base, and start adopting those rules more gradually.

Here is the config that included airbnb and mostly worked with our set up ```js import globals from "globals"; import pluginJs from "@eslint/js"; import { FlatCompat } from "@eslint/eslintrc"; import path from "path"; import prettierConfig from "eslint-config-prettier"; import requirejs from "eslint-plugin-requirejs"; import { fileURLToPath } from "url"; // This chunk needed to use older style shared eslint configs, e.g. airbnb-base const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const compat = new FlatCompat({ baseDirectory: __dirname }); export default [ // This object must contain no other properties than ignores in order for it // to apply to all config objects in this array { ignores: ["src/components/"] }, // Use the recommended config for JS files pluginJs.configs.recommended, // Use the popular airbnb-base config, but extend it with our own rules ...compat.extends("airbnb-base"), // Lint all the main MetacatUI files { name: "lint-views-models-and-collections", files: ["src/**/*.js"], plugins: { requirejs }, languageOptions: { sourceType: "commonjs", ecmaVersion: 2020, globals: { ...globals.browser, ...globals.amd, MetacatUI: "readonly", } }, // Use requirejs.configs.recommended.rules and some of our own rules rules: { ...requirejs.configs.recommended.rules, "import/no-amd": "off", // We use AMD "no-console": "off", // We allow console.log for now "strict": ["error", "global"], // We use strict mode "func-names": "off", // require and backbone need to use unnamed functions } }, // Allow the prettier plugin to override any conflicting rules ...[].concat(prettierConfig), ]; ```
yvonnesjy commented 1 month ago

Is it possible to have lint only run on changed lines/files so we can fix as we go? I think incremental fixes might be more practical than incremental rules adoption

robyngit commented 1 month ago

thanks @yvonnesjy! 🧠⚡ That's exactly the strategy we landed on in a discussion with the broader dev team. So the rules will be more strict, and will include the airbnb set, but we'll just apply fixes as we touch each file.

robyngit commented 1 month ago

@yvonnesjy @ianguerin @ianguerin @rushirajnenuji - this PR is ready for review!

To test the new formatting & linting tools in this PR:

  1. gh pr checkout 2412
  2. npm install to add new dev dependencies
  3. npm run format to have prettier auto-format code (npm run format-check to see errors without making changes)
  4. npm run lint to see the linting errors (!!!)

The entire code base has been reformatted to use Prettier code style; however new linting standards will need to be implemented gradually. The PR introduces new GitHub actions to check for formatting & linting errors on new Pull Requests. See demo with auto generated comments pointing out errors and suggesting fixes where possible.

PR comments are only made where the linting errors apply to the lines of code that were changed. However, the GitHub action test will fail if there are linting errors in any part of the files changed. I think we can decide on a case-by-case basis whether to fix entire files or allow PRs through with some errors - a balance between improving our code quality and encouraging quick merging of new contributions.

The contributing guide has also been updated with these changes and generally cleaned up a bit: https://github.com/NCEAS/metacatui/blob/2284d194c5f5f1db3a374c316fb10a00a12bccb1/CONTRIBUTING.md

Looking for feedback on this strategy (👍🏻 or 👎🏻 ?) and also whether installing and using the new tools goes smoothly.

Note: Once this PR is merged into develop, there will likely be merge conflicts with any current feature branches. You may want to apply prettier formatting before merging with develop, see https://github.com/NCEAS/metacatui/issues/2096#issuecomment-2073387618 for details.

ianguerin commented 1 month ago

Wow the automated GitHub comments are going to be a huge improvement for code review experience! Installation worked for me. I was able to get the ESLint findings to show up in VSCode by installing the ESLint extension by Microsoft, and adding the following lines to my User Settings JSON file:

...
  "eslint.options": { "overrideConfigFile": "eslint.config.mjs" },
  "eslint.experimental.useFlatConfig": true,
...

I was able to get Prettier formatting to work in VSCode by installing the Prettier extension by Prettier. I bound a keyboard shortcut to format the document. I also installed Pretter ESLint by Rebecca Vest, but I'm not sure which formatter is more useful yet.

Thanks for working on this!

robyngit commented 1 month ago

Thanks for going through this @yvonnesjy! I recently discovered GitHub provides a UI for viewing PR changes commit by commit. The second commit is the one that changes nearly every file in the code base. The fourth commit also changes a lot of files to remove a special comment at the top of the file. Neither changes anything functionally, so I don't think those changes need to be reviewed file by file.

Here is a breakdown of each commit with links to the files changed in just those commits:

robyngit commented 1 month ago

@yvonnesjy thank you so much for reviewing so thoroughly!

typos in existing code might cause the formatter to misinterpret... if we ever run into surprise bugs that require rollbacks, we might want to consider breaking this down into smaller verifiable PR's so that we don't need to get everything right in one go

These are really good points and I suspect that we could run into some of these issues. I am going to move forward with the PR as-is so that we can get the formatting changes in place before too many merge conflicts arise with existing and WIP branches. I will definitely keep this strategy in mind for future PRs that change large amounts of code, and