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

Fix output for multiline column comments #779

Merged
merged 1 commit into from
Apr 5, 2020

Conversation

tmr08c
Copy link
Contributor

@tmr08c tmr08c commented Mar 22, 2020

Closes #778

If a column comment includes the newline character, the newline character
would be "printed" into the annotation block resulting in a line break
and an uncommented line.

For example, for the following table:

create_table "users", force: :cascade do |t|
  t.string "name", comment: "This is a comment.\nWith two lines!"
  t.datetime "created_at", precision: 6, null: false
  t.datetime "updated_at", precision: 6, null: false
end

annotating the model with the --with-comment flag will result in:

\# == Schema Information
\#
\# Table name: users
\#
\#  id                                       :bigint           not null, primary key
\#  name(This is a comment.
With two lines!) :string
\#  created_at                               :datetime         not null
\#  updated_at                               :datetime         not null
\#

This uncommented line would result in invalid Ruby and cause the file to
no longer be valid.

This fix replaces the newline character with an escaped version, so the
output will look more like:

\# == Schema Information
\#
\# Table name: users
\#
\#  id                                       :bigint           not null, primary key
\#  name(This is a comment.\nWith two lines!):string
\#  created_at                               :datetime         not null
\#  updated_at                               :datetime         not null
\#

col_name = if with_comments?(klass, options) && col.comment
"#{col.name}(#{col.comment})"
"#{col.name}(#{col.comment.gsub(/\n/, "\\n")})"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to find something more general and elegant than gsub, but didn't find a good option. I'd be interested if there are other characters that would be concerning (\t?) that would make sense to check for and escape as well.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe there's a library for sanitizing whitespace? It might be worth looking into.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I looked a bit, but didn't find anything that stuck out. String#dump seemed promising, but I believe it escaped UTF characters that were expected to work.

I could make this more generic and escape any \ with \\ if that seems safer.

@drwl
Copy link
Collaborator

drwl commented Apr 5, 2020

Woah neat, I didn't know column comments were a thing.

@drwl
Copy link
Collaborator

drwl commented Apr 5, 2020

@tmr08c could you rebase and add comments to make the rubocop step part of CI pass? Happy to merge in after.

drwl pushed a commit that referenced this pull request Apr 5, 2020
This is a bit of a cheat of a refactoring that simply extracts the logic for collecting a column's attributes out of `get_schema_info` and into its own method (`get_attributes`).

I found that in PRs like #779 that the Rubocop ABC limit was being exceeded:

```
lib/annotate/annotate_models.rb:235:5: C: Metrics/AbcSize: Assignment Branch Condition size for get_schema_info is too high. [145/145]
    def get_schema_info(klass, header, options = {}) ...
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```

Hopefully, this should break this up and reduce the complexity of the method.

There are opportunities to go further, but I thought this could be a good place to start. 

I would be open and interested in discussing further refactoring opportunities if it would make sense (maybe creating some new classes to encapsulate some of this logic).
If a column comment includes the newline character, the newline character
would be "printed" into the annotation block resulting in a line break
and an uncommented line.

For example, for the following table:

```
create_table "users", force: :cascade do |t|
  t.string "name", comment: "This is a comment.\nWith two lines!"
  t.datetime "created_at", precision: 6, null: false
  t.datetime "updated_at", precision: 6, null: false
end
```

annotating the model with the `--with-comment` flag will result in:

```
\# == Schema Information
\#
\# Table name: users
\#
\#  id                                       :bigint           not null, primary key
\#  name(This is a comment.
With two lines!) :string
\#  created_at                               :datetime         not null
\#  updated_at                               :datetime         not null
\#
```

This uncommented line would result in invalid Ruby and cause the file to
no longer be valid.

This fix replaces the newline character with an escaped version, so the
output will look more like:

```
\# == Schema Information
\#
\# Table name: users
\#
\#  id                                       :bigint           not null, primary key
\#  name(This is a comment.\nWith two lines!):string
\#  created_at                               :datetime         not null
\#  updated_at                               :datetime         not null
\#
```
@tmr08c tmr08c force-pushed the tmr08c-fix-multi-line-comments branch from 74a2075 to 2e6c777 Compare April 5, 2020 14:55
@drwl drwl merged commit 214da4f into ctran:develop Apr 5, 2020
@tmr08c tmr08c deleted the tmr08c-fix-multi-line-comments branch April 6, 2020 10:40
vfonic pushed a commit to vfonic/annotate_models that referenced this pull request May 8, 2020
This is a bit of a cheat of a refactoring that simply extracts the logic for collecting a column's attributes out of `get_schema_info` and into its own method (`get_attributes`).

I found that in PRs like ctran#779 that the Rubocop ABC limit was being exceeded:

```
lib/annotate/annotate_models.rb:235:5: C: Metrics/AbcSize: Assignment Branch Condition size for get_schema_info is too high. [145/145]
    def get_schema_info(klass, header, options = {}) ...
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```

Hopefully, this should break this up and reduce the complexity of the method.

There are opportunities to go further, but I thought this could be a good place to start. 

I would be open and interested in discussing further refactoring opportunities if it would make sense (maybe creating some new classes to encapsulate some of this logic).
vfonic pushed a commit to vfonic/annotate_models that referenced this pull request May 8, 2020
Closes ctran#778 

If a column comment includes the newline character, the newline character
would be "printed" into the annotation block resulting in a line break
and an uncommented line.

For example, for the following table:

```
create_table "users", force: :cascade do |t|
  t.string "name", comment: "This is a comment.\nWith two lines!"
  t.datetime "created_at", precision: 6, null: false
  t.datetime "updated_at", precision: 6, null: false
end
```

annotating the model with the `--with-comment` flag will result in:

```
\# == Schema Information
\#
\# Table name: users
\#
\#  id                                       :bigint           not null, primary key
\#  name(This is a comment.
With two lines!) :string
\#  created_at                               :datetime         not null
\#  updated_at                               :datetime         not null
\#
```

This uncommented line would result in invalid Ruby and cause the file to
no longer be valid.

This fix replaces the newline character with an escaped version, so the
output will look more like:

```
\# == Schema Information
\#
\# Table name: users
\#
\#  id                                       :bigint           not null, primary key
\#  name(This is a comment.\nWith two lines!):string
\#  created_at                               :datetime         not null
\#  updated_at                               :datetime         not null
\#
```
ocarta-l pushed a commit to ocarta-l/annotate_models that referenced this pull request Jun 18, 2021
This is a bit of a cheat of a refactoring that simply extracts the logic for collecting a column's attributes out of `get_schema_info` and into its own method (`get_attributes`).

I found that in PRs like ctran#779 that the Rubocop ABC limit was being exceeded:

```
lib/annotate/annotate_models.rb:235:5: C: Metrics/AbcSize: Assignment Branch Condition size for get_schema_info is too high. [145/145]
    def get_schema_info(klass, header, options = {}) ...
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```

Hopefully, this should break this up and reduce the complexity of the method.

There are opportunities to go further, but I thought this could be a good place to start. 

I would be open and interested in discussing further refactoring opportunities if it would make sense (maybe creating some new classes to encapsulate some of this logic).
ocarta-l pushed a commit to ocarta-l/annotate_models that referenced this pull request Jun 18, 2021
Closes ctran#778 

If a column comment includes the newline character, the newline character
would be "printed" into the annotation block resulting in a line break
and an uncommented line.

For example, for the following table:

```
create_table "users", force: :cascade do |t|
  t.string "name", comment: "This is a comment.\nWith two lines!"
  t.datetime "created_at", precision: 6, null: false
  t.datetime "updated_at", precision: 6, null: false
end
```

annotating the model with the `--with-comment` flag will result in:

```
\# == Schema Information
\#
\# Table name: users
\#
\#  id                                       :bigint           not null, primary key
\#  name(This is a comment.
With two lines!) :string
\#  created_at                               :datetime         not null
\#  updated_at                               :datetime         not null
\#
```

This uncommented line would result in invalid Ruby and cause the file to
no longer be valid.

This fix replaces the newline character with an escaped version, so the
output will look more like:

```
\# == Schema Information
\#
\# Table name: users
\#
\#  id                                       :bigint           not null, primary key
\#  name(This is a comment.\nWith two lines!):string
\#  created_at                               :datetime         not null
\#  updated_at                               :datetime         not null
\#
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Issue generating annotations when a column comment has newline character
2 participants