From 2e6c777d001404010e0fef703b532e5acf5a7237 Mon Sep 17 00:00:00 2001 From: Troy Rosenberg Date: Sat, 21 Mar 2020 20:50:09 -0400 Subject: [PATCH] Fix output for multiline column comments 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 \# ``` --- lib/annotate/annotate_models.rb | 3 ++- spec/lib/annotate/annotate_models_spec.rb | 27 +++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/lib/annotate/annotate_models.rb b/lib/annotate/annotate_models.rb index bd85f1171..8351e1162 100644 --- a/lib/annotate/annotate_models.rb +++ b/lib/annotate/annotate_models.rb @@ -251,10 +251,11 @@ def get_schema_info(klass, header, options = {}) col_type = get_col_type(col) attrs = get_attributes(col, col_type, klass, options) col_name = if with_comments?(klass, options) && col.comment - "#{col.name}(#{col.comment})" + "#{col.name}(#{col.comment.gsub(/\n/, "\\n")})" else col.name end + if options[:format_rdoc] info << sprintf("# %-#{max_size}.#{max_size}s%s", "*#{col_name}*::", attrs.unshift(col_type).join(", ")).rstrip + "\n" elsif options[:format_yard] diff --git a/spec/lib/annotate/annotate_models_spec.rb b/spec/lib/annotate/annotate_models_spec.rb index d679734ac..3f0a977bc 100644 --- a/spec/lib/annotate/annotate_models_spec.rb +++ b/spec/lib/annotate/annotate_models_spec.rb @@ -1096,6 +1096,33 @@ def mock_column(name, type, options = {}) end end + context 'when columns have multiline comments' do + let :columns do + [ + mock_column(:id, :integer, limit: 8, comment: 'ID'), + mock_column(:notes, :text, limit: 55, comment: "Notes.\nMay include things like notes."), + mock_column(:no_comment, :text, limit: 20, comment: nil) + ] + end + + let :expected_result do + <<~EOS + # Schema Info + # + # Table name: users + # + # id(ID) :integer not null, primary key + # notes(Notes.\\nMay include things like notes.):text(55) not null + # no_comment :text(20) not null + # + EOS + end + + it 'works with option "with_comment"' do + is_expected.to eq expected_result + end + end + context 'when geometry columns are included' do let :columns do [