denisraslov / folderslint

πŸ“ Directory structure linter for Front-End projects
MIT License
183 stars 3 forks source link

Add support to folder case naming convention #19

Open fsmaia opened 2 years ago

fsmaia commented 2 years ago

Beyond to * wildcards, it would be amazing to add naming convention restrictions, like camelCase, PascalCases, kebab-case, CONSTANT_CASE, and others.

This would be very useful for React components folders, for instance:

components/MyComponent/...  # Valid
components/my-component/... # Invalid

Maybe this could be achieved by accepting special patterns like:

I'm super interested in helping and even implementing it if you will.

mattferrin commented 1 year ago

@fsmaia, I’m not recommending my Rust spin-off version, but I allowed regex. Regex starts with a slash, so I could distinguish between glob and regex rules easily and didn’t mix them.

Beyond mentioning regex, I haven’t thought hard enough to have any concrete opinions on user experience yet. Regex is hard.

Igorkowalski94 commented 1 year ago

As an alternative, you can use eslint-plugin-project-structure

Cloud Shows an illustrated sun in light mode and a moon with stars in dark mode. Cloud

FolderOwl
eslint‑plugin-project‑structure

ESLint plugin with rules to help you achieve a scalable, consistent, and well-structured project.

Create your own framework! Define your folder structure, advanced naming conventions, file composition, and create independent modules.

Take your project to the next level and save time by automating the review of key principles of a healthy project!

[![npm](https://img.shields.io/npm/v/eslint-plugin-project-structure.svg?&logo=nodedotjs&color=%231f6feb&labelColor=%23212830)](https://www.npmjs.com/package/eslint-plugin-project-structure#root)[![npm downloads](https://img.shields.io/npm/dy/eslint-plugin-project-structure.svg?&logo=nodedotjs&label=Downloads&color=%238957e5&labelColor=%23212830)](https://www.npmjs.com/package/eslint-plugin-project-structure#root)[![Check, test, build](https://img.shields.io/github/actions/workflow/status/Igorkowalski94/eslint-plugin-project-structure/check.yml?&logo=github&color=%23238636&label=Check%2C%20test%2C%20build&labelColor=%23212830)](https://github.com/Igorkowalski94/eslint-plugin-project-structure/actions/workflows/check.yml)[![Sponsor](https://img.shields.io/badge/Sponsor-grey?logo=githubsponsors&style=flat&color=%23212830)](https://github.com/sponsors/Igorkowalski94)[![GitHub Repo stars](https://img.shields.io/github/stars/igorkowalski94/eslint-plugin-project-structure?label=Star)](https://github.com/Igorkowalski94/eslint-plugin-project-structure)

project‑structure/​folder‑structure

Enforce rules on folder structure to keep your project consistent, orderly and well thought out.

Rocket Features:

- Validation of folder structure. Any files/folders outside the structure will be considered an error. - File/Folder name regex validation with features like wildcard `*` and treating `.` as a character, along with other conveniences. - Build in case validation. - Inheriting the folder's name. The file/folder inherits the name of the folder in which it is located. Option of adding your own prefixes/suffixes or changing the case. - Enforcing the existence of a files/folders when a specific file/folder exists. For example, if `./src/Component.tsx` exists, then `./src/Component.test.tsx` and `./src/stories/Component.stories.tsx` must also exist. - Reusable rules for folder structures. - An option to create a separate configuration file with TypeScript support. - Forcing a nested/flat structure for a given folder. - Support for all file extensions. - Folder recursion. You can repeatedly nest a folder structure and set a limit on the nesting depth. There is also an option to change the rule at the final level, such as flattening the folder structure. - Fewer repetitions and precise error messages, even for deeply nested folders (recursion), by representing the folder structure as a tree. - Checking the length of paths and notifying when the limit is exceeded.

project‑structure/​independent‑modules

A key principle of a healthy project is to prevent the creation of a massive dependency tree, where removing or editing one feature triggers a chain reaction that impacts the entire project.

Create independent modules to keep your project scalable and easy to maintain. Get rid of dependencies between modules and create truly independent functionalities.

Rocket Features:

- Creating independent modules in which you control what can be imported (e.g. types, functions, components of one functionality cannot be imported into another functionality). - The ability to create very detailed rules, even for nested folder structures. Whether it's a large module, a sub-module, or a single file, there are no limitations. - Disabling external imports (node_modules) for a given module (Option to add exceptions). - Non-relative/relative imports support. - Support for imports without extension. - Reusable import patterns. - Support for path aliases. The plugin will automatically detect your tsconfig.json and use your settings. There is also an option to enter them manually. - An option to create a separate configuration file with TypeScript support.

project‑structure/​file‑composition

Enforce advanced naming rules and prohibit the use of given selectors in a given file.

Have full control over what your file can contain and the naming conventions it must follow.

Rocket Features:

- File composition validation. - Supported selectors: `class`, `function`, `arrowFunction`, `type`, `interface`, `enum`, `variable`, `variableCallExpression`, `variableTaggedTemplateExpression`. - Rules for exported selectors, selectors in the root of the file and nested/all selectors in the file. They can be used together in combination. - Prohibit the use of given selectors in a given file. For example, `**/*.consts.ts` files can only contain variables, `**/*.types.ts` files can only contain enums, interfaces and types. - Enforcing a maximum of one main function/class per file. - Inheriting the filename as the selector name. Option to add your own prefixes/suffixes, change the case, or remove parts of the filename. - Selector name regex validation. - Build in case validation. - Different rules for different files. - An option to create a separate configuration file with TypeScript support.
mattferrin commented 1 year ago

@Igorkowalski94, it’s exciting that a repository seems to be getting traction to enforce folder structure. The keywords structure, children, rule, and name seem unwieldy though. Separating the config from eslint would aid readability too. I liked the simplicity of mine: https://github.com/mattferrin/folder-structure-lint

Perhaps you can use the traction you have to make simplifications that improve readability. Like having a list of simple string rules where every path in your source directory has to satisfy at least one. It’s more legible that way, in my opinion.

Igorkowalski94 commented 1 year ago

@mattferrin

Separating the config from eslint would aid readability too.

The entire configuration is located in a separate file.

The keywords structure, children, rule, and name seem unwieldy though.

It's rather subjective, it's much easier to write rules for folder recursion this way and there is much less need to repeat yourself, from what I see in your package it's not possible, same as inheriting a name from a parent.

I'm curious what the following structure would look like in your package. There would probably be a lot of repetitions and I don't see how folder recursion would work...

For example, you have a folder containing many file/folder rules and you want to repeat it recursively:

    πŸ“‚ hooks
    β”œβ”€β”€ ...
    β”œβ”€β”€ πŸ“„ useSimpleGlobalHook.test.ts
    β”œβ”€β”€ πŸ“„ useSimpleGlobalHook.ts
    └── πŸ“‚ useComplexGlobalHook
        β”œβ”€β”€ πŸ“ hooks (recursion)
        β”œβ”€β”€ πŸ“„ useComplexGlobalHook.api.ts
        β”œβ”€β”€ πŸ“„ useComplexGlobalHook.types.ts
        β”œβ”€β”€ πŸ“„ useComplexGlobalHook.test.ts
        └── πŸ“„ useComplexGlobalHook.ts

Also in my package you can mix Case with regex and parent name, here is an example.

And your package doesn't support eslint, so you can't see errors in real time.

mattferrin commented 1 year ago

@Igorkowalski94 Glob syntax allows for recursion so my tool does by extension. I probably didn’t demo it because I think it’s generally a bad idea.

I’ve never met 2 smart people that don’t disagree on something like that though. I valued simplicity so adding complex things to enforce complex things wasn’t aligned with my values. But I probably should have added support to enforce casing.