protofire / solhint

Solhint is an open-source project to provide a linting utility for Solidity code.
https://protofire.github.io/solhint/
MIT License
1.01k stars 154 forks source link

Feature request: rule for ordering imports topologically and alphabetically #571

Open PaulRBerg opened 2 months ago

PaulRBerg commented 2 months ago

It would be helpful if Solhint offered a rule for ordering imports topologically and alphabetically.

Rationale: this is a non-opinionated code design that lessens the cognitive load on users.

Example of PR where we manually ordered the imports: https://github.com/sablier-labs/v2-periphery/pull/301

I propose the following logic:

dbale-altoros commented 2 months ago

thanks @PaulRBerg for posting I'll check what can be done about this

PaulRBerg commented 2 weeks ago

Can we sponsor you with a bounty to work on this, @dbale-altoros? feel free to share your Ethereum address on Telegram.

dbale-altoros commented 1 week ago

Hi @PaulRBerg i'm on vacations. I'll contact you this friday o next monday

dbale-altoros commented 3 days ago

@PaulRBerg I was starting to do this Just to be on the same page The rule will support these kind of imports

Import parts of a file

Import parts and define alias

Import the whole file

Regarding the hierarchy I will put a sample of unsorted imports Would you mind ordering in the way you think it should be

import './ThisIsAVeryLongFileOnPurposeToTestTheFirstPathShorterThanTheLastOnelooooooooooong.sol';
import {Unauthorized, add as func, Point} from "./Foo.sol";
import "https://github.com/owner/repo/blob/branch/path/to/Contract.sol";
import {Initializable} from './openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol';
import '../../../../token/interfaces/FakeContract1.sol';
import {FakeContract3} from '../../../token/interfaces/FakeContract3.sol';
import './../../../../token/interfaces/AFakeContract1.sol';
import './../token/interfaces/IXTokenWrapper.sol';
import {IXTokenFactory, holaquetal} from '../../token/interfaces/IXTokenFactory.sol';
import '@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol';
import {FakeContract2} from '../../../token/interfaces/FakeContract2.sol';
import "http://github.com/owner/repo/blob/branch/path/to/Contract2.sol";
import {Afool1} from './Afool1.sol';
import "./Ownable.sol";
import {IXTokenWrapper2} from '../token/interfaces/IXTokenWrapper2.sol';
import {ReentrancyGuardUpgradeable2} from '@apenzeppelin/ReentrancyGuardUpgradeable2.sol';

take into account there are paths like this ./../../folder/file.sol which are at the same level as ../../folder/file.sol

PaulRBerg commented 3 days ago

thank you @dbale-altoros

adding @smol-ninja and @andreivladbrg for help here