parlour 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e7b2efb86589a0b2212d88906507d92990457318bdb3902426eef282a3da1b0e
4
- data.tar.gz: 16e1cb30836c714623ca43d5b72a1cfe2225bd4f93993d1c7ea9c04d2bb6db15
3
+ metadata.gz: 74fcc1898cf62ffe8cd5300bb14409c02b9d3a1fd3f323a07606ef399de2f9c7
4
+ data.tar.gz: 111bb1a4d35a610797e4d845388f6cf7dc2815b8b7732b885bc91eb281fc0408
5
5
  SHA512:
6
- metadata.gz: b5862a79da284a4953bd5d87b81c7cbe3852c91434d9d9b6b6f766d7838878ac2e40699f423951a559bc4e02e51bc922b936e133f12ddbe6a8276d44df16f607
7
- data.tar.gz: d563d410dce0963e554d45fceb69c295ff25a36f99093c7b392bfd52d3d33c4d7a6aa6f4e15aacb19a999db71cd98b2fd58f6e540b811793d987316573985be1
6
+ metadata.gz: c44c7ca71ffa19834234533348c340c341df6332f8f7ff15708e4d46c4016ef8dd5fbee5012e333338b79746bb8360aef68ea83bf50f651d6fc1b5636567895d
7
+ data.tar.gz: cc64f14e22f32a6952b896cb51eca120a0a5a94ccbd0aca41147af9d0dcb90d9ba6748771a1a17324a9c7ba5ecf1b6615963a174ce90b5b5a8e2d48ec8de5c91
@@ -3,6 +3,12 @@ All notable changes to this project will be documented in this file.
3
3
 
4
4
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
5
5
 
6
+ ## [0.4.0] - 2019-07-10
7
+ ### Changed
8
+ - Breaking change: The Parlour CLI tool no longer takes command-line arguments, and instead uses a `.parlour` configuration file. See the README!
9
+ - RBIs now begin with `# typed: strong`.
10
+ - Plugins now define a stub constructor to avoid an exception if they don't define one.
11
+
6
12
  ## [0.3.1] - 2019-07-09
7
13
  ### Changed
8
14
  - Multi-line parameter lists no longer have a trailing comma.
data/README.md CHANGED
@@ -11,6 +11,15 @@ Parlour is an RBI generator and merger for Sorbet. It consists of two key parts:
11
11
  RBIs for the same codebase. These are combined automatically as much as
12
12
  possible, but any other conflicts can be resolved manually through prompts.
13
13
 
14
+ ## Why should I use this?
15
+
16
+ - Parlour enables **much easier creation of RBI generators**, as formatting
17
+ is all handled for you, and you don't need to write your own CLI.
18
+
19
+ - You can **use many plugins together seamlessly**, running them all with a
20
+ single command and consolidating all of their definitions into a single
21
+ RBI output file.
22
+
14
23
  ## Usage
15
24
 
16
25
  There aren't really any docs currently, so have a look around the code to find
@@ -18,8 +27,7 @@ any extra options you may need.
18
27
 
19
28
  ### Using just the generator
20
29
 
21
- Here's a quick example of how you might generate an RBI currently, though this
22
- API is very likely to change:
30
+ Here's a quick example of how you can generate an RBI:
23
31
 
24
32
  ```ruby
25
33
  require 'parlour'
@@ -82,27 +90,67 @@ end
82
90
  useful!)
83
91
 
84
92
  You can then run several plugins, combining their output and saving it into one
85
- RBI file, using the command-line tool. For example, if that code was in a file
86
- called `plugin.rb`, this would save the RBI into `output.rbi`:
93
+ RBI file, using the command-line tool. The command line tool is configurated
94
+ using a `.parlour` YAML file. For example, if that code was in a file
95
+ called `plugin.rb`, then using this `.parlour` file and then running `parlour`
96
+ would save the RBI into `output.rbi`:
87
97
 
98
+ ```yaml
99
+ output_file: output.rbi
100
+
101
+ relative_requires:
102
+ - plugin.rb
103
+
104
+ plugins:
105
+ MyPlugin: {}
88
106
  ```
89
- parlour --relative-requires plugin.rb MyPlugin output.rbi
107
+
108
+ The `{}` indicates that this plugin needs no extra configuration. If it did need
109
+ configuration, this could be specified like so:
110
+
111
+ ```yaml
112
+ plugins:
113
+ MyPlugin:
114
+ foo: something
115
+ bar: something else
90
116
  ```
91
117
 
92
118
  You can also use plugins from gems. If that plugin was published as a gem called
93
119
  `parlour-gem`:
94
120
 
95
- ```
96
- parlour --requires parlour-gem MyPlugin output.rbi
121
+ ```yaml
122
+ output_file: output.rbi
123
+
124
+ requires:
125
+ - parlour-gem
126
+
127
+ plugins:
128
+ MyPlugin: {}
97
129
  ```
98
130
 
99
131
  The real power of this is the ability to use many plugins at once:
100
132
 
101
- ```
102
- parlour --requires gem1,gem2,gem3 Gem1::Plugin Gem2::Plugin Gem3::Plugin output.rbi
133
+ ```yaml
134
+ output_file: output.rbi
135
+
136
+ requires:
137
+ - gem1
138
+ - gem2
139
+ - gem3
140
+
141
+ plugins:
142
+ Gem1::Plugin: {}
143
+ Gem2::Plugin: {}
144
+ Gem3::Plugin: {}
103
145
  ```
104
146
 
105
- ## Code Structure
147
+ ## Parlour Plugins
148
+
149
+ _Have you written an awesome Parlour plugin? Please submit a PR to add it to this list!_
150
+
151
+ - [Sord](https://github.com/AaronC81/sord) - Generate RBIs from YARD documentation
152
+
153
+ ## Parlour's Code Structure
106
154
 
107
155
  ### Overall Flow
108
156
  ```
@@ -137,9 +185,6 @@ accepts the current indentation level and a set of formatting options.
137
185
  (Each object is responsible for generating its own indentation; that is, the
138
186
  lines generated by a child object should not then be indented by its parent.)
139
187
 
140
- I think generation is quite close to done, but it still needs features like
141
- constants and type parameters.
142
-
143
188
  ### Plugins
144
189
  Plugins are automatically detected when they subclass `Plugin`. Plugins can then
145
190
  be run by passing an array of them, along with an `RbiGenerator`, to
@@ -165,7 +210,7 @@ It is able to do the following merges automatically:
165
210
  If a merge can't be performed automatically, then the `#resolve_conflicts`
166
211
  method takes a block. This block is passed all the conflicting objects, and one
167
212
  should be selected and returned - all others will be deleted. (Alternatively,
168
- the block can return nil, and all will be deleted.) This will allow a CLI to
213
+ the block can return nil, and all will be deleted.) This allows the CLI to
169
214
  prompt the user asking them what they'd like to do, in the case of conflicts
170
215
  between each plugin's signatures which can't automatically be resolved.
171
216
 
@@ -3,6 +3,7 @@ require 'parlour'
3
3
  require 'commander/import'
4
4
  require 'bundler'
5
5
  require 'rainbow'
6
+ require 'yaml'
6
7
 
7
8
  program :name, 'parlour'
8
9
  program :version, Parlour::VERSION
@@ -10,43 +11,45 @@ program :description, 'An RBI generator and plugin system'
10
11
 
11
12
  default_command :run
12
13
  command :run do |c|
14
+ # TODO: re-add support for flags and figure out how to merge them with .parlour
13
15
  c.syntax = 'parlour run <plugins...> <output-file> [options]'
14
- c.description = 'Generates an RBI file from a list of plugins'
15
- c.option '--requires STRING', String, 'A comma-separated string of gems to require'
16
- c.option '--relative-requires STRING', String, 'A comma-separated string of files to require, relative to the working dir'
17
- c.option '--tab-size INTEGER', Integer, 'The size of tabs to use'
18
- c.option '--break-params INTEGER', Integer, 'Break params onto their own lines if there are this many'
16
+ c.description = 'Generates an RBI file from your .parlour file'
19
17
 
20
18
  c.action do |args, options|
21
- options.default(
22
- tab_size: 2,
23
- break_params: 4,
24
- requires: '',
25
- relative_requires: ''
26
- )
19
+ configuration = keys_to_symbols(YAML.load_file(File.join(Dir.pwd, '.parlour')))
27
20
 
28
- options.requires.split(',').each { |source| require(source) }
29
- options.relative_requires.split(',').each do |source|
30
- require(File.join(Dir.pwd, source))
31
- end
21
+ raise 'you must specify output_file in your .parlour file' unless configuration[:output_file]
32
22
 
33
- *plugin_names, output_file = args
23
+ # Style defaults
24
+ configuration[:style] ||= {}
25
+ configuration[:style][:tab_size] ||= 2
26
+ configuration[:style][:break_params] ||= 4
34
27
 
35
- raise 'no output file specified' if output_file.nil?
28
+ # Require defaults
29
+ configuration[:requires] ||= []
30
+ configuration[:relative_requires] ||= []
31
+
32
+ # Plugin defaults
33
+ configuration[:plugins] ||= []
36
34
 
37
35
  plugin_instances = []
38
36
 
37
+ configuration[:requires].each { |source| require(source) }
38
+ configuration[:relative_requires].each do |source|
39
+ require_relative(File.join(Dir.pwd, source))
40
+ end
41
+
39
42
  # Collect the instances of each plugin into an array
40
- plugin_names.each do |name|
41
- plugin = Parlour::Plugin.registered_plugins[name]
43
+ configuration[:plugins].each do |name, options|
44
+ plugin = Parlour::Plugin.registered_plugins[name.to_s]&.new(options)
42
45
  raise "missing plugin #{name}" unless plugin
43
46
  plugin_instances << plugin
44
47
  end
45
48
 
46
49
  # Create a generator instance and run all plugins on it
47
50
  gen = Parlour::RbiGenerator.new(
48
- break_params: options.break_params,
49
- tab_size: options.tab_size
51
+ break_params: configuration[:style][:break_params],
52
+ tab_size: configuration[:style][:tab_size]
50
53
  )
51
54
  Parlour::Plugin.run_plugins(plugin_instances, gen)
52
55
 
@@ -70,6 +73,27 @@ command :run do |c|
70
73
  end
71
74
 
72
75
  # Write the final RBI
73
- File.write(output_file, gen.rbi)
76
+ File.write(configuration[:output_file], gen.rbi)
74
77
  end
75
- end
78
+ end
79
+
80
+ private
81
+
82
+ # Given a hash, converts its keys and any keys of child hashes to symbols.
83
+ # @param [Hash] hash
84
+ # @return [void]
85
+ def keys_to_symbols(hash)
86
+ hash.map do |k, v|
87
+ [
88
+ k.to_sym,
89
+ case v
90
+ when Hash
91
+ keys_to_symbols(v)
92
+ when Array
93
+ v.map { |x| x.is_a?(Hash) ? keys_to_symbols(x) : x }
94
+ else
95
+ v
96
+ end
97
+ ]
98
+ end.to_h
99
+ end
@@ -9,7 +9,7 @@ module Parlour
9
9
 
10
10
  @@registered_plugins = {}
11
11
 
12
- sig { returns(T::Hash[String, Plugin]) }
12
+ sig { returns(T::Hash[String, T.class_of(Plugin)]) }
13
13
  # Returns all registered plugins, as a hash of their paths to the {Plugin}
14
14
  # instances themselves.
15
15
  #
@@ -25,7 +25,7 @@ module Parlour
25
25
  # @param new_plugin [Plugin] The new plugin.
26
26
  # @return [void]
27
27
  def self.inherited(new_plugin)
28
- registered_plugins[T.must(new_plugin.name)] = new_plugin.new
28
+ registered_plugins[T.must(new_plugin.name)] = new_plugin
29
29
  end
30
30
 
31
31
  sig { params(plugins: T::Array[Plugin], generator: RbiGenerator).void }
@@ -36,11 +36,17 @@ module Parlour
36
36
  # @return [void]
37
37
  def self.run_plugins(plugins, generator)
38
38
  plugins.each do |plugin|
39
+ puts "=== #{plugin.class.name}"
39
40
  generator.current_plugin = plugin
40
41
  plugin.generate(generator.root)
42
+ rescue Exception => e
43
+ puts "!!! This plugin threw an exception: #{e}"
41
44
  end
42
45
  end
43
46
 
47
+ sig { params(options: Hash).void }
48
+ def initialize(options); end
49
+
44
50
  sig { abstract.params(root: RbiGenerator::Namespace).void }
45
51
  # Plugin subclasses should redefine this method and do their RBI generation
46
52
  # inside it.
@@ -43,7 +43,7 @@ module Parlour
43
43
  #
44
44
  # @return [String] The generated RBI file
45
45
  def rbi
46
- root.generate_rbi(0, options).join("\n")
46
+ "# typed: strong\n" + root.generate_rbi(0, options).join("\n")
47
47
  end
48
48
  end
49
49
  end
@@ -1,5 +1,5 @@
1
1
  # typed: strong
2
2
  module Parlour
3
3
  # The library version.
4
- VERSION = '0.3.1'
4
+ VERSION = '0.4.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: parlour
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Christiansen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-07-09 00:00:00.000000000 Z
11
+ date: 2019-07-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sorbet-runtime