mwc 0.2.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 +7 -0
- data/.gitignore +11 -0
- data/.overcommit.yml +34 -0
- data/.rspec +3 -0
- data/.travis.yml +7 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +65 -0
- data/LICENSE.txt +21 -0
- data/README.md +110 -0
- data/Rakefile +8 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/exe/mwc +6 -0
- data/lib/mwc.rb +56 -0
- data/lib/mwc/command.rb +25 -0
- data/lib/mwc/commands/compile.rb +26 -0
- data/lib/mwc/commands/init.rb +72 -0
- data/lib/mwc/commands/server.rb +26 -0
- data/lib/mwc/compile_options.rb +94 -0
- data/lib/mwc/config.rb +81 -0
- data/lib/mwc/mruby.rb +14 -0
- data/lib/mwc/project.rb +25 -0
- data/lib/mwc/server.rb +32 -0
- data/lib/mwc/tasks.rb +83 -0
- data/lib/mwc/templates/.gitignore +11 -0
- data/lib/mwc/templates/config/build.rb +44 -0
- data/lib/mwc/templates/mwcrc.erb +12 -0
- data/lib/mwc/utils/command.rb +110 -0
- data/lib/mwc/utils/command_registry.rb +45 -0
- data/lib/mwc/version.rb +5 -0
- data/mwasm.gemspec +43 -0
- metadata +189 -0
data/lib/mwc/command.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'thor'
|
4
|
+
|
5
|
+
require 'mwc/utils/command_registry'
|
6
|
+
require 'mwc/config'
|
7
|
+
require 'mwc/commands/init'
|
8
|
+
require 'mwc/commands/compile'
|
9
|
+
require 'mwc/commands/server'
|
10
|
+
|
11
|
+
module Mwc
|
12
|
+
# :nodoc:
|
13
|
+
class Command < Thor
|
14
|
+
include Utils::CommandRegistry
|
15
|
+
|
16
|
+
desc 'version', 'show version'
|
17
|
+
def version
|
18
|
+
puts Mwc::VERSION
|
19
|
+
end
|
20
|
+
|
21
|
+
add_command Commands::Init
|
22
|
+
add_command Commands::Compile
|
23
|
+
add_command Commands::Server
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'thor/rake_compat'
|
4
|
+
|
5
|
+
require 'mwc/utils/command'
|
6
|
+
require 'mwc/tasks'
|
7
|
+
require 'mwc'
|
8
|
+
|
9
|
+
module Mwc
|
10
|
+
module Commands
|
11
|
+
# Compile mruby to wasm
|
12
|
+
class Compile < Thor::Group
|
13
|
+
include Utils::Command
|
14
|
+
|
15
|
+
name 'compile'
|
16
|
+
description 'compile source code to wasm'
|
17
|
+
display_on { Mwc.config.exist? }
|
18
|
+
add_option :format, default: 'html', enum: %w[html js wasm]
|
19
|
+
|
20
|
+
def compile
|
21
|
+
Tasks.new
|
22
|
+
Rake::Task[parent_options['format']].invoke
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'mwc/utils/command'
|
4
|
+
require 'mwc'
|
5
|
+
|
6
|
+
module Mwc
|
7
|
+
module Commands
|
8
|
+
# Create a new project
|
9
|
+
class Init < Thor::Group
|
10
|
+
include Thor::Actions
|
11
|
+
include Utils::Command
|
12
|
+
|
13
|
+
name 'init'
|
14
|
+
usage 'init NAME'
|
15
|
+
description 'create a new project'
|
16
|
+
display_on { !Mwc.config.exist? }
|
17
|
+
argument :name, type: :string, desc: 'project name'
|
18
|
+
|
19
|
+
def create_project
|
20
|
+
empty_directory(name)
|
21
|
+
self.destination_root = name
|
22
|
+
Mwc.root = destination_root
|
23
|
+
end
|
24
|
+
|
25
|
+
# :nodoc:
|
26
|
+
def create_mwcrc
|
27
|
+
template('mwcrc.erb', '.mwcrc')
|
28
|
+
end
|
29
|
+
|
30
|
+
# :nodoc:
|
31
|
+
def setup_project
|
32
|
+
empty_directory('vendor')
|
33
|
+
empty_directory('dist')
|
34
|
+
empty_directory('src/js')
|
35
|
+
copy_file('config/build.rb')
|
36
|
+
copy_file('.gitignore')
|
37
|
+
end
|
38
|
+
|
39
|
+
# :nodoc:
|
40
|
+
def download_mruby
|
41
|
+
Mwc.config.reload!
|
42
|
+
# TODO: Allow choose download mode
|
43
|
+
inside(mruby_directory.dirname) do
|
44
|
+
run("curl -OL #{archive_url}")
|
45
|
+
run("tar -zxf #{filename}")
|
46
|
+
remove_file(filename)
|
47
|
+
run("mv mruby-#{version} #{mruby_directory}")
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def version
|
54
|
+
Mwc.config.mruby.version
|
55
|
+
end
|
56
|
+
|
57
|
+
# :nodoc:
|
58
|
+
def archive_url
|
59
|
+
"https://github.com/mruby/mruby/archive/#{filename}"
|
60
|
+
end
|
61
|
+
|
62
|
+
# :nodoc:
|
63
|
+
def filename
|
64
|
+
"#{version}.tar.gz"
|
65
|
+
end
|
66
|
+
|
67
|
+
def mruby_directory
|
68
|
+
Mwc.config.mruby.path
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rack'
|
4
|
+
|
5
|
+
require 'mwc/utils/command'
|
6
|
+
require 'mwc/server'
|
7
|
+
require 'mwc'
|
8
|
+
|
9
|
+
module Mwc
|
10
|
+
module Commands
|
11
|
+
# :nodoc:
|
12
|
+
class Server < Thor::Group
|
13
|
+
include Utils::Command
|
14
|
+
|
15
|
+
name 'server'
|
16
|
+
description 'serve compiled wasm'
|
17
|
+
add_option :port, type: :numeric, default: 8080
|
18
|
+
|
19
|
+
def boot
|
20
|
+
Rack::Handler
|
21
|
+
.default
|
22
|
+
.run(Mwc::Server.new, Port: parent_options['port'])
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'mwc'
|
4
|
+
|
5
|
+
module Mwc
|
6
|
+
# The compile options
|
7
|
+
class CompileOptions
|
8
|
+
# :nodoc:
|
9
|
+
EXTRA_JS_TYPE = {
|
10
|
+
library_js: '--js-library',
|
11
|
+
pre_js: '--pre-js',
|
12
|
+
post_js: '--post-js'
|
13
|
+
}.freeze
|
14
|
+
|
15
|
+
OPTIONS = %i[shell source_map extra].freeze
|
16
|
+
|
17
|
+
# :nodoc:
|
18
|
+
def initialize(options = {})
|
19
|
+
@options = []
|
20
|
+
|
21
|
+
options.each do |name, value|
|
22
|
+
handler = "add_#{name}"
|
23
|
+
send(handler, value) if respond_to?(handler)
|
24
|
+
end
|
25
|
+
|
26
|
+
OPTIONS.each { |name| send("setup_#{name}") }
|
27
|
+
output(options[:format])
|
28
|
+
end
|
29
|
+
|
30
|
+
# Setup shell file
|
31
|
+
#
|
32
|
+
# @since 0.2.0
|
33
|
+
# @api private
|
34
|
+
def setup_shell
|
35
|
+
return if Mwc.config.project.shell.nil?
|
36
|
+
|
37
|
+
path = Mwc.root.join(Mwc.config.project.shell)
|
38
|
+
@options.push "--shell-file #{path}"
|
39
|
+
end
|
40
|
+
|
41
|
+
# Setup source map
|
42
|
+
#
|
43
|
+
# @since 0.2.0
|
44
|
+
# @api private
|
45
|
+
def setup_source_map
|
46
|
+
return unless Mwc.config.project.source_map
|
47
|
+
|
48
|
+
@options.push '-g4 --source-map-base /'
|
49
|
+
end
|
50
|
+
|
51
|
+
# Setup extra options
|
52
|
+
#
|
53
|
+
# @since 0.2.0
|
54
|
+
# @api private
|
55
|
+
def setup_extra
|
56
|
+
return unless Mwc.config.project.options.any?
|
57
|
+
|
58
|
+
Mwc.config.project.options.each do |name, value|
|
59
|
+
@options.push "-s #{name}=#{value}"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Convert options to string
|
64
|
+
#
|
65
|
+
# @return [String] the options
|
66
|
+
def to_s
|
67
|
+
@options.join(' ')
|
68
|
+
end
|
69
|
+
|
70
|
+
# Configure extra javacript
|
71
|
+
#
|
72
|
+
# @since 0.2.0
|
73
|
+
# @api private
|
74
|
+
%i[library_js pre_js post_js].each do |type|
|
75
|
+
define_method "add_#{type}" do |items|
|
76
|
+
items.each do |path|
|
77
|
+
@options.push "#{EXTRA_JS_TYPE[type]} #{path}"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
# Configure output format
|
85
|
+
#
|
86
|
+
# @param foramt [String] output format
|
87
|
+
#
|
88
|
+
# @since 0.1.0
|
89
|
+
# @api private
|
90
|
+
def output(format)
|
91
|
+
@options.push "-o dist/#{Mwc.config.project.name}.#{format}"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
data/lib/mwc/config.rb
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'forwardable'
|
4
|
+
require 'singleton'
|
5
|
+
|
6
|
+
require 'mwc/project'
|
7
|
+
require 'mwc/mruby'
|
8
|
+
require 'mwc'
|
9
|
+
|
10
|
+
module Mwc
|
11
|
+
# The compile preferences
|
12
|
+
class Config
|
13
|
+
class << self
|
14
|
+
extend Forwardable
|
15
|
+
|
16
|
+
delegate %i[
|
17
|
+
exist?
|
18
|
+
mruby
|
19
|
+
] => :instance
|
20
|
+
end
|
21
|
+
|
22
|
+
include Singleton
|
23
|
+
|
24
|
+
attr_reader :project, :mruby
|
25
|
+
|
26
|
+
# :nodoc:
|
27
|
+
def initialize
|
28
|
+
@path = Mwc.root.join('.mwcrc')
|
29
|
+
@project = Project.new
|
30
|
+
@mruby = MRuby.new
|
31
|
+
|
32
|
+
load_config if exist?
|
33
|
+
end
|
34
|
+
|
35
|
+
# TODO: Move to DSL module
|
36
|
+
# Set name
|
37
|
+
#
|
38
|
+
# @param name [String|NilClass] the name
|
39
|
+
#
|
40
|
+
# @since 0.1.0
|
41
|
+
# @api private
|
42
|
+
def name(name = nil)
|
43
|
+
return @name if name.nil?
|
44
|
+
|
45
|
+
@name = name.to_s
|
46
|
+
end
|
47
|
+
|
48
|
+
# Check config file exists
|
49
|
+
#
|
50
|
+
# @return [TrueClass,FalseClass] exist or not
|
51
|
+
#
|
52
|
+
# @since 0.1.0
|
53
|
+
# @api private
|
54
|
+
def exist?
|
55
|
+
@path.exist?
|
56
|
+
end
|
57
|
+
|
58
|
+
# Reload config
|
59
|
+
#
|
60
|
+
# @since 0.1.0
|
61
|
+
# @api private
|
62
|
+
def reload!
|
63
|
+
# TODO: Update path when root changed
|
64
|
+
@path = Mwc.root.join('.mwcrc')
|
65
|
+
return unless exist?
|
66
|
+
|
67
|
+
load_config
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
# Laod .mwcrc config
|
73
|
+
#
|
74
|
+
# @since 0.1.0
|
75
|
+
# @api private
|
76
|
+
def load_config
|
77
|
+
# TODO: Improve config DSL
|
78
|
+
instance_eval(@path.read)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
data/lib/mwc/mruby.rb
ADDED
data/lib/mwc/project.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mwc
|
4
|
+
# The project settings
|
5
|
+
class Project
|
6
|
+
attr_accessor :name, :shell, :source_map
|
7
|
+
attr_reader :options
|
8
|
+
|
9
|
+
# :nodoc:
|
10
|
+
def initialize
|
11
|
+
@options = {}
|
12
|
+
end
|
13
|
+
|
14
|
+
# Add customize options
|
15
|
+
#
|
16
|
+
# @param name [String] the option name
|
17
|
+
# @param value [String] the option value
|
18
|
+
#
|
19
|
+
# @since 0.2.0
|
20
|
+
# @api private
|
21
|
+
def option(name, value)
|
22
|
+
@options[name] = value
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/mwc/server.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'singleton'
|
4
|
+
require 'forwardable'
|
5
|
+
require 'rack'
|
6
|
+
|
7
|
+
require 'mwc'
|
8
|
+
|
9
|
+
module Mwc
|
10
|
+
# Static assets server
|
11
|
+
class Server
|
12
|
+
WASM_RULE = /\.(?:wasm)\z/.freeze
|
13
|
+
WASM_HEADER = { 'Content-Type' => 'application/wasm' }.freeze
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
@static =
|
17
|
+
Rack::Static.new(
|
18
|
+
->(_) { [404, {}, []] },
|
19
|
+
root: 'dist', # TODO: Set by config
|
20
|
+
index: "#{Mwc.config.project.name}.html",
|
21
|
+
urls: [''],
|
22
|
+
header_rules: [
|
23
|
+
[WASM_RULE, WASM_HEADER]
|
24
|
+
]
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
def call(env)
|
29
|
+
@static.call(env)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/mwc/tasks.rb
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rake/tasklib'
|
4
|
+
|
5
|
+
require 'mwc/compile_options'
|
6
|
+
require 'mwc'
|
7
|
+
|
8
|
+
module Mwc
|
9
|
+
# :nodoc:
|
10
|
+
class Tasks < Rake::TaskLib
|
11
|
+
SOURCES = FileList['src/**/*.c']
|
12
|
+
BINARIES = SOURCES.ext('bc')
|
13
|
+
LIBRARY_JS = FileList['src/js/**/*.lib.js']
|
14
|
+
PRE_JS = FileList['src/js/**/*.pre.js']
|
15
|
+
POST_JS = FileList['src/js/**/*.post.js']
|
16
|
+
|
17
|
+
# :nodoc:
|
18
|
+
def initialize
|
19
|
+
return unless mruby_directory.join('Rakefile').exist?
|
20
|
+
|
21
|
+
namespace :mruby do
|
22
|
+
ENV['MRUBY_CONFIG'] = Mwc.root.join('config', 'build.rb').to_s
|
23
|
+
# TODO: Prevent load error breaks command
|
24
|
+
load mruby_directory.join('Rakefile')
|
25
|
+
end
|
26
|
+
|
27
|
+
compile_binary_task
|
28
|
+
compile_wasm_task
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
# :nodoc:
|
34
|
+
def compile_binary_task
|
35
|
+
rule '.bc' => SOURCES do |task|
|
36
|
+
sh "emcc -I #{mruby_directory.join('include')} -I include -c " \
|
37
|
+
"#{task.source} -o #{task.name}"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# :nodoc:
|
42
|
+
def compile_wasm_task
|
43
|
+
%i[wasm html js].each do |format|
|
44
|
+
task "mruby.#{format}" => ['mruby:all'].concat(BINARIES) do
|
45
|
+
compile(format)
|
46
|
+
end
|
47
|
+
|
48
|
+
desc "Compile sources to #{format} WebAssembly"
|
49
|
+
task format => "mruby.#{format}"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# :nodoc:
|
54
|
+
def compile(format)
|
55
|
+
do_compile CompileOptions.new(
|
56
|
+
format: format,
|
57
|
+
library_js: LIBRARY_JS,
|
58
|
+
pre_js: PRE_JS,
|
59
|
+
post_js: POST_JS
|
60
|
+
)
|
61
|
+
end
|
62
|
+
|
63
|
+
# :nodoc:
|
64
|
+
def do_compile(options)
|
65
|
+
sh "emcc #{sources.join(' ')} #{options}"
|
66
|
+
end
|
67
|
+
|
68
|
+
# :nodoc:
|
69
|
+
def libmruby
|
70
|
+
mruby_directory.join('build/wasm/lib/libmruby.bc')
|
71
|
+
end
|
72
|
+
|
73
|
+
# :nodoc:
|
74
|
+
def sources
|
75
|
+
[libmruby].concat(BINARIES)
|
76
|
+
end
|
77
|
+
|
78
|
+
# :nodoc:
|
79
|
+
def mruby_directory
|
80
|
+
Mwc.config.mruby.path
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|