singer 0.4.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/README.md +45 -1
 - data/exe/singer +1 -1
 - data/lib/singer/configuration.rb +6 -1
 - data/lib/singer/option_parsing.rb +61 -0
 - data/lib/singer/paths.rb +17 -1
 - data/lib/singer/template.rb +11 -2
 - data/lib/singer/version.rb +1 -1
 - data/lib/singer.rb +3 -14
 - data/templates/sinatra_app/config/config.ru +1 -1
 - data/templates/sinatra_app/exe/server.rb +1 -1
 - data/templates/sinatra_app/lib/{__SNAKECASE_NAME__ → __PROJECT_NAME_SNAKECASE__}/hello.rb +1 -1
 - data/templates/sinatra_app/lib/{__SNAKECASE_NAME__ → __PROJECT_NAME_SNAKECASE__}/server.rb +1 -1
 - data/templates/sinatra_app/test/server/test_server.rb +1 -1
 - data/templates/sinatra_app/test/server/test_server_error_dumping.rb +1 -1
 - data/templates/sinatra_app/test/test_hello.rb +1 -1
 - data/templates/sinatra_app/views/layout.haml +1 -1
 - data/templates/tdd/lib/{__SNAKECASE_NAME__.rb → __PROJECT_NAME_SNAKECASE__.rb} +2 -2
 - data/templates/tdd/test/test___PROJECT_NAME_SNAKECASE__.rb +16 -0
 - metadata +7 -6
 - data/templates/tdd/test/test___SNAKECASE_NAME__.rb +0 -16
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: cd871af4e10b86d0362c5bef72223344e86d5f81cb6a2871e901ec588f2d97b8
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 5bbab829554eee4d7da41e43f07fec57784269906da6a7f866a466a73f1a9e92
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: ba2fecb7f5b4a230e5eb26d7e8fef5566e1753fec82952b431779b7720fc3c525beb26a9e9e977c2d328648b11531e1bc4e760c1edbde219f1f025abb0be72d9
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 3f121f9b2383ef48b822e1dac292e5a9f8455ded6cb9816b4fcd79b8139e64d46709c5fd2f9473cb200a1f8fc4808586e16bcfad574d91c86c8892bb67aba96a
         
     | 
    
        data/README.md
    CHANGED
    
    | 
         @@ -8,7 +8,51 @@ Run `gem install singer`. 
     | 
|
| 
       8 
8 
     | 
    
         | 
| 
       9 
9 
     | 
    
         
             
            ## Usage
         
     | 
| 
       10 
10 
     | 
    
         | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
      
 11 
     | 
    
         
            +
            ```bash
         
     | 
| 
      
 12 
     | 
    
         
            +
            singer [OPTION]... [TEMPLATE_NAME] PROJECT_NAME
         
     | 
| 
      
 13 
     | 
    
         
            +
            ```
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            Run `singer --help` to see up-to-date list of options.
         
     | 
| 
      
 16 
     | 
    
         
            +
            Run `singer --list-templates` to see available templates' names, both shipped with the gem and found on current system.
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            For `PROJECT_NAME`, using `snake_case` is best, although an attempt will be made to understand `CamelCase`, too.
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
            ## Writing your own templates
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
            Many features of Singer will become clearer when seeing actual usage - please feel encouraged to examine the templates shipped with the gem (you can find them in `templates_from_gem` shown by the `singer --show-paths`).
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            ### Template location
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
            User-provided templates should be placed in the directory named `templates_from_user` in the `singer --show-paths` output.
         
     | 
| 
      
 27 
     | 
    
         
            +
            Each template resides in a subdirectory - the subdirectory's name becomes the template's name, and is not included in the generated paths (Singer will only replicate the directory structure _inside_ it).
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            ### Variables available to templates
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            Templates written in ERB or other templating mechanisms that execute Ruby code will have access to Singer::CONFIGURATION object and its accessors. For example, the following code in a `my_template`'s file:
         
     | 
| 
      
 32 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 33 
     | 
    
         
            +
            class <%= Singer::CONFIGURATION.project_name_camelcase %>
         
     | 
| 
      
 34 
     | 
    
         
            +
            ```
         
     | 
| 
      
 35 
     | 
    
         
            +
            will, when Singer is called with `singer my_template foo_bar_baz`, result in this written to output file:
         
     | 
| 
      
 36 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 37 
     | 
    
         
            +
            class FooBarBaz
         
     | 
| 
      
 38 
     | 
    
         
            +
            ```
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
            To see an up-to-date list of available variables, run `singer --list-variables`.
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
            ### Special segments in template paths
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
            Any of the variables above can be also used in paths/filenames of template files, capitalized and surrounded by double underscores.
         
     | 
| 
      
 45 
     | 
    
         
            +
            So, if `my_template` has a file at this path:
         
     | 
| 
      
 46 
     | 
    
         
            +
            ```
         
     | 
| 
      
 47 
     | 
    
         
            +
            docs_for___PROJECT_NAME_SNAKECASE__/__PROJECT_NAME_CAMELCASE__ - humble beginnings.txt
         
     | 
| 
      
 48 
     | 
    
         
            +
            ```
         
     | 
| 
      
 49 
     | 
    
         
            +
            and you run `singer my_template alpha_beta`, a file named like this will be created:
         
     | 
| 
      
 50 
     | 
    
         
            +
            ```
         
     | 
| 
      
 51 
     | 
    
         
            +
            docs_for_alpha_beta/AlphaBeta - humble beginnings.txt
         
     | 
| 
      
 52 
     | 
    
         
            +
            ```
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
            Tiny caveat for completeness - while `template_file_name_actual` can be used inside template files, the `__TEMPLATE_FILE_NAME_ACTUAL__` will not be substituted in paths.
         
     | 
| 
      
 55 
     | 
    
         
            +
            "Stack level too deep" and all that ;)
         
     | 
| 
       12 
56 
     | 
    
         | 
| 
       13 
57 
     | 
    
         
             
            ## Development
         
     | 
| 
       14 
58 
     | 
    
         | 
    
        data/exe/singer
    CHANGED
    
    
    
        data/lib/singer/configuration.rb
    CHANGED
    
    | 
         @@ -1,4 +1,9 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module Singer
         
     | 
| 
       2 
2 
     | 
    
         
             
            	# holds settings
         
     | 
| 
       3 
     | 
    
         
            -
            	CONFIGURATION = Struct.new( 
     | 
| 
      
 3 
     | 
    
         
            +
            	CONFIGURATION = Struct.new(
         
     | 
| 
      
 4 
     | 
    
         
            +
            		:template_name,
         
     | 
| 
      
 5 
     | 
    
         
            +
            		:project_name_original, :project_name_camelcase, :project_name_snakecase,
         
     | 
| 
      
 6 
     | 
    
         
            +
            		:template_file_name_original, :template_file_name_actual,
         
     | 
| 
      
 7 
     | 
    
         
            +
            	).new
         
     | 
| 
      
 8 
     | 
    
         
            +
            	CONFIGURATION_VARIABLES_FORBIDDEN_IN_PATHS = %w[template_file_name_actual].freeze
         
     | 
| 
       4 
9 
     | 
    
         
             
            end
         
     | 
| 
         @@ -0,0 +1,61 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Singer
         
     | 
| 
      
 2 
     | 
    
         
            +
            	# extracts what we need from ARGV
         
     | 
| 
      
 3 
     | 
    
         
            +
            	class OptionParsing
         
     | 
| 
      
 4 
     | 
    
         
            +
            		DEFAULT_TEMPLATE_NAME = 'tdd'.freeze
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            		def self.configure(argvies) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
         
     | 
| 
      
 7 
     | 
    
         
            +
            			options = {}
         
     | 
| 
      
 8 
     | 
    
         
            +
            			OptionParser.new do |parser|
         
     | 
| 
      
 9 
     | 
    
         
            +
            				parser.banner = <<~USAGE
         
     | 
| 
      
 10 
     | 
    
         
            +
            					Usage: #{$PROGRAM_NAME} [OPTION]... [TEMPLATE_NAME] PROJECT_NAME
         
     | 
| 
      
 11 
     | 
    
         
            +
            					Generates a project from a multi-file template.
         
     | 
| 
      
 12 
     | 
    
         
            +
            					PROJECT_NAME can be in snake_case or CamelCase.
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            					Options:
         
     | 
| 
      
 15 
     | 
    
         
            +
            				USAGE
         
     | 
| 
      
 16 
     | 
    
         
            +
            				parser.on('--list-templates', 'list all available templates') do
         
     | 
| 
      
 17 
     | 
    
         
            +
            					list_all_templates
         
     | 
| 
      
 18 
     | 
    
         
            +
            					Kernel.exit
         
     | 
| 
      
 19 
     | 
    
         
            +
            				end
         
     | 
| 
      
 20 
     | 
    
         
            +
            				parser.on('--show-paths', 'show paths used to load files') do
         
     | 
| 
      
 21 
     | 
    
         
            +
            					show_paths
         
     | 
| 
      
 22 
     | 
    
         
            +
            					Kernel.exit
         
     | 
| 
      
 23 
     | 
    
         
            +
            				end
         
     | 
| 
      
 24 
     | 
    
         
            +
            				parser.on('--list-variables', 'list all variables available to templates') do
         
     | 
| 
      
 25 
     | 
    
         
            +
            					list_variables
         
     | 
| 
      
 26 
     | 
    
         
            +
            					Kernel.exit
         
     | 
| 
      
 27 
     | 
    
         
            +
            				end
         
     | 
| 
      
 28 
     | 
    
         
            +
            			end.parse!(argvies, into: options)
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
            			raise NameMissingError, 'Missing mandatory argument PROJECT_NAME' if argvies.empty?
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
            			encase_name(argvies.pop)
         
     | 
| 
      
 33 
     | 
    
         
            +
            			CONFIGURATION.template_name = argvies.shift || DEFAULT_TEMPLATE_NAME
         
     | 
| 
      
 34 
     | 
    
         
            +
            		end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
            		def self.list_all_templates
         
     | 
| 
      
 37 
     | 
    
         
            +
            			columnize_hash(Template.all.transform_values(&:path))
         
     | 
| 
      
 38 
     | 
    
         
            +
            		end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
            		def self.show_paths
         
     | 
| 
      
 41 
     | 
    
         
            +
            			columnize_hash(%w[singer_config_dir templates_from_user templates_from_gem].to_h{ [_1, Paths.send(_1)] })
         
     | 
| 
      
 42 
     | 
    
         
            +
            		end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
            		def self.columnize_hash(hash)
         
     | 
| 
      
 45 
     | 
    
         
            +
            			first_column_width = hash.keys.map(&:length).max
         
     | 
| 
      
 46 
     | 
    
         
            +
            			hash.each do |k, v|
         
     | 
| 
      
 47 
     | 
    
         
            +
            				puts "#{k.to_s.ljust(first_column_width)} #{v}"
         
     | 
| 
      
 48 
     | 
    
         
            +
            			end
         
     | 
| 
      
 49 
     | 
    
         
            +
            		end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
            		def self.list_variables
         
     | 
| 
      
 52 
     | 
    
         
            +
            			puts CONFIGURATION.members
         
     | 
| 
      
 53 
     | 
    
         
            +
            		end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
            		def self.encase_name(name)
         
     | 
| 
      
 56 
     | 
    
         
            +
            			CONFIGURATION.project_name_original = name
         
     | 
| 
      
 57 
     | 
    
         
            +
            			CONFIGURATION.project_name_snakecase = name.gsub(/(\w)([A-Z])/){ "#{$1}_#{$2}" }.gsub(/_+/, '_').downcase
         
     | 
| 
      
 58 
     | 
    
         
            +
            			CONFIGURATION.project_name_camelcase = CONFIGURATION.project_name_snakecase.split('_').map(&:capitalize).join
         
     | 
| 
      
 59 
     | 
    
         
            +
            		end
         
     | 
| 
      
 60 
     | 
    
         
            +
            	end
         
     | 
| 
      
 61 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/singer/paths.rb
    CHANGED
    
    | 
         @@ -1,6 +1,18 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module Singer
         
     | 
| 
       2 
2 
     | 
    
         
             
            	# helps find files
         
     | 
| 
       3 
3 
     | 
    
         
             
            	class Paths
         
     | 
| 
      
 4 
     | 
    
         
            +
            		def self.xdg_config_dir
         
     | 
| 
      
 5 
     | 
    
         
            +
            			@xdg_config_dir ||= ENV.fetch('XDG_CONFIG_DIR', File.join(Dir.home, '.config'))
         
     | 
| 
      
 6 
     | 
    
         
            +
            		end
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            		def self.singer_config_dir
         
     | 
| 
      
 9 
     | 
    
         
            +
            			@singer_config_dir ||= File.join(xdg_config_dir, 'singer')
         
     | 
| 
      
 10 
     | 
    
         
            +
            		end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            		def self.templates_from_user
         
     | 
| 
      
 13 
     | 
    
         
            +
            			@templates_from_user ||= File.join(singer_config_dir, 'templates')
         
     | 
| 
      
 14 
     | 
    
         
            +
            		end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
       4 
16 
     | 
    
         
             
            		def self.templates_from_gem
         
     | 
| 
       5 
17 
     | 
    
         
             
            			@templates_from_gem ||= File.expand_path('../../templates', __dir__)
         
     | 
| 
       6 
18 
     | 
    
         
             
            		end
         
     | 
| 
         @@ -9,12 +21,16 @@ module Singer 
     | 
|
| 
       9 
21 
     | 
    
         
             
            			File.join(...).gsub(/__([[:alpha:]][[:word:]]+)__/) do |match|
         
     | 
| 
       10 
22 
     | 
    
         
             
            				potential_config = $1.downcase
         
     | 
| 
       11 
23 
     | 
    
         | 
| 
       12 
     | 
    
         
            -
            				if  
     | 
| 
      
 24 
     | 
    
         
            +
            				if variable_name_can_be_substituted?(potential_config)
         
     | 
| 
       13 
25 
     | 
    
         
             
            					CONFIGURATION.send(potential_config)
         
     | 
| 
       14 
26 
     | 
    
         
             
            				else
         
     | 
| 
       15 
27 
     | 
    
         
             
            					match
         
     | 
| 
       16 
28 
     | 
    
         
             
            				end
         
     | 
| 
       17 
29 
     | 
    
         
             
            			end
         
     | 
| 
       18 
30 
     | 
    
         
             
            		end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
            		def self.variable_name_can_be_substituted?(name)
         
     | 
| 
      
 33 
     | 
    
         
            +
            			CONFIGURATION.respond_to?(name) && !CONFIGURATION_VARIABLES_FORBIDDEN_IN_PATHS.include?(name)
         
     | 
| 
      
 34 
     | 
    
         
            +
            		end
         
     | 
| 
       19 
35 
     | 
    
         
             
            	end
         
     | 
| 
       20 
36 
     | 
    
         
             
            end
         
     | 
    
        data/lib/singer/template.rb
    CHANGED
    
    | 
         @@ -8,7 +8,13 @@ module Singer 
     | 
|
| 
       8 
8 
     | 
    
         
             
            		end
         
     | 
| 
       9 
9 
     | 
    
         | 
| 
       10 
10 
     | 
    
         
             
            		def self.load_all
         
     | 
| 
       11 
     | 
    
         
            -
            			 
     | 
| 
      
 11 
     | 
    
         
            +
            			[Paths.templates_from_gem, Paths.templates_from_user]
         
     | 
| 
      
 12 
     | 
    
         
            +
            				.map{ load_from_directory(_1) }
         
     | 
| 
      
 13 
     | 
    
         
            +
            				.reduce(&:merge)
         
     | 
| 
      
 14 
     | 
    
         
            +
            		end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            		def self.load_from_directory(dir)
         
     | 
| 
      
 17 
     | 
    
         
            +
            			Dir[File.join(dir, '*')].to_h do |template_dir|
         
     | 
| 
       12 
18 
     | 
    
         
             
            				[File.basename(template_dir), new(template_dir)]
         
     | 
| 
       13 
19 
     | 
    
         
             
            			end
         
     | 
| 
       14 
20 
     | 
    
         
             
            		end
         
     | 
| 
         @@ -25,9 +31,12 @@ module Singer 
     | 
|
| 
       25 
31 
     | 
    
         | 
| 
       26 
32 
     | 
    
         
             
            		def generate(output_path)
         
     | 
| 
       27 
33 
     | 
    
         
             
            			files.each do |file|
         
     | 
| 
       28 
     | 
    
         
            -
            				 
     | 
| 
      
 34 
     | 
    
         
            +
            				CONFIGURATION.template_file_name_original = file
         
     | 
| 
       29 
35 
     | 
    
         
             
            				target_file = Paths.output_path(output_path, file)
         
     | 
| 
      
 36 
     | 
    
         
            +
            				CONFIGURATION.template_file_name_actual = target_file
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
       30 
38 
     | 
    
         
             
            				FileUtils.mkdir_p(File.dirname(target_file))
         
     | 
| 
      
 39 
     | 
    
         
            +
            				source_file = File.join(path, file)
         
     | 
| 
       31 
40 
     | 
    
         
             
            				TemplatingMethods.send(:erb, source_file, target_file)
         
     | 
| 
       32 
41 
     | 
    
         
             
            			end
         
     | 
| 
       33 
42 
     | 
    
         
             
            		end
         
     | 
    
        data/lib/singer/version.rb
    CHANGED
    
    
    
        data/lib/singer.rb
    CHANGED
    
    | 
         @@ -1,29 +1,18 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            require_relative 'singer/version'
         
     | 
| 
       2 
2 
     | 
    
         
             
            require_relative 'singer/configuration'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require_relative 'singer/option_parsing'
         
     | 
| 
       3 
4 
     | 
    
         
             
            require_relative 'singer/paths'
         
     | 
| 
       4 
5 
     | 
    
         
             
            require_relative 'singer/template'
         
     | 
| 
       5 
6 
     | 
    
         
             
            require_relative 'singer/templating_methods'
         
     | 
| 
       6 
7 
     | 
    
         | 
| 
      
 8 
     | 
    
         
            +
            require 'optparse'
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
       7 
10 
     | 
    
         
             
            # Singer, which generates Sinatra apps etc. from templates
         
     | 
| 
       8 
11 
     | 
    
         
             
            module Singer
         
     | 
| 
       9 
12 
     | 
    
         
             
            	class Error < StandardError; end
         
     | 
| 
       10 
13 
     | 
    
         
             
            	class NameMissingError < StandardError; end
         
     | 
| 
       11 
14 
     | 
    
         
             
            	class TemplateUnknown < StandardError; end
         
     | 
| 
       12 
15 
     | 
    
         | 
| 
       13 
     | 
    
         
            -
            	DEFAULT_TEMPLATE_NAME = 'tdd'.freeze
         
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
            	def self.configure(argvies)
         
     | 
| 
       16 
     | 
    
         
            -
            		raise NameMissingError, 'Missing mandatory argument NAME' if argvies.empty?
         
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
            		encase_name(argvies.pop)
         
     | 
| 
       19 
     | 
    
         
            -
            		CONFIGURATION.template_name = argvies.shift || DEFAULT_TEMPLATE_NAME
         
     | 
| 
       20 
     | 
    
         
            -
            	end
         
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
            	def self.encase_name(name)
         
     | 
| 
       23 
     | 
    
         
            -
            		CONFIGURATION.snakecase_name = name.gsub(/(\w)([A-Z])/){ "#{$1}_#{$2}" }.gsub(/_+/, '_').downcase
         
     | 
| 
       24 
     | 
    
         
            -
            		CONFIGURATION.camelcase_name = CONFIGURATION.snakecase_name.split('_').map(&:capitalize).join
         
     | 
| 
       25 
     | 
    
         
            -
            	end
         
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
16 
     | 
    
         
             
            	def self.generate
         
     | 
| 
       28 
17 
     | 
    
         
             
            		unless Template.all.key?(CONFIGURATION.template_name)
         
     | 
| 
       29 
18 
     | 
    
         
             
            			raise TemplateUnknown, "Template #{CONFIGURATION.template_name.inspect} not found"
         
     | 
| 
         @@ -3,7 +3,7 @@ require 'haml' 
     | 
|
| 
       3 
3 
     | 
    
         
             
            require 'sassc'
         
     | 
| 
       4 
4 
     | 
    
         
             
            require 'colorize'
         
     | 
| 
       5 
5 
     | 
    
         | 
| 
       6 
     | 
    
         
            -
            module <%= Singer::CONFIGURATION. 
     | 
| 
      
 6 
     | 
    
         
            +
            module <%= Singer::CONFIGURATION.project_name_camelcase %>
         
     | 
| 
       7 
7 
     | 
    
         
             
            	# Sinatra app with routes
         
     | 
| 
       8 
8 
     | 
    
         
             
            	class Server < Sinatra::Base
         
     | 
| 
       9 
9 
     | 
    
         
             
            		set :root, '.' # to make directory structure with views/ work
         
     | 
| 
         @@ -10,7 +10,7 @@ class TestServerErrorDumping < Minitest::Test 
     | 
|
| 
       10 
10 
     | 
    
         
             
            			refute message.lines.any?{ _1.include?('/vendor/') } # now you don't
         
     | 
| 
       11 
11 
     | 
    
         
             
            		end
         
     | 
| 
       12 
12 
     | 
    
         | 
| 
       13 
     | 
    
         
            -
            		app = <%= Singer::CONFIGURATION. 
     | 
| 
      
 13 
     | 
    
         
            +
            		app = <%= Singer::CONFIGURATION.project_name_camelcase %>::Server.new! # .new! returns real instance without Sinatra::Wrapper
         
     | 
| 
       14 
14 
     | 
    
         
             
            		app.dump_errors!(exc, log)
         
     | 
| 
       15 
15 
     | 
    
         
             
            	end
         
     | 
| 
       16 
16 
     | 
    
         | 
| 
         @@ -3,6 +3,6 @@ require 'minitest_helper' 
     | 
|
| 
       3 
3 
     | 
    
         
             
            # TODO: remove
         
     | 
| 
       4 
4 
     | 
    
         
             
            class TestHello < Minitest::Test
         
     | 
| 
       5 
5 
     | 
    
         
             
            	def test_greet_with_a_param_generates_a_greeting_string
         
     | 
| 
       6 
     | 
    
         
            -
            		assert_equal 'Hello, stranger.', <%= Singer::CONFIGURATION. 
     | 
| 
      
 6 
     | 
    
         
            +
            		assert_equal 'Hello, stranger.', <%= Singer::CONFIGURATION.project_name_camelcase %>::Hello.greet(:stranger)
         
     | 
| 
       7 
7 
     | 
    
         
             
            	end
         
     | 
| 
       8 
8 
     | 
    
         
             
            end
         
     | 
| 
         @@ -1,13 +1,13 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            require 'colorize'
         
     | 
| 
       2 
2 
     | 
    
         
             
            # require 'awesome_print'
         
     | 
| 
       3 
3 
     | 
    
         | 
| 
       4 
     | 
    
         
            -
            class <%= Singer::CONFIGURATION. 
     | 
| 
      
 4 
     | 
    
         
            +
            class <%= Singer::CONFIGURATION.project_name_camelcase %>
         
     | 
| 
       5 
5 
     | 
    
         
             
            	def hello(who:)
         
     | 
| 
       6 
6 
     | 
    
         
             
            		"Hello, #{who}."
         
     | 
| 
       7 
7 
     | 
    
         
             
            	end
         
     | 
| 
       8 
8 
     | 
    
         
             
            end
         
     | 
| 
       9 
9 
     | 
    
         | 
| 
       10 
10 
     | 
    
         
             
            if File.expand_path($PROGRAM_NAME) == File.expand_path(__FILE__)
         
     | 
| 
       11 
     | 
    
         
            -
            	ciastka = <%= Singer::CONFIGURATION. 
     | 
| 
      
 11 
     | 
    
         
            +
            	ciastka = <%= Singer::CONFIGURATION.project_name_camelcase %>.new
         
     | 
| 
       12 
12 
     | 
    
         
             
            	puts "Testing testing: #{ciastka.hello(who: :world).green}"
         
     | 
| 
       13 
13 
     | 
    
         
             
            end
         
     | 
| 
         @@ -0,0 +1,16 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'minitest/rg'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'minitest/autorun' if $PROGRAM_NAME == __FILE__
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            require_relative '../lib/<%= Singer::CONFIGURATION.project_name_snakecase %>'
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            class Test<%= Singer::CONFIGURATION.project_name_camelcase %> < Minitest::Test
         
     | 
| 
      
 7 
     | 
    
         
            +
            	# TEST_INPUT = File.read('input_mini.txt').lines(chomp: true)
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            	def setup
         
     | 
| 
      
 10 
     | 
    
         
            +
            		@<%= Singer::CONFIGURATION.project_name_snakecase %> = <%= Singer::CONFIGURATION.project_name_camelcase %>.new
         
     | 
| 
      
 11 
     | 
    
         
            +
            	end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            	def test_hello_interpolates_into_string
         
     | 
| 
      
 14 
     | 
    
         
            +
            		assert_equal 'Hello, world.', @<%= Singer::CONFIGURATION.project_name_snakecase %>.hello(who: :world)
         
     | 
| 
      
 15 
     | 
    
         
            +
            	end
         
     | 
| 
      
 16 
     | 
    
         
            +
            end
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,13 +1,13 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: singer
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version:  
     | 
| 
      
 4 
     | 
    
         
            +
              version: 1.1.0
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Emil Chludziński
         
     | 
| 
       8 
8 
     | 
    
         
             
            bindir: exe
         
     | 
| 
       9 
9 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       10 
     | 
    
         
            -
            date: 2025- 
     | 
| 
      
 10 
     | 
    
         
            +
            date: 2025-02-09 00:00:00.000000000 Z
         
     | 
| 
       11 
11 
     | 
    
         
             
            dependencies:
         
     | 
| 
       12 
12 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       13 
13 
     | 
    
         
             
              name: erb
         
     | 
| 
         @@ -38,6 +38,7 @@ files: 
     | 
|
| 
       38 
38 
     | 
    
         
             
            - exe/singer
         
     | 
| 
       39 
39 
     | 
    
         
             
            - lib/singer.rb
         
     | 
| 
       40 
40 
     | 
    
         
             
            - lib/singer/configuration.rb
         
     | 
| 
      
 41 
     | 
    
         
            +
            - lib/singer/option_parsing.rb
         
     | 
| 
       41 
42 
     | 
    
         
             
            - lib/singer/paths.rb
         
     | 
| 
       42 
43 
     | 
    
         
             
            - lib/singer/template.rb
         
     | 
| 
       43 
44 
     | 
    
         
             
            - lib/singer/templating_methods.rb
         
     | 
| 
         @@ -47,8 +48,8 @@ files: 
     | 
|
| 
       47 
48 
     | 
    
         
             
            - templates/sinatra_app/config/config.ru
         
     | 
| 
       48 
49 
     | 
    
         
             
            - templates/sinatra_app/config/puma.rb
         
     | 
| 
       49 
50 
     | 
    
         
             
            - templates/sinatra_app/exe/server.rb
         
     | 
| 
       50 
     | 
    
         
            -
            - templates/sinatra_app/lib/ 
     | 
| 
       51 
     | 
    
         
            -
            - templates/sinatra_app/lib/ 
     | 
| 
      
 51 
     | 
    
         
            +
            - templates/sinatra_app/lib/__PROJECT_NAME_SNAKECASE__/hello.rb
         
     | 
| 
      
 52 
     | 
    
         
            +
            - templates/sinatra_app/lib/__PROJECT_NAME_SNAKECASE__/server.rb
         
     | 
| 
       52 
53 
     | 
    
         
             
            - templates/sinatra_app/lib/zeitwerk_setup.rb
         
     | 
| 
       53 
54 
     | 
    
         
             
            - templates/sinatra_app/test/minitest_helper.rb
         
     | 
| 
       54 
55 
     | 
    
         
             
            - templates/sinatra_app/test/server/test_server.rb
         
     | 
| 
         @@ -59,8 +60,8 @@ files: 
     | 
|
| 
       59 
60 
     | 
    
         
             
            - templates/sinatra_app/views/layout.haml
         
     | 
| 
       60 
61 
     | 
    
         
             
            - templates/sinatra_app/views/style.sass
         
     | 
| 
       61 
62 
     | 
    
         
             
            - templates/tdd/Gemfile
         
     | 
| 
       62 
     | 
    
         
            -
            - templates/tdd/lib/ 
     | 
| 
       63 
     | 
    
         
            -
            - templates/tdd/test/ 
     | 
| 
      
 63 
     | 
    
         
            +
            - templates/tdd/lib/__PROJECT_NAME_SNAKECASE__.rb
         
     | 
| 
      
 64 
     | 
    
         
            +
            - templates/tdd/test/test___PROJECT_NAME_SNAKECASE__.rb
         
     | 
| 
       64 
65 
     | 
    
         
             
            homepage: https://gitlab.com/tanstaafl/singer/
         
     | 
| 
       65 
66 
     | 
    
         
             
            licenses:
         
     | 
| 
       66 
67 
     | 
    
         
             
            - MIT
         
     | 
| 
         @@ -1,16 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require 'minitest/rg'
         
     | 
| 
       2 
     | 
    
         
            -
            require 'minitest/autorun' if $PROGRAM_NAME == __FILE__
         
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
            require_relative '../lib/<%= Singer::CONFIGURATION.snakecase_name %>'
         
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
            class Test<%= Singer::CONFIGURATION.camelcase_name %> < Minitest::Test
         
     | 
| 
       7 
     | 
    
         
            -
            	# TEST_INPUT = File.read('input_mini.txt').lines(chomp: true)
         
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
            	def setup
         
     | 
| 
       10 
     | 
    
         
            -
            		@<%= Singer::CONFIGURATION.snakecase_name %> = <%= Singer::CONFIGURATION.camelcase_name %>.new
         
     | 
| 
       11 
     | 
    
         
            -
            	end
         
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
            	def test_hello_interpolates_into_string
         
     | 
| 
       14 
     | 
    
         
            -
            		assert_equal 'Hello, world.', @<%= Singer::CONFIGURATION.snakecase_name %>.hello(who: :world)
         
     | 
| 
       15 
     | 
    
         
            -
            	end
         
     | 
| 
       16 
     | 
    
         
            -
            end
         
     |