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

Check for license #209

Closed
marcusklaas opened this issue Aug 27, 2015 · 8 comments
Closed

Check for license #209

marcusklaas opened this issue Aug 27, 2015 · 8 comments
Labels
good first issue Issues up for grabs, also good candidates for new rustfmt contributors

Comments

@marcusklaas
Copy link
Contributor

License should probably be a configuration option.

cc https://github.com/nrc/rustfmt/issues/20

@marcusklaas marcusklaas added the good first issue Issues up for grabs, also good candidates for new rustfmt contributors label Aug 27, 2015
@scyptnex
Copy link

Working on this.

In my current implementation, the user specifies if they want the license to be from a file (license_policy="FileLicense") or a string (license_policy="TextLicense"), Since rustfmt's top-of-src license directs you to the 'file at the top level of this distribution', it would be a TextLicense.

There are some implications concerning the default configuration for this code, specifically, what is a reasonable default behaviour for the license?

Also there are legal implications, This code could be used to keep the licenses for an entire codebase up to date, but the result is that it overwrites some license that is at the top of a file. A naive user could accidentally overwrite someone else's license with their own

@marcusklaas
Copy link
Contributor Author

My initial idea was that we would simply warn on a missing (or inconsistent) license. Keeping licenses up to date by hand shouldn't be too much work and your last point certainly is significant as well.

@nrc nrc added this to the 1.0 milestone Apr 6, 2016
@kamalmarhubi
Copy link
Contributor

kamalmarhubi commented Jun 1, 2016

This sounds fiddly. Copyright dates in license headers will differ across a codebase for example. Could you define more clearly how you're thinking this would work? I can imagine:

  • heuristically track license headers and warn if they're inconsistent (user friendly, but probably a messy implementation to not be noisy)
  • some kind of optional template for a comment that must appear at the top of source files

Were either of these what you had in mind?

@nrc
Copy link
Member

nrc commented Jun 1, 2016

The latter - user supplies a license template, we check for it on every file, warn if one is missing. Added extra - default template values and insert a license where it is missing.

@nrc nrc removed this from the 1.0 milestone Jun 15, 2017
@opilar
Copy link
Contributor

opilar commented Sep 21, 2017

Hi! Seems no progress. I would like to help.
Can someone to help me with the implementation?
I don't know how to add this rule.
How user should supply a license template?

@nrc
Copy link
Member

nrc commented Sep 21, 2017

Implementation steps (kinda guesswork, feel free to change as needed)

  • add a license_template config option which specifies a path to a license template file
  • add code to the driver (lib.rs) which if that option is set, and the path can be read, adds the template to the context before we start formatting.
  • add code to the driver such that when we start formatting a new file, we call a new function check_license on that file
  • check_license should return early if there is no template
  • to start with, just check that the file starts with the license template
  • then add templating features - for a first PR, I would allow {} in the template and interpret this to mean any text. This should be easy to implement using a regex and replacing {} with .*. The tricky thing is escaping the license text (which is why I don't propose using a regex for the template).

@opilar let me know if you have any questions and thanks for jumping on this!

dlukes added a commit to dlukes/rustfmt that referenced this issue Feb 16, 2018
dlukes added a commit to dlukes/rustfmt that referenced this issue Feb 16, 2018
dlukes added a commit to dlukes/rustfmt that referenced this issue Feb 16, 2018
I'm not quite sure how best to handle loading the license template from
a path -- I mean obviously I know *how* to do it, but I'm not sure where
to fit it in the codebase :) So this first attempt puts the license
template directly into the config file.

These are my misgivings about the license template config option as a
path to a file (I'd love feedback if some of these are wrong or can be
easily circumvented!):

1. I thought the obvious choice for the type of `license_template` in
`create_config!` should be `PathBuf`, but `PathBuf` doesn't implement
`FromStr` (yet? see rust-lang/rust#44431), so
it would have to be wrapped in a tuple struct, and I went down that road
for a little while but then it seemed like too much ceremony for too
little gain.

2. So a plain `String` then (which, mind you, also means the same
`doc_hint()`, i.e. `<string>`, not `<path>` or something like that). The
fact that it's a valid path will be checked once we try to read the
file.

3. But where in the code should the license template be read? The
obvious choice for me would be somewhere in `Config::from_toml()`, but
since `Config` is defined via the `create_config!` macro, that would
mean tight coupling between the macro invocation (which defines the
configuration option `license_template`) and its definition (which would
rely on the existence of that option to run the template loading code).

4. `license_template` could also be made a special option which is
hardwired into the macro. This gets rid of the tight coupling, but
special-casing one of the config options would make the code harder to
navigate.

5. The macro could maybe be rewritten to allow for config options that
load additional resources from files when the config is being parsed,
but that's beyond my skill level I'm afraid (and probably
overengineering the problem if it's only ever going to be used for this
one option).

6. Finally, the file can be loaded at some later point in time, e.g. in
`format_lines()`, right before `check_license()` is called. But to
face a potential *IO* error at so late a stage, when the source files
have already been parsed... I don't know, it doesn't feel right.

BTW I don't like that I'm actually parsing the license template as late
as inside `check_license()` either, but for much the same reasons, I
don't know where else to put it. If the `Config` were hand-rolled
instead of a macro, I'd just define a custom `license_template` option
and load and parse the template in the `Config`'s init. But the way
things are, I'm a bit at a loss.

However, if someone more familiar with the project would kindly provide
a few hints as to how the path approach can be done in a way that is as
clean as possible in the context of the codebase, I'll be more than
happy to implement it! :)
dlukes added a commit to dlukes/rustfmt that referenced this issue Feb 16, 2018
I'm not quite sure how best to handle loading the license template from
a path -- I mean obviously I know *how* to do it, but I'm not sure where
to fit it in the codebase :) So this first attempt puts the license
template directly into the config file.

These are my misgivings about the license template config option as a
path to a file (I'd love feedback if some of these are wrong or can be
easily circumvented!):

1. I thought the obvious choice for the type of `license_template` in
`create_config!` should be `PathBuf`, but `PathBuf` doesn't implement
`FromStr` (yet? see rust-lang/rust#44431), so
it would have to be wrapped in a tuple struct, and I went down that road
for a little while but then it seemed like too much ceremony for too
little gain.

2. So a plain `String` then (which, mind you, also means the same
`doc_hint()`, i.e. `<string>`, not `<path>` or something like that). The
fact that it's a valid path will be checked once we try to read the
file.

3. But where in the code should the license template be read? The
obvious choice for me would be somewhere in `Config::from_toml()`, but
since `Config` is defined via the `create_config!` macro, that would
mean tight coupling between the macro invocation (which defines the
configuration option `license_template`) and its definition (which would
rely on the existence of that option to run the template loading code).

4. `license_template` could also be made a special option which is
hardwired into the macro. This gets rid of the tight coupling, but
special-casing one of the config options would make the code harder to
navigate.

5. Instead, the macro could maybe be rewritten to allow for config
options that load additional resources from files when the config is
being parsed, but that's beyond my skill level I'm afraid (and probably
overengineering the problem if it's only ever going to be used for this
one option).

6. Finally, the file can be loaded at some later point in time, e.g. in
`format_lines()`, right before `check_license()` is called. But to
face a potential *IO* error at so late a stage, when the source files
have already been parsed... I don't know, it doesn't feel right.

BTW I don't like that I'm actually parsing the license template as late
as inside `check_license()` either, but for much the same reasons, I
don't know where else to put it. If the `Config` were hand-rolled
instead of a macro, I'd just define a custom `license_template` option
and load and parse the template in the `Config`'s init. But the way
things are, I'm a bit at a loss.

However, if someone more familiar with the project would kindly provide
a few hints as to how the path approach can be done in a way that is as
clean as possible in the context of the codebase, I'll be more than
happy to implement it! :)
dlukes added a commit to dlukes/rustfmt that referenced this issue Feb 16, 2018
I'm not quite sure how best to handle loading the license template from
a path -- I mean obviously I know *how* to do it, but I'm not sure where
to fit it in the codebase :) So this first attempt puts the license
template directly into the config file.

These are my misgivings about the license template config option as a
path to a file (I'd love feedback if some of these are wrong or can be
easily circumvented!):

1. I thought the obvious choice for the type of `license_template` in
`create_config!` should be `PathBuf`, but `PathBuf` doesn't implement
`FromStr` (yet? see rust-lang/rust#44431), so
it would have to be wrapped in a tuple struct, and I went down that road
for a little while but then it seemed like too much ceremony for too
little gain.

2. So a plain `String` then (which, mind you, also means the same
`doc_hint()`, i.e. `<string>`, not `<path>` or something like that). The
fact that it's a valid path will be checked once we try to read the
file.

3. But where in the code should the license template be read? The
obvious choice for me would be somewhere in `Config::from_toml()`, but
since `Config` is defined via the `create_config!` macro, that would
mean tight coupling between the macro invocation (which defines the
configuration option `license_template`) and its definition (which would
rely on the existence of that option to run the template loading code).

4. `license_template` could also be made a special option which is
hardwired into the macro. This gets rid of the tight coupling, but
special-casing one of the config options would make the code harder to
navigate.

5. Instead, the macro could maybe be rewritten to allow for config
options that load additional resources from files when the config is
being parsed, but that's beyond my skill level I'm afraid (and probably
overengineering the problem if it's only ever going to be used for this
one option).

6. Finally, the file can be loaded at some later point in time, e.g. in
`format_lines()`, right before `check_license()` is called. But to
face a potential *IO* error at so late a stage, when the source files
have already been parsed... I don't know, it doesn't feel right.

BTW I don't like that I'm actually parsing the license template as late
as inside `check_license()` either, but for much the same reasons, I
don't know where else to put it. If the `Config` were hand-rolled
instead of a macro, I'd just define a custom `license_template` option
and load and parse the template in the `Config`'s init. But the way
things are, I'm a bit at a loss.

However, if someone more familiar with the project would kindly provide
a few hints as to how the path approach can be done in a way that is as
clean as possible in the context of the codebase, I'll be more than
happy to implement it! :)
@dlukes
Copy link
Contributor

dlukes commented Feb 16, 2018

I hope you don't mind, but since there hasn't been any activity on this since September, I took a stab at it :) Trying to learn to find my way around other people's Rust code. I hit some snags though and I can't seem to come up with a satisfactory solution, please see #2456 for details.

dlukes added a commit to dlukes/rustfmt that referenced this issue Mar 5, 2018
I'm not quite sure how best to handle loading the license template from
a path -- I mean obviously I know *how* to do it, but I'm not sure where
to fit it in the codebase :) So this first attempt puts the license
template directly into the config file.

These are my misgivings about the license template config option as a
path to a file (I'd love feedback if some of these are wrong or can be
easily circumvented!):

1. I thought the obvious choice for the type of `license_template` in
`create_config!` should be `PathBuf`, but `PathBuf` doesn't implement
`FromStr` (yet? see rust-lang/rust#44431), so
it would have to be wrapped in a tuple struct, and I went down that road
for a little while but then it seemed like too much ceremony for too
little gain.

2. So a plain `String` then (which, mind you, also means the same
`doc_hint()`, i.e. `<string>`, not `<path>` or something like that). The
fact that it's a valid path will be checked once we try to read the
file.

3. But where in the code should the license template be read? The
obvious choice for me would be somewhere in `Config::from_toml()`, but
since `Config` is defined via the `create_config!` macro, that would
mean tight coupling between the macro invocation (which defines the
configuration option `license_template`) and its definition (which would
rely on the existence of that option to run the template loading code).

4. `license_template` could also be made a special option which is
hardwired into the macro. This gets rid of the tight coupling, but
special-casing one of the config options would make the code harder to
navigate.

5. Instead, the macro could maybe be rewritten to allow for config
options that load additional resources from files when the config is
being parsed, but that's beyond my skill level I'm afraid (and probably
overengineering the problem if it's only ever going to be used for this
one option).

6. Finally, the file can be loaded at some later point in time, e.g. in
`format_lines()`, right before `check_license()` is called. But to
face a potential *IO* error at so late a stage, when the source files
have already been parsed... I don't know, it doesn't feel right.

BTW I don't like that I'm actually parsing the license template as late
as inside `check_license()` either, but for much the same reasons, I
don't know where else to put it. If the `Config` were hand-rolled
instead of a macro, I'd just define a custom `license_template` option
and load and parse the template in the `Config`'s init. But the way
things are, I'm a bit at a loss.

However, if someone more familiar with the project would kindly provide
a few hints as to how the path approach can be done in a way that is as
clean as possible in the context of the codebase, I'll be more than
happy to implement it! :)
nrc added a commit that referenced this issue Mar 8, 2018
@dlukes
Copy link
Contributor

dlukes commented Mar 10, 2018

I think this can be closed now in light of #2456? :)

@nrc nrc closed this as completed Mar 11, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue Issues up for grabs, also good candidates for new rustfmt contributors
Projects
None yet
Development

No branches or pull requests

6 participants