mwc 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|