{"id":20683962,"url":"https://github.com/aaronc81/sord","last_synced_at":"2025-05-14T20:09:45.175Z","repository":{"id":45060926,"uuid":"193150231","full_name":"AaronC81/sord","owner":"AaronC81","description":"Convert YARD docs to Sorbet RBI and Ruby 3/Steep RBS files","archived":false,"fork":false,"pushed_at":"2025-03-05T00:11:14.000Z","size":656,"stargazers_count":319,"open_issues_count":19,"forks_count":18,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-05-07T06:43:45.394Z","etag":null,"topics":["parlour","rbs","ruby","ruby3","sorbet","yard","yardoc"],"latest_commit_sha":null,"homepage":"https://sord.aaronc.cc","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AaronC81.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-06-21T19:28:56.000Z","updated_at":"2025-04-24T18:03:49.000Z","dependencies_parsed_at":"2025-03-14T17:41:29.052Z","dependency_job_id":null,"html_url":"https://github.com/AaronC81/sord","commit_stats":{"total_commits":323,"total_committers":12,"mean_commits":"26.916666666666668","dds":"0.40866873065015474","last_synced_commit":"c69f8cf00dde13838d270a4adbeeee07e4065d77"},"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AaronC81%2Fsord","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AaronC81%2Fsord/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AaronC81%2Fsord/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AaronC81%2Fsord/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AaronC81","download_url":"https://codeload.github.com/AaronC81/sord/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254219374,"owners_count":22034397,"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":["parlour","rbs","ruby","ruby3","sorbet","yard","yardoc"],"created_at":"2024-11-16T22:18:25.717Z","updated_at":"2025-05-14T20:09:45.155Z","avatar_url":"https://github.com/AaronC81.png","language":"Ruby","readme":"# Sord\n\n## Overview\n\nSord is a [**So**rbet](https://sorbet.org) and [YA**RD**](https://yardoc.org/)\ncrossover. It can **automatically generate RBI and RBS type signature files** by\nlooking at the **types specified in YARD documentation** comments.\n\nIf your project is already YARD documented, then this can generate most of the\ntype signatures you need!\n\nSord is the perfect way to jump-start the adoption of types in your project,\nwhether you plan to use Sorbet's RBI format or Ruby 3/Steep's RBS format.\n\n**Try Sord online at: [sord.aaronc.cc](https://sord.aaronc.cc)**\n\nSord has the following features:\n  - Automatically generates signatures for modules, classes and methods\n  - Support for multiple parameter or return types (`T.any`/`|`)\n  - Gracefully handles missing YARD types (`T.untyped`/`untyped`)\n  - Can infer setter parameter type from the corresponding getter's return type\n  - Recognises mixins (`include` and `extend`)\n  - Support for generic types such as `Array\u003cT\u003e` and `Hash\u003cK, V\u003e`\n  - Can infer namespaced classes (`[Bar]` can become `GemName::Foo::Bar`)\n  - Handles return types which can be `nil` (`T.nilable`/`untyped`)\n  - Handles duck types (`T.untyped`/`untyped`)\n  - Support for ordered list types (`[Array(Integer, Symbol)]` becomes `[Integer, Symbol]`)\n  - Support for boolean types (`[true, false]` becomes `T::Boolean`/`bool`)\n  - Support for `\u0026block` parameters documented with `@yieldparam` and `@yieldreturn`\n\n## Usage\n\nInstall Sord with `gem install sord`.\n\nSord is a command line tool. To use it, open a terminal in the root directory\nof your project and invoke `sord`, passing a path where you'd like to save your\nfile (this file will be overwritten):\n\n```\nsord defs.rbi\n```\n\nSord will generate YARD docs and then print information about what it's inferred\nas it runs. It is best to fix any issues in the YARD documentation, as any edits\nmade to the resulting file will be replaced if you re-run Sord.\n\nThe output type is inferred by the file extension you use, but you can also\nspecify it explicitly with `--rbi` or `--rbs`.\n\n## Shipping RBI Types\n\nRBI files generated by Sord can be used in two main ways:\n\n- [Shipped in the gem itself](https://sorbet.org/docs/rbi#rbis-within-gems).\n- Contributed to [sorbet-typed](https://github.com/sorbet/sorbet-typed).\n\nGenerally, you should ship the type signatures with your gem if possible.\nsorbet-typed is meant to be a place for gems that are no longer updated or\nwhere the maintainer is unwilling to ship type signatures with the gem itself.\n\n### Flags\n\nSord also takes some flags to alter the generated file:\n\n  - `--rbi`/`--rbs`: Override the output format inferred from the file\n    extension.\n  - `--no-sord-comments`: Generates the file without any Sord comments about\n    warnings/inferences/errors. (The original file's comments will still be\n    included.)\n  - `--no-regenerate`: By default, Sord will regenerate a repository's YARD\n    docs for you. This option skips regenerating the YARD docs.\n  - `--break-params`: Determines how many parameters are necessary before\n    the signature is changed from a single-line to a multi-line block.\n    (Default: 4)\n  - `--replace-errors-with-untyped`: Uses `T.untyped` instead of `SORD_ERROR_*`\n    constants.\n  - `--replace-unresolved-with-untyped`: Uses `T.untyped` when Sord is unable to\n    resolve a constant.\n  - `--include-messages` and `--exclude-messages`: Used to filter the logging\n    messages given by Sord. `--include-messages` acts as a whitelist, printing\n    only messages of the specified logging kinds, whereas `--exclude-messages`\n    acts as a blacklist and suppresses the specified logging kinds. Both flags\n    take a comma-separated list of logging kinds, for example `omit,infer`.\n    When using `--include-messages`, the `done` kind is included by default.\n    (You cannot specify both `--include-messages` and `--exclude-messages`.)\n  - `--exclude-untyped`: Exclude methods and attributes with untyped return\n    values.\n  - `--tags TAGS`: Provide a list of comma-separated tags as understood by the\n    `yard` command. E.g. `--tags 'mytag:My Description,mytag2:My New Description'\n\n## Example\n\nSay we have this file, called `test.rb`:\n\n```ruby\nmodule Example\n  class Person\n    # @param name [String] The name of the Person to create.\n    # @param age [Integer] The age of the Person to create.\n    # @return [Example::Person]\n    def initialize(name, age)\n      @name = name\n      @age = age\n    end\n\n    # @return [String]\n    attr_accessor :name\n\n    # @return [Integer]\n    attr_accessor :age\n\n    # @param possible_names [Array\u003cString\u003e] An array of potential names to choose from.\n    # @param possible_ages [Array\u003cInteger\u003e] An array of potential ages to choose from.\n    # @return [Example::Person]\n    def self.construct_randomly(possible_names, possible_ages)\n      Person.new(possible_names.sample, possible_ages.sample)\n    end\n  end\nend\n```\n\nFirst, generate a YARD registry by running `yardoc test.rb`. Then, we can run\n`sord test.rbi` to generate the RBI file. (Careful not to overwrite your code\nfiles! Note the `.rbi` file extension.) In doing this, Sord prints:\n\n```\n[INFER] Assuming from filename you wish to generate in RBI format\n[DONE ] Processed 8 objects (2 namespaces and 6 methods)\n```\n\nThe `test.rbi` file then contains a complete RBI file for `test.rb`:\n\n```ruby\n# typed: strong\nmodule Example\n  class Person\n    # _@param_ `name` — The name of the Person to create.\n    # \n    # _@param_ `age` — The age of the Person to create.\n    sig { params(name: String, age: Integer).void }\n    def initialize(name, age); end\n\n    # _@param_ `possible_names` — An array of potential names to choose from.\n    # \n    # _@param_ `possible_ages` — An array of potential ages to choose from.\n    sig { params(possible_names: T::Array[String], possible_ages: T::Array[Integer]).returns(Example::Person) }\n    def self.construct_randomly(possible_names, possible_ages); end\n\n    sig { returns(String) }\n    attr_accessor :name\n\n    sig { returns(Integer) }\n    attr_accessor :age\n  end\nend\n```\n\nIf we had instead generated `test.rbs`, we would get this file in RBS format:\n\n```ruby\nmodule Example\n  class Person\n    # _@param_ `name` — The name of the Person to create.\n    # \n    # _@param_ `age` — The age of the Person to create.\n    def initialize: (String name, Integer age) -\u003e void\n\n    # _@param_ `possible_names` — An array of potential names to choose from.\n    # \n    # _@param_ `possible_ages` — An array of potential ages to choose from.\n    def self.construct_randomly: (Array[String] possible_names, Array[Integer] possible_ages) -\u003e Example::Person\n\n    attr_accessor name: String\n\n    attr_accessor age: Integer\n  end\nend\n```\n\n## Things to be aware of\n\nThe general rule of thumb for type conversions is:\n\n  - If Sord understands the YARD type, then it is converted into the RBI or RBS\n    type.\n  - If the YARD type is missing, Sord fills in `T.untyped`.\n  - If the YARD type can't be understood, Sord creates an undefined Ruby constant\n    with a similar name to the unknown YARD type. For example, the obviously\n    invalid YARD type `A%B` will become a constant called `SORD_ERROR_AB`.\n    You should search through your resulting file to find and fix and \n    `SORD_ERROR`s.\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub at https://github.com/AaronC81/sord. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.\n\nWhile contributing, if you want to see the results of your changes to Sord you\ncan use the `examples:seed` Rake task. The task uses Sord to generate types for\na number of open source Ruby gems, including Bundler, Haml, Rouge, and RSpec.\n`rake examples:seed` (and `rake examples:reseed` to regenerate the files) will\nclone the repositories of these gems into `sord_examples/` and then generate the\nfiles into the same directory.\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).\n\n## Code of Conduct\n\nEveryone interacting in the Sord project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/AaronC81/sord/blob/master/CODE_OF_CONDUCT.md).\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faaronc81%2Fsord","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faaronc81%2Fsord","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faaronc81%2Fsord/lists"}