Brian Silverman | b67da23 | 2015-09-12 23:50:30 -0400 | [diff] [blame] | 1 | ZIP_PATH = '/usr/bin/zip' |
| 2 | |
| 3 | ruby_file_types = FileType(['.rb']) |
| 4 | |
| 5 | def _collect_transitive_sources(ctx): |
Austin Schuh | 9d92e6b | 2017-10-17 01:19:38 -0700 | [diff] [blame] | 6 | source_files = depset(order='postorder') |
Brian Silverman | b67da23 | 2015-09-12 23:50:30 -0400 | [diff] [blame] | 7 | for dep in ctx.attr.deps: |
| 8 | source_files += dep.transitive_ruby_files |
| 9 | |
| 10 | source_files += ruby_file_types.filter(ctx.files.srcs) |
| 11 | return source_files |
| 12 | |
| 13 | def _ruby_library_impl(ctx): |
| 14 | transitive_sources = _collect_transitive_sources(ctx) |
| 15 | return struct( |
| 16 | transitive_ruby_files = transitive_sources, |
| 17 | ) |
| 18 | |
| 19 | def _ruby_binary_impl(ctx): |
| 20 | main_file = ctx.files.srcs[0] |
| 21 | transitive_sources = _collect_transitive_sources(ctx) |
| 22 | executable = ctx.outputs.executable |
| 23 | manifest_file = ctx.outputs.manifest |
| 24 | |
| 25 | path_map = '\n'.join([('%s|%s' % (item.short_path, item.path)) |
| 26 | for item in transitive_sources]) |
| 27 | ctx.file_action(output=manifest_file, content=path_map) |
| 28 | |
| 29 | ctx.action( |
| 30 | inputs = list(transitive_sources) + [manifest_file], |
| 31 | outputs = [ executable ], |
| 32 | arguments = [ manifest_file.path, executable.path, main_file.path ], |
| 33 | executable = ctx.executable._ruby_linker, |
| 34 | ) |
| 35 | |
| 36 | return struct( |
Austin Schuh | 9d92e6b | 2017-10-17 01:19:38 -0700 | [diff] [blame] | 37 | files = depset([executable]), |
Brian Silverman | b67da23 | 2015-09-12 23:50:30 -0400 | [diff] [blame] | 38 | runfiles = ctx.runfiles(collect_data = True), |
| 39 | ) |
| 40 | |
| 41 | |
| 42 | _ruby_attrs = { |
| 43 | 'srcs': attr.label_list( |
| 44 | allow_files = ruby_file_types, |
| 45 | mandatory = True, |
| 46 | non_empty = True, |
| 47 | ), |
| 48 | 'deps': attr.label_list( |
| 49 | providers = ['transitive_ruby_files'], |
| 50 | allow_files = False, |
| 51 | ), |
| 52 | 'data': attr.label_list( |
| 53 | allow_files = True, |
Brian Silverman | b200c17 | 2017-01-02 17:35:35 -0800 | [diff] [blame] | 54 | cfg = 'data', |
Brian Silverman | b67da23 | 2015-09-12 23:50:30 -0400 | [diff] [blame] | 55 | ), |
| 56 | } |
| 57 | |
| 58 | '''Packages ruby code into a library. |
| 59 | |
| 60 | The files can use require with paths from the base of the workspace and/or |
| 61 | require_relative with other files that are part of the library. |
| 62 | require also works from the filesystem as usual. |
| 63 | |
| 64 | Attrs: |
| 65 | srcs: Ruby source files to include. |
| 66 | deps: Other ruby_library rules to include. |
| 67 | ''' |
| 68 | ruby_library = rule( |
| 69 | implementation = _ruby_library_impl, |
| 70 | attrs = _ruby_attrs, |
| 71 | ) |
| 72 | |
| 73 | '''Packages ruby code into a binary which can be run. |
| 74 | |
| 75 | See ruby_library for details on how require works. |
| 76 | |
| 77 | Attrs: |
| 78 | srcs: Ruby source files to include. The first one is loaded to at startup. |
| 79 | deps: ruby_library rules to include. |
| 80 | ''' |
| 81 | ruby_binary = rule( |
| 82 | implementation = _ruby_binary_impl, |
| 83 | executable = True, |
| 84 | attrs = _ruby_attrs + { |
| 85 | '_ruby_linker': attr.label( |
| 86 | executable = True, |
Brian Silverman | b200c17 | 2017-01-02 17:35:35 -0800 | [diff] [blame] | 87 | cfg = 'host', |
Brian Silverman | b67da23 | 2015-09-12 23:50:30 -0400 | [diff] [blame] | 88 | default = Label('//tools/ruby:standalone_ruby'), |
| 89 | ) |
| 90 | }, |
| 91 | outputs = { |
| 92 | 'manifest': '%{name}.tar_manifest', |
| 93 | }, |
| 94 | ) |