@@ -19,85 +19,138 @@ REPOS = {
1919 zeitwerk : 'https://github.com/fxn/zeitwerk'
2020}
2121
22- namespace :examples do
23- require 'fileutils'
24- require 'rainbow'
22+ # Thrown by tasks to present a "friendly" error message and abort the task.
23+ class TaskError < StandardError
24+ end
2525
26- desc "Clone git repositories and run Sord on them as examples"
27- task :seed , [ :mode , :clean ] do |t , args |
28- if File . directory? ( 'sord_examples' )
29- puts Rainbow ( 'sord_examples directory already exists, please delete the directory or run a reseed!' ) . red
30- exit
31- end
26+ # Handles Sord examples, including checkout and running Sord to generate types.
27+ class ExampleRunner
28+ attr_reader :mode , :mode_arg , :clean
29+ alias clean? clean
30+
31+ # @return [<Symbol>] Names of gems where Sord failed.
32+ attr_accessor :failed_examples
3233
33- if args [ :mode ] == 'rbi'
34- mode_arg = '--rbi'
35- elsif args [ :mode ] == 'rbs'
36- mode_arg = '--rbs'
34+ # @param [String] mode "rbi" or "rbs".
35+ # @param [Boolean] clean Run Sord with additional options to generate minimal type output.
36+ def initialize ( mode :, clean : false )
37+ @mode = mode
38+ @clean = clean
39+
40+ if mode == 'rbi'
41+ @mode_arg = '--rbi'
42+ elsif mode == 'rbs'
43+ @mode_arg = '--rbs'
3744 else
38- puts Rainbow ( 'please specify \'rbi\' or \'rbs\'!' ) . red
39- exit
45+ raise TaskError , 'please specify \'rbi\' or \'rbs\'!'
46+ end
47+
48+ @failed_examples = [ ]
49+ end
50+
51+ # Create the `sord_examples` directory, ready for checkouts.
52+ # @raise [TaskError] If it already exists.
53+ def create_examples_dir
54+ if File . directory? ( File . join ( __dir__ , 'sord_examples' ) )
55+ raise TaskError , 'sord_examples directory already exists, please delete the directory or run a reseed!'
4056 end
4157
4258 FileUtils . mkdir 'sord_examples'
43- FileUtils . cd 'sord_examples'
44-
45- Bundler . with_clean_env do
46- # Shallow clone each of the repositories, then bundle install and run sord.
47- REPOS . each do |name , url |
48- puts "Cloning #{ name } ..."
49- system ( "git clone #{ url } --depth=1" )
50- FileUtils . cd name . to_s
59+ end
60+
61+ # Check that the `sord_examples` directory exists.
62+ # @raise [TaskError] If it doesn't.
63+ def validate_examples_dir
64+ unless File . directory? ( File . join ( __dir__ , 'sord_examples' ) )
65+ raise TaskError , 'The sord_examples directory does not exist. Have you run the seed task?'
66+ end
67+ end
68+
69+ # Check out a repository, add Sord to its Gemfile, and install its dependencies.
70+ # @param [Symbol] name Name of the checkout.
71+ # @param [String] url Git URL.
72+ def prepare_checkout ( name , url )
73+ Dir . chdir ( File . join ( __dir__ , 'sord_examples' ) ) do
74+ puts "Cloning #{ name } ..."
75+ system ( "git clone #{ url } --depth=1" )
76+
77+ Dir . chdir ( name . to_s ) do
5178 # Add sord to gemfile.
5279 `echo "gem 'sord', path: '../../'" >> Gemfile`
80+
5381 # Run bundle install.
5482 system ( 'bundle install' )
55- # Generate sri
56- puts "Generating rbi for #{ name } ..."
57- if args [ :clean ]
58- system ( "bundle exec sord ../#{ name } .#{ args [ :mode ] } #{ mode_arg } --no-sord-comments --replace-errors-with-untyped --replace-unresolved-with-untyped" )
59- else
60- system ( "bundle exec sord ../#{ name } .#{ args [ :mode ] } #{ mode_arg } " )
61- end
62- puts "#{ name } .#{ args [ :mode ] } generated!"
63- FileUtils . cd '..'
6483 end
6584 end
85+ end
6686
67- puts Rainbow ( "Seeding complete!" ) . green
87+ # Run Sord on a checked-out repository.
88+ # @param [Symbol] name Name of the checkout.
89+ def generate_types ( name )
90+ puts "Generating rbi for #{ name } ..."
91+
92+ Dir . chdir ( File . join ( __dir__ , 'sord_examples' , name . to_s ) ) do
93+ if clean?
94+ system ( "bundle exec sord ../#{ name } .#{ mode } #{ mode_arg } --no-sord-comments --replace-errors-with-untyped --replace-unresolved-with-untyped" )
95+ else
96+ system ( "bundle exec sord ../#{ name } .#{ mode } #{ mode_arg } " )
97+ end
98+
99+ if $?. success?
100+ puts "#{ name } .#{ mode } generated!"
101+ else
102+ puts "Sord exited with error"
103+ failed_examples << name
104+ end
105+ end
68106 end
69107
70- desc 'Regenerate the rbi files in sord_examples.'
71- task :reseed , [ :mode , :clean ] do |t , args |
72- if Dir . exist? ( 'sord_examples' )
73- FileUtils . cd 'sord_examples'
74- else
75- raise Rainbow ( "The sord_examples directory does not exist. Have you run the seed task?" ) . red . bold
108+ # Check that all Sord executions were successful.
109+ # @raise [TaskError] If any failed.
110+ def validate_sord_success
111+ if failed_examples . any?
112+ raise TaskError , "Not all Sord runs were successful: #{ failed_examples . map ( &:to_s ) . join ( ', ' ) } "
76113 end
114+ end
115+ end
77116
78- if args [ :mode ] == 'rbi'
79- mode_arg = '--rbi'
80- elsif args [ :mode ] == 'rbs'
81- mode_arg = '--rbs'
82- else
83- puts Rainbow ( 'please specify \'rbi\' or \'rbs\'!' ) . red
84- exit
117+ namespace :examples do
118+ require 'fileutils'
119+ require 'rainbow'
120+
121+ desc "Clone git repositories and run Sord on them as examples"
122+ task :seed , [ :mode , :clean ] do |t , args |
123+ examples = ExampleRunner . new ( **args )
124+ examples . create_examples_dir
125+
126+ Bundler . with_clean_env do
127+ REPOS . each do |name , url |
128+ examples . prepare_checkout ( name , url )
129+ examples . generate_types ( name )
130+ end
85131 end
132+ examples . validate_sord_success
133+
134+ puts Rainbow ( "Seeding complete!" ) . green
135+
136+ rescue TaskError => e
137+ abort Rainbow ( e . to_s ) . red
138+ end
139+
140+ desc 'Regenerate the rbi files in sord_examples.'
141+ task :reseed , [ :mode , :clean ] do |t , args |
142+ examples = ExampleRunner . new ( **args )
143+ examples . validate_examples_dir
86144
87145 REPOS . keys . each do |name |
88- FileUtils . cd name . to_s
89- puts "Regenerating rbi file for #{ name } ..."
90- Bundler . with_clean_env do
91- if args [ :clean ]
92- system ( "bundle exec sord ../#{ name } .#{ args [ :mode ] } #{ mode_arg } --no-regenerate --no-sord-comments --replace-errors-with-untyped --replace-unresolved-with-untyped" )
93- else
94- system ( "bundle exec sord ../#{ name } .#{ args [ :mode ] } #{ mode_arg } --no-regenerate" )
95- end
96- end
97- FileUtils . cd '..'
146+ examples . generate_types ( name )
98147 end
148+ examples . validate_sord_success
99149
100150 puts Rainbow ( "Re-seeding complete!" ) . green
151+
152+ rescue TaskError => e
153+ abort Rainbow ( e . to_s ) . red
101154 end
102155
103156 desc 'Delete the sord_examples directory to allow the seeder to run again.'
0 commit comments