module Swift::Gist
Constants
- ERB_TEMPLATE
- VERSION
Public Class Methods
format_swift_module(swift_module)
click to toggle source
This function generates a valid swift case for each SwiftModule
.
The resulting output will be something like:
.target(name: “SomeModule”) .target(name: “SomeModule”, dependencies: [“SomeOtherModule”]) .testTarget(name: “SomeModuleTests”, dependencies: [“SomeOtherModule”])
# File lib/swift/gist/format_swift_module.rb, line 11 def self.format_swift_module swift_module target_type = swift_module.type == :src ? 'target' : 'testTarget' formatted_name = %Q|name: "#{swift_module.name}"| formatted_dependencies = "dependencies: [%s]" % swift_module.depends_on.map { |dependency| %Q|"#{dependency}"| }.join(', ') %Q|.%{target_type}(%{formatted_name}%{formatted_dependencies})| % { target_type: target_type, formatted_name: formatted_name, formatted_dependencies: swift_module.depends_on.count > 0 ? ", #{formatted_dependencies}" : "" } end
generate_project( swift_modules, mktmpdir: Dir.method(:mktmpdir), open: File.method(:open), spm_package_creator: method(:spm_package_definition_from_swift_modules), spm_project_creator: method(:spm_project_from_swift_modules) )
click to toggle source
# File lib/swift/gist/generate_project.rb, line 4 def self.generate_project( swift_modules, mktmpdir: Dir.method(:mktmpdir), open: File.method(:open), spm_package_creator: method(:spm_package_definition_from_swift_modules), spm_project_creator: method(:spm_project_from_swift_modules) ) mktmpdir.call.tap do |tmp_dir| spm_project_creator.call swift_modules, tmp_dir: tmp_dir open.call("#{tmp_dir}/Package.swift", 'w') do |file| file.puts spm_package_creator.call(swift_modules) end end end
generate_project_art(swift_modules, tmp_dir)
click to toggle source
# File lib/swift/gist/generate_project_art.rb, line 3 def self.generate_project_art swift_modules, tmp_dir description = StringIO.new description.puts tmp_dir description.puts '.' description.puts "├── Package.swift" description.puts "└── Sources" swift_modules.sort_by { |swift_module| swift_module.name }.each_with_index do |swift_module, index| description.print index == swift_modules.length - 1 ? " └── " : " ├── " description.puts swift_module.name swift_module.sources.sort.each_with_index do |source, source_index| description.print index == swift_modules.length - 1 ? " " : " │" description.print source_index == swift_module.sources.length - 1 ? " └── " : " ├── " description.puts source end end description.string end
parse_command_line_arguments(arguments)
click to toggle source
The CLI creates a new module for every `–module` or `–test-module` argument. The `–source` and `–depends-on` arguments are all applied to the last defined swift module.
# File lib/swift/gist/cli.rb, line 16 def self.parse_command_line_arguments arguments unless arguments.count > 0 error = CLIError.new(<<REASON Usage: swift-gist [--module[=<name>]] [--test-module[=<name>]] [--source[=<glob>]] [--depends-on[=<module name>]] REASON ) raise error end swift_modules = [] OptionParser.new do |parser| parser.on('--module MODULE') do |module_name| swift_modules << SwiftModule.new(module_name, :src, []) end parser.on('--source SOURCE') do |source| if swift_modules.last.nil? raise CLIError.new("Error: The `--source` argument requires that a `--module` or `--test-module` has already been defined.") end swift_modules.last.sources |= Dir[source] end parser.on('--test-module MODULE') do |module_name| swift_modules << SwiftModule.new(module_name, :test, []) end parser.on('--depends-on MODULE') do |module_name| if swift_modules.last.nil? raise CLIError.new("Error: The `--depends-on` argument requires that a `--module` or `--test-module` has already been defined.") end swift_modules.last.depends_on << module_name end end.parse arguments swift_modules.each do |swift_module| if swift_module.sources.count == 0 raise CLIError.new("Error: The module '#{swift_module.name}' does not have any valid sources.") end end swift_modules end
run( arguments, chdir: Dir.method(:chdir), cli: method(:parse_command_line_arguments), formatted_date: -> { Time.iso8601(Time.now.iso8601) }
click to toggle source
This is the ugly command that binds everything together.
1 - Parses command line arguments 2 - Creates a SPM project linking just the files specified with `–source` arguments
# File lib/swift/gist/runner.rb, line 12 def self.run( arguments, chdir: Dir.method(:chdir), cli: method(:parse_command_line_arguments), formatted_date: -> { Time.iso8601(Time.now.iso8601) }, project_art_generator: method(:generate_project_art), project_generator: method(:generate_project), rm_rf: FileUtils.method(:rm_rf), stdin_watcher: method(:watch_stdin), stdout: $stdout.method(:puts), system: method(:system), watcher: method(:watch_sources) ) begin swift_modules = cli.call arguments rescue CLIError => error puts error.reason exit end begin tmp_dir = project_generator.call(swift_modules) stdout.call project_art_generator.call(swift_modules, tmp_dir) chdir.call(tmp_dir) do system.call('swift test') end counter = 1 build_command = -> { stdout.call "\n\n-----> Running `$ swift test` @ '#{formatted_date.call}' - Build ##{counter}" chdir.call(tmp_dir) do system.call('swift test') end counter += 1 } watcher.call(swift_modules, &build_command) stdin_watcher.call(&build_command) ensure rm_rf.call tmp_dir end 0 end
spm_package_definition_from_swift_modules(swift_modules, format_swift_module: method(:format_swift_module))
click to toggle source
# File lib/swift/gist/spm_package_creator.rb, line 5 def self.spm_package_definition_from_swift_modules swift_modules, format_swift_module: method(:format_swift_module) formatted_modules = swift_modules.map { |swift_module| format_swift_module.call swift_module } ERB.new(ERB_TEMPLATE).result(binding) end
spm_project_from_swift_modules( swift_modules, tmp_dir:, mkdir_p: FileUtils.method(:mkdir_p), pwd: Dir.method(:pwd), ln_s: FileUtils.method(:ln_s) )
click to toggle source
# File lib/swift/gist/spm_project_creator.rb, line 4 def self.spm_project_from_swift_modules( swift_modules, tmp_dir:, mkdir_p: FileUtils.method(:mkdir_p), pwd: Dir.method(:pwd), ln_s: FileUtils.method(:ln_s) ) swift_modules.each do |swift_module| mkdir_p.call "#{tmp_dir}/Sources/#{swift_module.name}" swift_module.sources.each do |source| ln_s.call "#{pwd.call}/#{source}", "#{tmp_dir}/Sources/#{swift_module.name}" end end end
watch_sources(swift_modules, listener: Listen) { || ... }
click to toggle source
# File lib/swift/gist/file_watcher.rb, line 5 def self.watch_sources swift_modules, listener: Listen sources = Set.new(swift_modules.map { |swift_module| swift_module.sources }.flatten) dirs = Set.new(sources.map { |path| Dir.exist?(path) ? path : File.dirname(path) }) listener.to(*dirs, only: /.*swift/, relative: true) do |modified, created, deleted| next unless sources.intersect?(Set.new(modified + created + deleted)) yield end.start end
watch_stdin(stdin: STDIN) { || ... }
click to toggle source
# File lib/swift/gist/stdin_watcher.rb, line 4 def self.watch_stdin stdin: STDIN while stdin.gets yield end end