Skip to content

Commit

Permalink
Merge pull request #47779 from zzak/mdl
Browse files Browse the repository at this point in the history
Introduce markdownlint for guides
  • Loading branch information
rafaelfranca committed Mar 29, 2023
2 parents ddd6f8e + c3f2b54 commit 4d171a4
Show file tree
Hide file tree
Showing 26 changed files with 177 additions and 91 deletions.
24 changes: 24 additions & 0 deletions .github/workflows/mdl.yml
@@ -0,0 +1,24 @@
name: Markdown Lint [Guides]

on: [pull_request]

permissions:
contents: read

jobs:
mdl:
runs-on: ubuntu-latest
env:
BUNDLE_ONLY: mdl

steps:
- uses: actions/checkout@v3

- name: Set up Ruby 3.2
uses: ruby/setup-ruby@v1
with:
ruby-version: 3.2
bundler-cache: true

- name: Run mdl
run: bundle exec rake -f guides/Rakefile guides:lint
1 change: 1 addition & 0 deletions .mdlrc
@@ -0,0 +1 @@
style "#{File.dirname(__FILE__)}/.mdlrc.rb"
23 changes: 23 additions & 0 deletions .mdlrc.rb
@@ -0,0 +1,23 @@
# frozen_string_literal: true

all

exclude_rule "MD003"
exclude_rule "MD004"
exclude_rule "MD005"
exclude_rule "MD006"
exclude_rule "MD007"
exclude_rule "MD012"
exclude_rule "MD014"
exclude_rule "MD024"
exclude_rule "MD026"
exclude_rule "MD033"
exclude_rule "MD034"
exclude_rule "MD036"
exclude_rule "MD040"
exclude_rule "MD041"

rule "MD013", line_length: 2000, ignore_code_blocks: true
# rule "MD024", allow_different_nesting: true # This did not work as intended, see action_cable_overview.md
rule "MD029", style: :ordered
# rule "MD046", style: :consistent # default (:fenced)
5 changes: 5 additions & 0 deletions Gemfile
Expand Up @@ -49,6 +49,11 @@ group :rubocop do
gem "rubocop-md", require: false
end

group :mdl do
gem "mdl", require: false
gem "rake", ">= 13", require: false
end

group :doc do
gem "sdoc", ">= 2.6.0"
gem "rdoc", "~> 6.5"
Expand Down
21 changes: 20 additions & 1 deletion Gemfile.lock
Expand Up @@ -159,6 +159,8 @@ GEM
regexp_parser (>= 1.5, < 3.0)
xpath (~> 3.2)
cgi (0.3.6)
chef-utils (18.1.29)
concurrent-ruby
concurrent-ruby (1.1.10)
connection_pool (2.3.0)
crack (0.4.5)
Expand Down Expand Up @@ -274,6 +276,10 @@ GEM
railties (>= 6.0.0)
json (2.6.3)
jwt (2.6.0)
kramdown (2.4.0)
rexml
kramdown-parser-gfm (1.1.0)
kramdown (~> 2.0)
libxml-ruby (4.0.0)
listen (3.8.0)
rb-fsevent (~> 0.10, >= 0.10.3)
Expand All @@ -288,6 +294,12 @@ GEM
net-smtp
marcel (1.0.2)
matrix (0.4.2)
mdl (0.12.0)
kramdown (~> 2.3)
kramdown-parser-gfm (~> 1.1)
mixlib-cli (~> 2.1, >= 2.1.1)
mixlib-config (>= 2.2.1, < 4)
mixlib-shellout
memoist (0.16.2)
mini_magick (4.12.0)
mini_mime (1.1.2)
Expand All @@ -302,6 +314,11 @@ GEM
minitest (>= 5.0)
minitest-server (1.0.7)
minitest (~> 5.16)
mixlib-cli (2.1.8)
mixlib-config (3.0.27)
tomlrb
mixlib-shellout (3.2.7)
chef-utils
mono_logger (1.1.1)
msgpack (1.6.0)
multi_json (1.15.0)
Expand Down Expand Up @@ -406,7 +423,7 @@ GEM
rubocop-ast (>= 1.26.0, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 3.0)
rubocop-ast (1.27.0)
rubocop-ast (1.28.0)
parser (>= 3.2.1.0)
rubocop-md (1.2.0)
rubocop (>= 1.0)
Expand Down Expand Up @@ -488,6 +505,7 @@ GEM
thor (1.2.1)
tilt (2.0.11)
timeout (0.3.2)
tomlrb (2.0.3)
trailblazer-option (0.1.2)
turbo-rails (1.3.2)
actionpack (>= 6.0.0)
Expand Down Expand Up @@ -557,6 +575,7 @@ DEPENDENCIES
json (>= 2.0.0)
libxml-ruby
listen (~> 3.3)
mdl
minitest (>= 5.15.0)
minitest-bisect
minitest-ci
Expand Down
8 changes: 8 additions & 0 deletions guides/Rakefile
Expand Up @@ -24,6 +24,14 @@ namespace :guides do
end
end

desc "Lint guides, using `mdl`"
task :lint do
require "mdl"
all = Dir.glob("#{__dir__}/source/*.md")
files = all - Dir.glob("#{__dir__}/**/*_release_notes.md") # Ignore release notes
MarkdownLint.run files
end

# Validate guides -------------------------------------------------------------------------
desc 'Validate guides, use ONLY=foo to process just "foo.html"'
task :validate do
Expand Down
28 changes: 14 additions & 14 deletions guides/source/action_cable_overview.md
Expand Up @@ -651,28 +651,28 @@ consumer.subscriptions.create("AppearanceChannel", {
#### Client-Server Interaction
1. **Client** connects to the **Server** via `createConsumer()`. (`consumer.js`). The
**Server** identifies this connection by `current_user`.
**Server** identifies this connection by `current_user`.
2. **Client** subscribes to the appearance channel via
`consumer.subscriptions.create({ channel: "AppearanceChannel" })`. (`appearance_channel.js`)
`consumer.subscriptions.create({ channel: "AppearanceChannel" })`. (`appearance_channel.js`)
3. **Server** recognizes a new subscription has been initiated for the
appearance channel and runs its `subscribed` callback, calling the `appear`
method on `current_user`. (`appearance_channel.rb`)
appearance channel and runs its `subscribed` callback, calling the `appear`
method on `current_user`. (`appearance_channel.rb`)
4. **Client** recognizes that a subscription has been established and calls
`connected` (`appearance_channel.js`), which in turn calls `install` and `appear`.
`appear` calls `AppearanceChannel#appear(data)` on the server, and supplies a
data hash of `{ appearing_on: this.appearingOn }`. This is
possible because the server-side channel instance automatically exposes all
public methods declared on the class (minus the callbacks), so that these can be
reached as remote procedure calls via a subscription's `perform` method.
`connected` (`appearance_channel.js`), which in turn calls `install` and `appear`.
`appear` calls `AppearanceChannel#appear(data)` on the server, and supplies a
data hash of `{ appearing_on: this.appearingOn }`. This is
possible because the server-side channel instance automatically exposes all
public methods declared on the class (minus the callbacks), so that these can be
reached as remote procedure calls via a subscription's `perform` method.
5. **Server** receives the request for the `appear` action on the appearance
channel for the connection identified by `current_user`
(`appearance_channel.rb`). **Server** retrieves the data with the
`:appearing_on` key from the data hash and sets it as the value for the `:on`
key being passed to `current_user.appear`.
channel for the connection identified by `current_user`
(`appearance_channel.rb`). **Server** retrieves the data with the
`:appearing_on` key from the data hash and sets it as the value for the `:on`
key being passed to `current_user.appear`.
### Example 2: Receiving New Web Notifications
Expand Down
6 changes: 3 additions & 3 deletions guides/source/action_mailer_basics.md
Expand Up @@ -116,10 +116,10 @@ a full list of all available options, please have a look further down at the
Complete List of Action Mailer user-settable attributes section.

* The [`default`][] method sets default values for all emails sent from
this mailer. In this case, we use it to set the `:from` header value for all
messages in this class. This can be overridden on a per-email basis.
this mailer. In this case, we use it to set the `:from` header value for all
messages in this class. This can be overridden on a per-email basis.
* The [`mail`][] method creates the actual email message. We use it to specify
the values of headers like `:to` and `:subject` per email.
the values of headers like `:to` and `:subject` per email.

[`default`]: https://api.rubyonrails.org/classes/ActionMailer/Base.html#method-c-default
[`mail`]: https://api.rubyonrails.org/classes/ActionMailer/Base.html#method-i-mail
Expand Down
3 changes: 1 addition & 2 deletions guides/source/active_record_basics.md
Expand Up @@ -88,8 +88,7 @@ singularizing) both regular and irregular words. When using class names composed
of two or more words, the model class name should follow the Ruby conventions,
using the CamelCase form, while the table name must use the snake_case form. Examples:

* Model Class - Singular with the first letter of each word capitalized (e.g.,
`BookClub`).
* Model Class - Singular with the first letter of each word capitalized (e.g., `BookClub`).
* Database Table - Plural with underscores separating words (e.g., `book_clubs`).

| Model / Class | Table / Schema |
Expand Down
3 changes: 3 additions & 0 deletions guides/source/active_record_encryption.md
Expand Up @@ -265,6 +265,7 @@ When generating the filter parameter, it will use the model name as a prefix. E.
```ruby
config.active_record.encryption.add_to_filter_parameters = false
```

In case you want exclude specific columns from this automatic filtering, add them to `config.active_record.encryption.excluded_from_filter_parameters`.

### Encoding
Expand Down Expand Up @@ -534,6 +535,7 @@ ActiveRecord::Encryption.without_encryption do
...
end
```

This means that reading encrypted text will return the ciphertext, and saved content will be stored unencrypted.

##### Protect Encrypted Data
Expand All @@ -545,4 +547,5 @@ ActiveRecord::Encryption.protecting_encrypted_data do
...
end
```

This can be handy if you want to protect encrypted data while still running arbitrary code against it (e.g. in a Rails console).
8 changes: 4 additions & 4 deletions guides/source/active_record_migrations.md
Expand Up @@ -517,14 +517,14 @@ Column modifiers can be applied when creating or changing a column:
* `comment` Adds a comment for the column.
* `collation` Specifies the collation for a `string` or `text` column.
* `default` Allows to set a default value on the column. Note that if you
are using a dynamic value (such as a date), the default will only be calculated
the first time (i.e. on the date the migration is applied). Use `nil` for `NULL`.
are using a dynamic value (such as a date), the default will only be calculated
the first time (i.e. on the date the migration is applied). Use `nil` for `NULL`.
* `limit` Sets the maximum number of characters for a `string` column
and the maximum number of bytes for `text/binary/integer` columns.
and the maximum number of bytes for `text/binary/integer` columns.
* `null` Allows or disallows `NULL` values in the column.
* `precision` Specifies the precision for `decimal/numeric/datetime/time` columns.
* `scale` Specifies the scale for the `decimal` and `numeric` columns,
representing the number of digits after the decimal point.
representing the number of digits after the decimal point.

NOTE: For `add_column` or `change_column` there is no option for adding indexes.
They need to be added separately using `add_index`.
Expand Down
6 changes: 2 additions & 4 deletions guides/source/active_record_multiple_databases.md
Expand Up @@ -23,10 +23,8 @@ At this time the following features are supported:

* Multiple writer databases and a replica for each
* Automatic connection switching for the model you're working with
* Automatic swapping between the writer and replica depending on the HTTP verb
and recent writes
* Rails tasks for creating, dropping, migrating, and interacting with the multiple
databases
* Automatic swapping between the writer and replica depending on the HTTP verb and recent writes
* Rails tasks for creating, dropping, migrating, and interacting with the multiple databases

The following features are not (yet) supported:

Expand Down
1 change: 1 addition & 0 deletions guides/source/active_storage_overview.md
Expand Up @@ -183,6 +183,7 @@ amazon:
server_side_encryption: "" # 'aws:kms' or 'AES256'
cache_control: "private, max-age=<%= 1.day.to_i %>"
```

TIP: Set sensible client HTTP timeouts and retry limits for your application. In certain failure scenarios, the default AWS client configuration may cause connections to be held for up to several minutes and lead to request queuing.

Add the [`aws-sdk-s3`](https://github.com/aws/aws-sdk-ruby) gem to your `Gemfile`:
Expand Down
3 changes: 2 additions & 1 deletion guides/source/api_app.md
Expand Up @@ -548,7 +548,8 @@ Some common modules you might want to add:
self.cache_store = :mem_cache_store
end
```
Rails does *not* pass this configuration automatically.

Rails does *not* pass this configuration automatically.

The best place to add a module is in your `ApplicationController`, but you can
also add modules to individual controllers.
37 changes: 15 additions & 22 deletions guides/source/asset_pipeline.md
Expand Up @@ -113,26 +113,17 @@ with a built-in helper. In the source the generated code looked like this:

The query string strategy has several disadvantages:

1. **Not all caches will reliably cache content where the filename only differs by
query parameters**
1. **Not all caches will reliably cache content where the filename only differs by query parameters**

[Steve Souders recommends](https://www.stevesouders.com/blog/2008/08/23/revving-filenames-dont-use-querystring/),
"...avoiding a querystring for cacheable resources". He found that in this
case 5-20% of requests will not be cached. Query strings in particular do not
work at all with some CDNs for cache invalidation.
[Steve Souders recommends][], "...avoiding a querystring for cacheable resources". He found that in this case 5-20% of requests will not be cached. Query strings in particular do not work at all with some CDNs for cache invalidation.

2. **The file name can change between nodes in multi-server environments.**

The default query string in Rails 2.x is based on the modification time of
the files. When assets are deployed to a cluster, there is no guarantee that the
timestamps will be the same, resulting in different values being used depending
on which server handles the request.
The default query string in Rails 2.x is based on the modification time of the files. When assets are deployed to a cluster, there is no guarantee that the timestamps will be the same, resulting in different values being used depending on which server handles the request.

3. **Too much cache invalidation**

When static assets are deployed with each new release of code, the mtime
(time of last modification) of _all_ these files changes, forcing all remote
clients to fetch them again, even when the content of those assets has not changed.
When static assets are deployed with each new release of code, the mtime (time of last modification) of _all_ these files changes, forcing all remote clients to fetch them again, even when the content of those assets has not changed.

Fingerprinting fixes these problems by avoiding query strings, and by ensuring
that filenames are consistent based on their content.
Expand All @@ -147,7 +138,7 @@ More reading:
* [Revving Filenames: don't use querystring](http://www.stevesouders.com/blog/2008/08/23/revving-filenames-dont-use-querystring/)

[`config.assets.digest`]: configuring.html#config-assets-digest

[Steve Souders recommends]: https://www.stevesouders.com/blog/2008/08/23/revving-filenames-dont-use-querystring/

How to Use the Asset Pipeline
-----------------------------
Expand Down Expand Up @@ -207,15 +198,15 @@ Pipeline assets can be placed inside an application in one of three locations:
`app/assets`, `lib/assets` or `vendor/assets`.

* `app/assets` is for assets that are owned by the application, such as custom
images, JavaScript files, or stylesheets.
images, JavaScript files, or stylesheets.

* `lib/assets` is for your own libraries' code that doesn't really fit into the
scope of the application or those libraries which are shared across applications.
scope of the application or those libraries which are shared across applications.

* `vendor/assets` is for assets that are owned by outside entities, such as
code for JavaScript plugins and CSS frameworks. Keep in mind that third party
code with references to other files also processed by the asset Pipeline (images,
stylesheets, etc.), will need to be rewritten to use helpers like `asset_path`.
code for JavaScript plugins and CSS frameworks. Keep in mind that third party
code with references to other files also processed by the asset Pipeline (images,
stylesheets, etc.), will need to be rewritten to use helpers like `asset_path`.

#### Search Paths

Expand Down Expand Up @@ -760,9 +751,9 @@ $ RAILS_ENV=production rails assets:precompile

Note the following caveats:

* If precompiled assets are available, they will be served — even if they no
longer match the original (uncompiled) assets, _even on the development
server._
* If precompiled assets are available, they will be served — even if they no
longer match the original (uncompiled) assets, _even on the development
server._

To ensure that the development server always compiles assets on-the-fly (and
thus always reflects the most recent state of the code), the development
Expand All @@ -777,6 +768,7 @@ Note the following caveats:
```ruby
config.assets.prefix = "/dev-assets"
```

* The asset precompile task in your deployment tool (_e.g.,_ Capistrano) should
be disabled.
* Any necessary compressors or minifiers must be available on your development
Expand Down Expand Up @@ -1141,6 +1133,7 @@ and any other environments you define with production behavior (not
`application.rb`).

TIP: For further details have a look at the docs of your production web server:

- [Apache](https://tn123.org/mod_xsendfile/)
- [NGINX](https://www.nginx.com/resources/wiki/start/topics/examples/xsendfile/)

Expand Down

0 comments on commit 4d171a4

Please sign in to comment.