{"id":18837066,"url":"https://github.com/bkuhlmann/pragmater","last_synced_at":"2025-04-05T15:06:19.129Z","repository":{"id":45695663,"uuid":"48672926","full_name":"bkuhlmann/pragmater","owner":"bkuhlmann","description":"A command line interface for managing pragma comments.","archived":false,"fork":false,"pushed_at":"2025-03-25T02:12:13.000Z","size":874,"stargazers_count":45,"open_issues_count":0,"forks_count":2,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-03-29T14:07:54.081Z","etag":null,"topics":["cli","frozen-string-literals","pragma-comment"],"latest_commit_sha":null,"homepage":"https://alchemists.io/projects/pragmater","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bkuhlmann.png","metadata":{"files":{"readme":"README.adoc","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.adoc","code_of_conduct":null,"threat_model":null,"audit":null,"citation":"CITATION.cff","codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["bkuhlmann"]}},"created_at":"2015-12-28T03:58:56.000Z","updated_at":"2025-03-25T02:12:17.000Z","dependencies_parsed_at":"2023-02-19T01:01:42.266Z","dependency_job_id":"62e7614c-80a1-4a19-9ef0-a2707cf1b386","html_url":"https://github.com/bkuhlmann/pragmater","commit_stats":{"total_commits":746,"total_committers":1,"mean_commits":746.0,"dds":0.0,"last_synced_commit":"93a57766b35d2114a137f6f2bee476be4b22580d"},"previous_names":[],"tags_count":84,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bkuhlmann%2Fpragmater","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bkuhlmann%2Fpragmater/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bkuhlmann%2Fpragmater/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bkuhlmann%2Fpragmater/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bkuhlmann","download_url":"https://codeload.github.com/bkuhlmann/pragmater/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247353745,"owners_count":20925329,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","frozen-string-literals","pragma-comment"],"created_at":"2024-11-08T02:33:42.337Z","updated_at":"2025-04-05T15:06:19.111Z","avatar_url":"https://github.com/bkuhlmann.png","language":"Ruby","funding_links":["https://github.com/sponsors/bkuhlmann"],"categories":[],"sub_categories":[],"readme":":toc: macro\n:toclevels: 5\n:figure-caption!:\n\n= Pragmater\n\nA command line interface that does one thing well by being entirely focused on managing/formatting\nsource file https://en.wikipedia.org/wiki/Directive_(programming)[directive pragmas] (a.k.a. _magic\ncomments_). Examples:\n\n[source,ruby]\n----\n#! /usr/bin/env ruby\n# frozen_string_literal: true\n# encoding: UTF-8\n----\n\nWith https://www.ruby-lang.org/en/news/2015/12/25/ruby-2-3-0-released[Ruby 2.3.0], frozen strings\nare supported via a pragma. This gem provides an easy way to insert or remove pragmas to single or\nmultiple Ruby source files in order to benefit from improved memory and concurrency performance.\n\ntoc::[]\n\n== Features\n\n* Supports inserting a pragma or multiple pragmas to single or multiple source files.\n* Supports removing pragma(s) from single or multiple source files.\n* Supports file list filtering. Defaults to any file.\n* Ensures duplicate pragmas never exist.\n* Ensures pragmas are consistently formatted.\n\n== Requirements\n\n. https://www.ruby-lang.org[Ruby]\n\n== Setup\n\nTo install _with_ security, run:\n\n[source,bash]\n----\n# 💡 Skip this line if you already have the public certificate installed.\ngem cert --add \u003c(curl --compressed --location https://alchemists.io/gems.pem)\ngem install pragmater --trust-policy HighSecurity\n----\n\nTo install _without_ security, run:\n\n[source,bash]\n----\ngem install pragmater\n----\n\n== Usage\n\n=== Command Line Interface (CLI)\n\nFrom the command line, type: `pragmater --help`\n\nimage:https://alchemists.io/images/projects/pragmater/screenshots/usage.png[Usage,width=581,height=345,role=focal_point]\n\nBoth the `insert` and `remove` commands support the same options for specifying pragmas and/or\nincluded files. Example:\n\n[source,bash]\n----\npragmater insert --comments \"# frozen_string_literal: true\" --patterns \"Gemfile\" \"Guardfile\" \"Rakefile\" \".gemspec\" \"config.ru\" \"bin/**/*\" \"**/*.rake\" \"**/*.rb\"\n----\n\nThe `insert` and `remove` commands default to the current working directory so a path isn’t\nnecessary unless you want to run Pragmater in a directory structure other than your current working\ndirectory.\n\n=== Customization\n\nThis gem can be configured via a global configuration: `$HOME/.config/pragmater/configuration.yml`\n\nIt can also be configured via link:https://alchemists.io/projects/xdg[XDG] environment\nvariables.\n\nThe default configuration is as follows:\n\n[source,yaml]\n----\ncomments: []\npatterns: []\nroot_dir: \".\"\n----\n\nFeel free to take the above configuration, modify, and save as your own custom `configuration.yml`.\n\nThe `configuration.yml` file can be configured as follows:\n\n* `comments`: Defines the array of pragmas you want to insert into your source files. Whatever is\n  defined here will be the default used for insert and remove operations.\n* `includes`: Defines the array file patterns to apply to. Whatever is defined here will be the\n  default used for insert and remove operations.\n* `root_dir`: Defines the root directory to apply the `includes` patterns too. By default, this will\n  be the current directory you are running Pragmater from but can be a different directory entirely.\n\n=== Available Pragmas\n\nWith Ruby 2.3 and higher, the following pragmas are available:\n\n* `# encoding:` Defaults to `UTF-8` but any supported encoding can be used. For a list of values,\n  launch an IRB session and run `Encoding.name_list`.\n* `# coding:` The shorthand for `# encoding:`. Supports the same values as mentioned above.\n* `# frozen_string_literal:` Defaults to `false` but can take either `true` or `false` as a value.\n  When enabled, Ruby will throw errors when strings are used in a mutable fashion.\n* `# warn_indent:` Defaults to `false` but can take either `true` or `false` as a value. When\n  enabled, and running Ruby with the `-w` option, it’ll throw warnings for code that isn’t indented\n  by two spaces.\n\n=== Syntax\n\nThe pragma syntax allows for two kinds of styles. Example:\n\n[source,ruby]\n----\n# encoding: UTF-8\n# -*- encoding: UTF-8 -*-\n----\n\nOnly the former syntax is supported by this gem as the latter syntax is more verbose and requires\nadditional typing.\n\n=== Precedence\n\nWhen different multiple pragmas are defined, they all take precedence:\n\n[source,ruby]\n----\n# encoding: binary\n# frozen_string_literal: true\n----\n\nIn the above example, both _binary_ encoding and _frozen string literals_ behavior will be applied.\n\nWhen defining multiple pragmas that are similar, behavior can differ based on the _kind_ of pragma\nused. The following walks through each use case so you know what to expect:\n\n[source,ruby]\n----\n# encoding: binary\n# encoding: UTF-8\n----\n\nIn the above example, only the _binary_ encoding will be applied while the _UTF-8_ encoding will be\nignored (same principle applies for the `coding` pragma too).\n\n[source,ruby]\n----\n# frozen_string_literal: false\n# frozen_string_literal: true\n----\n\nIn the above example, frozen string literal support _will be enabled_ instead of being disabled.\n\n[source,ruby]\n----\n# warn_indent: false\n# warn_indent: true\n----\n\nIn the above example, indentation warnings _will be enabled_ instead of being disabled.\n\n=== Frozen String Literals\n\nSupport for frozen string literals was added in Ruby 2.3.0. The ability to freeze strings within a\nsource can be done by placing a frozen string pragma at the top of each source file. Example:\n\n[source,ruby]\n----\n# frozen_string_literal: true\n----\n\nThis is great for _selective_ enablement of frozen string literals but might be too much work for\nsome (even with the aid of this gem). As an alternative, frozen string literals can be enabled via\nthe following Ruby command line option:\n\n....\n--enable=frozen-string-literal\n....\n\nIt is important to note that, once enabled, this freezes strings program-wide – It’s an all or\nnothing option.\n\nRegardless of whether you leverage the capabilities of this gem or the Ruby command line option\nmentioned above, the following Ruby command line option is available to aid debugging and tracking\ndown frozen string literal issues:\n\n....\n--debug=frozen-string-literal\n....\n\nFinally, you can use `--debug` (or `$DEBUG=true`) to force all raised exceptions to print to the console whether they are rescued or not. This is best used in conjunction with the above.\n\nRuby 2.3.0 also added the following methods to the `String` class:\n\n* `String#+@`: Answers a duplicated, mutable, string if not already frozen. Example:\n+\n[source,ruby]\n----\nimmutable = \"test\".freeze\nmutable = +immutable\n\nmutable.frozen?      # false\nmutable.capitalize!  # \"Test\"\n----\n* `String#-@`: Answers a immutable string if not already frozen. Example:\n+\n[source,ruby]\n----\nmutable = \"test\"\nimmutable = -mutable\n\nimmutable.frozen?      # true\nimmutable.capitalize!  # FrozenError\n----\n\nYou can also use the methods, shown above, for variable initialization. Example:\n\n[source,ruby]\n----\nimmutable = -\"test\"\nmutable = +\"test\"\n\nimmutable.frozen?  # true\nmutable.frozen?    # false\n----\n\n💡 Use of `+String#-@+` was link:https://bugs.ruby-lang.org/issues/13077[enhanced in Ruby 2.5.0] to\n_deduplicate_ all instances of the same string thus reducing your memory footprint. This can be\nvaluable in situations where you are not using the frozen string comment and need to selectively\nfreeze strings.\n\n💡 Use of `+String#dup+` was link:https://github.com/ruby/ruby/pull/8952[significantly enhanced in Ruby 3.3.0] to be as performant as `pass:[String#+@]` so you can use `+String#dup+` instead of `pass:[String#+@]` since `+String#dup+` is easier to read.\n\n=== Consistency\n\nAs an added bonus, this gem ensures pragmas for all analyzed files are formatted in a consistent\nstyle. This means there is always a space after the octothorp (`#`). Here are multiple pragmas\npresented together for a visual comparison:\n\n[source,ruby]\n----\n#! /usr/bin/env ruby\n# encoding: UTF-8\n# coding: UTF-8\n# frozen_string_literal: true\n# warn_indent: true\n----\n\nOne oddity to the above is the use of `# !/usr/bin/env ruby` is not allowed but `#! /usr/bin/env\nruby` is which is why spacing is slightly different for shell pragmas.\n\n== Development\n\nTo contribute, run:\n\n[source,bash]\n----\ngit clone https://github.com/bkuhlmann/pragmater\ncd pragmater\nbin/setup\n----\n\nYou can also use the IRB console for direct access to all objects:\n\n[source,bash]\n----\nbin/console\n----\n\n== Tests\n\nTo test, run:\n\n[source,bash]\n----\nbin/rake\n----\n\n== link:https://alchemists.io/policies/license[License]\n\n== link:https://alchemists.io/policies/security[Security]\n\n== link:https://alchemists.io/policies/code_of_conduct[Code of Conduct]\n\n== link:https://alchemists.io/policies/contributions[Contributions]\n\n== link:https://alchemists.io/policies/developer_certificate_of_origin[Developer Certificate of Origin]\n\n== link:https://alchemists.io/projects/pragmater/versions[Versions]\n\n== link:https://alchemists.io/community[Community]\n\n== Credits\n\n* Built with link:https://alchemists.io/projects/gemsmith[Gemsmith].\n* Engineered by link:https://alchemists.io/team/brooke_kuhlmann[Brooke Kuhlmann].\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbkuhlmann%2Fpragmater","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbkuhlmann%2Fpragmater","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbkuhlmann%2Fpragmater/lists"}