Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proposal: bin_files_must_export_main #57130

Open
jonasfj opened this issue Jun 18, 2024 · 4 comments
Open

proposal: bin_files_must_export_main #57130

jonasfj opened this issue Jun 18, 2024 · 4 comments
Labels
analyzer-linter Issues with the analyzer's support for the linter package area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion. linter-lint-proposal linter-status-pending type-enhancement A request for a change that isn't a bug

Comments

@jonasfj
Copy link
Member

jonasfj commented Jun 18, 2024

bin_files_must_export_main

Could also be called:

  • no_libraries_in_bin
  • executable_without_main

Description

Dart files in bin/ should export a main function that can serve as entrypoint for an executable.

Details

Files in the bin/ folder can be executed using dart run in your package, or any package that has a dependency on your package. Private scripts should be placed in tool/ and private libraries should be placed in lib/src/.

See package layout conventions.

Kind

This aims to guard against errors.

Bad Examples

# bin/foo.dart

const myFoo = 42;

Good Examples

# bin/foo.dart

void main() {
  print('hello world');
}

or

# bin/foo.dart

// You can export 'main' from a library, that's okay too.
export 'package:foo/src/foo.dart' show main;

Discussion

  • dart run foo will run bin/foo.dart from package:foo (requires that package :foo is either a dependency or the name of the root package).
  • dart run foo:bar will run bin/bar.dart from package:foo.
  • dart pub global run foo will run bin/foo.dart from package:foo.
  • The executables section in pubspec.yaml offers the creation of binstubs for files in bin/.
  • pana will assign packages with files in bin/ as has:executable.

It could be argued that this lint should only be enabled for packages that have a version and doesn't feature publish_to: none in the pubspec.yaml.
Though, there is no reason for other packages / apps to put libraries in bin/, this folder should be reserved for executables.

Motiviation

  • Package layout convention
  • has:executable search tag on pub.dev
    • This is granted by pana analysis.
    • We want packages that match this tag to have executable files in bin/.
    • We could make a check for this in pana, and score on this basis. But it's probably better UX to give a lint directly in the editor. That way authors will know it sooner rather than later.

cc @sigurdm, @isoos

@srawlins
Copy link
Member

I love this! Definitely missing.

One question: what about files in bin/some_lib/? Not that I've ever seen this or have any motivation to write such files 😛 . But they cannot be directly executed with pub run, right? Let's say you have some long and complex bin code, so you want to separate into separate files. But you absolutely do not want to put those separate files in lib/src (where they'd be accessible from dependents, even if it's frowned upon). And you don't want to do something like import '../tool/src/abc.dart'. So maybe you could put those impl files in bin/src/?

Anyways, we don't need an official policy for how to split up bin source files, except to say that files immediately in bin/ need a main method, and there is no restriction on files in any subdirectory in bin/.

@isoos
Copy link

isoos commented Jun 18, 2024

Anyways, we don't need an official policy for how to split up bin source files, except to say that files immediately in bin/ need a main method, and there is no restriction on files in any subdirectory in bin/.

Sidenote: the main method doesn't need to be present in the file in bin/<x>.dart it could use export to pull it in.

@jonasfj
Copy link
Member Author

jonasfj commented Jun 21, 2024

Anyways, we don't need an official policy for how to split up bin source files, except to say that files immediately in bin/ need a main method, and there is no restriction on files in any subdirectory in bin/.

I think it's fine if we focus on files in bin/ only. And ignore subdirectories of bin/.

Though, people really should put their binary implementation files in lib/src/, otherwise they are not reachable with a package:<mypk>/src/.. URI.

I suppose it's possible to put files in test/, or tool/ or whatever/, but then you're far outside anything we recommend or support. And who knows maybe we'll make diagnostics discouraging such things in the future -- I think that's orthogonal to this issue.


Side note: Files in test/ that ends with _test.dart should probably also have a main function, right?

@jonasfj
Copy link
Member Author

jonasfj commented Jun 21, 2024

Somewhat related, I propsoed a validator for executables section in pubspec.yaml here:
https://dart-review.googlesource.com/c/sdk/+/372302

But I think this shouldn't look inside the files to see if there is a main, it's better to make a separate lint (or diagnostic) that does this.


Actually, on that topic: I think we should consider making bin_files_must_export_main as proposed here a diagnostic warning, instead of a lint.

@srawlins srawlins added the type-enhancement A request for a change that isn't a bug label Jun 21, 2024
@devoncarew devoncarew transferred this issue from dart-lang/linter Nov 18, 2024
@devoncarew devoncarew added analyzer-linter Issues with the analyzer's support for the linter package area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion. labels Nov 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
analyzer-linter Issues with the analyzer's support for the linter package area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion. linter-lint-proposal linter-status-pending type-enhancement A request for a change that isn't a bug
Projects
None yet
Development

No branches or pull requests

4 participants