Module: Swift::Gist
- Defined in:
- lib/swift/gist.rb,
lib/swift/gist/cli.rb,
lib/swift/gist/runner.rb,
lib/swift/gist/version.rb,
lib/swift/gist/file_watcher.rb,
lib/swift/gist/swift_module.rb,
lib/swift/gist/stdin_watcher.rb,
lib/swift/gist/generate_project.rb,
lib/swift/gist/format_swift_module.rb,
lib/swift/gist/spm_package_creator.rb,
lib/swift/gist/spm_project_creator.rb,
lib/swift/gist/generate_project_art.rb
Defined Under Namespace
Classes: CLIError, SwiftModule
Constant Summary collapse
- VERSION =
"0.0.3"
Class Method Summary collapse
-
.format_swift_module(swift_module) ⇒ Object
This function generates a valid swift case for each SwiftModule.
- .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)) ⇒ Object
- .generate_project_art(swift_modules, tmp_dir) ⇒ Object
-
.parse_command_line_arguments(arguments) ⇒ Object
The CLI creates a new module for every ‘–module` or `–test-module` argument.
-
.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)) ⇒ Object
This is the ugly command that binds everything together.
- .spm_package_definition_from_swift_modules(swift_modules, format_swift_module: method(:format_swift_module)) ⇒ Object
- .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)) ⇒ Object
- .watch_sources(swift_modules, listener: Listen) ⇒ Object
- .watch_stdin(stdin: STDIN) ⇒ Object
Class Method Details
.format_swift_module(swift_module) ⇒ Object
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”])
11 12 13 14 15 16 17 18 19 20 21 |
# 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)) ⇒ Object
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# 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) ⇒ Object
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# 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) ⇒ Object
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.
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# 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) }, 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)) ⇒ Object
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
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# 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)) ⇒ Object
5 6 7 8 |
# 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)) ⇒ Object
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# 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) ⇒ Object
5 6 7 8 9 10 11 12 13 |
# 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) ⇒ Object
4 5 6 7 8 |
# File 'lib/swift/gist/stdin_watcher.rb', line 4 def self.watch_stdin stdin: STDIN while stdin.gets yield end end |