sscharter 0.7.0 → 0.9.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 +4 -4
- data/Gemfile +0 -13
- data/Gemfile.lock +13 -15
- data/LICENSE +1 -1
- data/README.md +3 -3
- data/Rakefile +12 -6
- data/lib/sscharter/chart.rb +35 -3
- data/lib/sscharter/cli.rb +48 -27
- data/lib/sscharter/version.rb +1 -1
- data/lib/sscharter.rb +520 -178
- data/tutorial/tutorial.md +71 -6
- metadata +34 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bd7619bb9674b4ec547ba0484ff931c1f39603ffa03fc0a32e826ef4e83adb46
|
4
|
+
data.tar.gz: 668322b1a02019b1ebfad49332cea047c8cd91f5f2de62be88a68dc64460a88c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ec041e5ebef20b6e9794a91b842ef7446305732564bdf6e8afd25e4d5a2281d9b6cbb37787a11cee7ce29d2a581aa31bbdf513bdb9f0661f5498e4b412ea26f9
|
7
|
+
data.tar.gz: 9e10bf1ef26b57f7cade038f5cc5cf290aa14b72050c6c3136f96a0c0511dff2ce43300a0b81fb66c0d75deda496ba1da4a13a174ff53f36b2ffb6cbc4f883ad
|
data/Gemfile
CHANGED
@@ -2,17 +2,4 @@
|
|
2
2
|
|
3
3
|
source "https://rubygems.org"
|
4
4
|
|
5
|
-
# Specify your gem's dependencies in sscharter.gemspec
|
6
5
|
gemspec
|
7
|
-
|
8
|
-
group :develop do
|
9
|
-
gem 'rake', '~> 13.0'
|
10
|
-
gem 'minitest', '~> 5.0'
|
11
|
-
end
|
12
|
-
|
13
|
-
gem 'rubyzip', '~> 2.3'
|
14
|
-
gem 'launchy', '~> 2.5'
|
15
|
-
gem 'webrick', '~> 1.8'
|
16
|
-
gem 'filewatcher', '~> 2.0'
|
17
|
-
gem 'em-websocket', '~> 0.5'
|
18
|
-
gem 'concurrent-ruby', '~> 1.3'
|
data/Gemfile.lock
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
sscharter (0.
|
4
|
+
sscharter (0.9.0)
|
5
|
+
base64
|
5
6
|
concurrent-ruby (~> 1.3)
|
6
7
|
em-websocket (~> 0.5)
|
7
8
|
filewatcher (~> 2.0)
|
8
9
|
launchy (~> 2.5)
|
9
|
-
rubyzip (~>
|
10
|
+
rubyzip (~> 3.1)
|
10
11
|
webrick (~> 1.8)
|
11
12
|
|
12
13
|
GEM
|
@@ -14,7 +15,8 @@ GEM
|
|
14
15
|
specs:
|
15
16
|
addressable (2.8.7)
|
16
17
|
public_suffix (>= 2.0.2, < 7.0)
|
17
|
-
|
18
|
+
base64 (0.3.0)
|
19
|
+
concurrent-ruby (1.3.5)
|
18
20
|
em-websocket (0.5.3)
|
19
21
|
eventmachine (>= 0.12.9)
|
20
22
|
http_parser.rb (~> 0)
|
@@ -24,27 +26,23 @@ GEM
|
|
24
26
|
http_parser.rb (0.8.0)
|
25
27
|
launchy (2.5.2)
|
26
28
|
addressable (~> 2.8)
|
27
|
-
minitest (5.25.
|
29
|
+
minitest (5.25.5)
|
28
30
|
module_methods (0.1.0)
|
29
|
-
public_suffix (6.0.
|
30
|
-
rake (13.
|
31
|
-
rubyzip (
|
32
|
-
webrick (1.
|
31
|
+
public_suffix (6.0.2)
|
32
|
+
rake (13.3.0)
|
33
|
+
rubyzip (3.1.0)
|
34
|
+
webrick (1.9.1)
|
35
|
+
yard (0.9.37)
|
33
36
|
|
34
37
|
PLATFORMS
|
35
38
|
x64-mingw-ucrt
|
36
39
|
x86_64-linux
|
37
40
|
|
38
41
|
DEPENDENCIES
|
39
|
-
concurrent-ruby (~> 1.3)
|
40
|
-
em-websocket (~> 0.5)
|
41
|
-
filewatcher (~> 2.0)
|
42
|
-
launchy (~> 2.5)
|
43
42
|
minitest (~> 5.0)
|
44
43
|
rake (~> 13.0)
|
45
|
-
rubyzip (~> 2.3)
|
46
44
|
sscharter!
|
47
|
-
|
45
|
+
yard (~> 0.9)
|
48
46
|
|
49
47
|
BUNDLED WITH
|
50
|
-
2.
|
48
|
+
2.7.1
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# sscharter
|
2
2
|
|
3
3
|
A Ruby DSL for writing Sunniesnow charts.
|
4
4
|
|
@@ -7,7 +7,7 @@ A Ruby DSL for writing Sunniesnow charts.
|
|
7
7
|
[Install Ruby](https://www.ruby-lang.org/en/documentation/installation/).
|
8
8
|
Then, run
|
9
9
|
|
10
|
-
```
|
10
|
+
```
|
11
11
|
gem install sscharter
|
12
12
|
```
|
13
13
|
|
@@ -27,4 +27,4 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/sunnie
|
|
27
27
|
|
28
28
|
## Code of Conduct
|
29
29
|
|
30
|
-
Everyone interacting in the
|
30
|
+
Everyone interacting in the sscharter project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/sunniesnow/sscharter/blob/master/CODE_OF_CONDUCT.md).
|
data/Rakefile
CHANGED
@@ -1,12 +1,18 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require 'bundler/gem_tasks'
|
4
|
+
require 'rake/testtask'
|
5
|
+
require 'yard'
|
5
6
|
|
6
|
-
Rake::TestTask.new
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
Rake::TestTask.new :test do |t|
|
8
|
+
t.libs << 'test'
|
9
|
+
t.libs << 'lib'
|
10
|
+
t.test_files = FileList['test/**/test_*.rb']
|
11
|
+
end
|
12
|
+
|
13
|
+
YARD::Rake::YardocTask.new do |t|
|
14
|
+
t.files.concat %w[README.md]
|
15
|
+
t.options.concat %w[--title sscharter --output-dir doc --exclude lib/sscharter/cli.rb --readme]
|
10
16
|
end
|
11
17
|
|
12
18
|
task default: :test
|
data/lib/sscharter/chart.rb
CHANGED
@@ -2,14 +2,41 @@
|
|
2
2
|
|
3
3
|
require 'json'
|
4
4
|
|
5
|
+
# A class to represent a chart.
|
6
|
+
# Basically a wrapper around the metadata and events ({Sunniesnow::Event}) of a chart.
|
7
|
+
# The main method is {#to_json}, which converts the chart to a JSON string
|
8
|
+
# that is actually recognizable by Sunniesnow.
|
5
9
|
class Sunniesnow::Chart
|
6
10
|
|
7
11
|
using Sunniesnow::Utils
|
8
12
|
|
9
|
-
|
10
|
-
|
13
|
+
# The schema URL for the output JSON.
|
14
|
+
# This will be set as the `$schema` property in the generated JSON.
|
15
|
+
SCHEMA = 'https://sunniesnow.github.io/schema/chart-1.0.json'
|
16
|
+
|
17
|
+
# The title of the music.
|
18
|
+
# This is one of the metadata of the chart which will be reflected in the generated JSON.
|
19
|
+
# Also, see
|
20
|
+
# {chart file specifications}[https://sunniesnow.github.io/doc/chart.html#title]
|
21
|
+
# for more info.
|
22
|
+
attr_accessor :title
|
23
|
+
|
24
|
+
attr_accessor :artist
|
25
|
+
attr_accessor :charter
|
26
|
+
attr_accessor :difficulty_name
|
27
|
+
attr_accessor :difficulty_color
|
28
|
+
attr_accessor :difficulty
|
29
|
+
attr_accessor :difficulty_sup
|
30
|
+
|
31
|
+
# An array of Sunniesnow::Event.
|
11
32
|
attr_reader :events
|
12
33
|
|
34
|
+
# @param [Integer] live_reload_port The port to use for live reload.
|
35
|
+
# It is useless if +production+ is +true+.
|
36
|
+
# @param [Boolean] production Whether the chart is in production or not.
|
37
|
+
# If +true+, the generated JSON (see {#to_json}) will not contain
|
38
|
+
# necessary information for sscharter integration in Sunniesnow
|
39
|
+
# (such as the live reload feature and reverse search feature).
|
13
40
|
def initialize live_reload_port: 31108, production: false
|
14
41
|
@title = ''
|
15
42
|
@artist = ''
|
@@ -23,8 +50,13 @@ class Sunniesnow::Chart
|
|
23
50
|
@production = production
|
24
51
|
end
|
25
52
|
|
53
|
+
##
|
54
|
+
# Convert to JSON.
|
55
|
+
# A Sunniesnow chart is always a JSON file in the level file.
|
56
|
+
# This method is used to generate that JSON file.
|
26
57
|
def to_json *args
|
27
58
|
hash = {
|
59
|
+
'$schema': SCHEMA,
|
28
60
|
title: @title,
|
29
61
|
artist: @artist,
|
30
62
|
charter: @charter,
|
@@ -38,7 +70,7 @@ class Sunniesnow::Chart
|
|
38
70
|
version: Sunniesnow::Charter::VERSION,
|
39
71
|
port: @live_reload_port
|
40
72
|
} unless @production
|
41
|
-
hash.to_json
|
73
|
+
hash.to_json *args
|
42
74
|
end
|
43
75
|
end
|
44
76
|
|
data/lib/sscharter/cli.rb
CHANGED
@@ -22,13 +22,12 @@ module Sunniesnow
|
|
22
22
|
module_function
|
23
23
|
|
24
24
|
def config
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
puts 'No .sscharter.yml found'
|
25
|
+
filenames = %w[sscharter.yml sscharter.yaml .sscharter.yml .sscharter.yaml].map { File.join PROJECT_DIR, _1 }
|
26
|
+
unless filename = filenames.find { File.exist? _1 }
|
27
|
+
$stderr.puts 'Config file sscharter.yml not found'
|
29
28
|
return nil
|
30
29
|
end
|
31
|
-
YAML.load_file
|
30
|
+
YAML.load_file filename, symbolize_names: true
|
32
31
|
end
|
33
32
|
|
34
33
|
singleton_class.attr_reader :commands
|
@@ -87,20 +86,18 @@ Sunniesnow::Charter::CLI::Subcommand.new :init, option_parser do |project_dir =
|
|
87
86
|
FileUtils.cp_r files, files_dir
|
88
87
|
FileUtils.cd project_dir do
|
89
88
|
File.write 'Gemfile', <<~GEMFILE
|
90
|
-
# frozen_string_literal: true
|
91
89
|
source 'https://rubygems.org'
|
92
90
|
gem 'sscharter', '~> #{Sunniesnow::Charter::VERSION}'
|
93
91
|
gem 'rake', '~> #{Rake::VERSION}'
|
94
92
|
gem 'bundler', '~> #{Bundler::VERSION}'
|
95
93
|
GEMFILE
|
96
94
|
File.write 'Rakefile', <<~RAKEFILE
|
97
|
-
# frozen_string_literal: true
|
98
95
|
task default: :build
|
99
96
|
task :build do
|
100
97
|
exec 'bundle exec sscharter build'
|
101
98
|
end
|
102
99
|
task :serve do
|
103
|
-
exec 'bundle exec sscharter serve'
|
100
|
+
exec 'bundle exec sscharter serve --no-open-browser'
|
104
101
|
end
|
105
102
|
RAKEFILE
|
106
103
|
File.write '.gitignore', <<~GITIGNORE
|
@@ -108,7 +105,7 @@ Sunniesnow::Charter::CLI::Subcommand.new :init, option_parser do |project_dir =
|
|
108
105
|
/tmp/
|
109
106
|
/build/
|
110
107
|
GITIGNORE
|
111
|
-
File.write '
|
108
|
+
File.write 'sscharter.yml', <<~SSCHARTER
|
112
109
|
---
|
113
110
|
project_name: #{File.basename project_dir}
|
114
111
|
build_dir: build
|
@@ -136,21 +133,19 @@ Sunniesnow::Charter::CLI::Subcommand.new :init, option_parser do |project_dir =
|
|
136
133
|
README
|
137
134
|
FileUtils.mkdir_p 'src'
|
138
135
|
File.write 'src/master.rb', <<~CHART
|
139
|
-
# frozen_string_literal: true
|
140
|
-
|
141
136
|
Sunniesnow::Charter.open 'master' do
|
142
137
|
|
143
138
|
title 'The title of the music'
|
144
139
|
artist 'The artist of the music'
|
145
140
|
charter 'Your name'
|
146
141
|
difficulty_name 'Master'
|
147
|
-
difficulty_color
|
142
|
+
difficulty_color :master
|
148
143
|
difficulty '12'
|
149
144
|
|
150
145
|
offset 0
|
151
146
|
bpm 120
|
152
147
|
|
153
|
-
tp_chain 0,
|
148
|
+
tp_chain 0, 100, 1 do
|
154
149
|
t -50, 0, 'hello'
|
155
150
|
b 1 # proceed by 1 beat
|
156
151
|
t 50, 0, 'world'
|
@@ -162,7 +157,7 @@ Sunniesnow::Charter::CLI::Subcommand.new :init, option_parser do |project_dir =
|
|
162
157
|
puts "Project initialized at #{project_dir}"
|
163
158
|
end
|
164
159
|
|
165
|
-
def build **opts
|
160
|
+
def build compression_level: Zip.default_compression, **opts, &block
|
166
161
|
return 1 unless config = Sunniesnow::Charter::CLI.config
|
167
162
|
dir = Sunniesnow::Charter::PROJECT_DIR
|
168
163
|
project_name = config[:project_name] || File.basename(dir)
|
@@ -171,17 +166,21 @@ def build **opts
|
|
171
166
|
sources_dir = File.join dir, config[:sources_dir] || 'src'
|
172
167
|
include_files = (config[:include] || []).map { File.join dir, _1 }
|
173
168
|
Sunniesnow::Charter.charts.clear
|
169
|
+
time = Time.now
|
174
170
|
Dir.glob File.join sources_dir, '*.rb' do |filename|
|
175
171
|
load filename
|
176
172
|
rescue Exception => e
|
177
173
|
puts "Error loading #{filename}:"
|
178
174
|
puts e.full_message
|
175
|
+
puts "Build aborted (took #{Time.now - time} seconds)"
|
179
176
|
return 1
|
180
177
|
end
|
178
|
+
puts "Built #{Sunniesnow::Charter.charts.size} chart(s) (took #{Time.now - time} seconds)"
|
179
|
+
time = Time.now
|
181
180
|
FileUtils.mkdir_p build_dir
|
182
181
|
build_filename = File.join build_dir, "#{project_name}.ssc"
|
183
182
|
FileUtils.rm build_filename if File.exist? build_filename
|
184
|
-
Zip::File.open build_filename, create: true do |zip_file|
|
183
|
+
Zip::File.open build_filename, compression_level:, create: true do |zip_file|
|
185
184
|
Dir.glob File.join files_dir, '**', '*' do |filename|
|
186
185
|
zip_file.add filename["#{files_dir}/".length..], filename
|
187
186
|
end
|
@@ -192,25 +191,33 @@ def build **opts
|
|
192
191
|
end
|
193
192
|
Sunniesnow::Charter.charts.each do |name, chart|
|
194
193
|
begin
|
195
|
-
|
194
|
+
sunniesnow_chart = chart.to_sunniesnow **opts
|
196
195
|
rescue => e
|
197
196
|
puts 'An error happened. Report if this is a bug of sscharter.'
|
198
197
|
puts e.full_message
|
199
198
|
return 2
|
200
199
|
end
|
200
|
+
block.(name, sunniesnow_chart) if block
|
201
201
|
zip_file.get_output_stream "#{name}.json" do |file|
|
202
|
-
file.write
|
202
|
+
file.write sunniesnow_chart.to_json
|
203
|
+
rescue => e
|
204
|
+
puts 'An error happened. Report if this is a bug of sscharter.'
|
205
|
+
puts e.full_message
|
206
|
+
return 2
|
203
207
|
end
|
204
208
|
end
|
209
|
+
zip_file.each { _1.time = Time.at 0 }
|
205
210
|
end
|
211
|
+
puts "Created #{project_name}.ssc (took #{Time.now - time} seconds)"
|
206
212
|
0
|
207
213
|
end
|
208
214
|
|
209
215
|
option_parser = OptionParser.new do |o|
|
210
216
|
o.banner = 'Usage: sscharter build'
|
217
|
+
o.on '--compression-level=LEVEL', Integer, 'Compression level (0-9)'
|
211
218
|
end
|
212
|
-
Sunniesnow::Charter::CLI::Subcommand.new :build, option_parser do
|
213
|
-
build production: true
|
219
|
+
Sunniesnow::Charter::CLI::Subcommand.new :build, option_parser do |compression_level: Zip.default_compression|
|
220
|
+
build compression_level:, production: true
|
214
221
|
end
|
215
222
|
|
216
223
|
option_parser = OptionParser.new do |o|
|
@@ -221,8 +228,17 @@ option_parser = OptionParser.new do |o|
|
|
221
228
|
o.on '--live-reload-port=PORT', Integer, 'live reload port number'
|
222
229
|
o.on '--[no-]production', 'Disable live reload'
|
223
230
|
o.on '--[no-]open-browser', 'Open browser'
|
231
|
+
o.on '--compression-level=LEVEL', Integer, 'Compression level (0-9)'
|
224
232
|
end
|
225
|
-
Sunniesnow::Charter::CLI::Subcommand.new :serve, option_parser do
|
233
|
+
Sunniesnow::Charter::CLI::Subcommand.new :serve, option_parser do |\
|
234
|
+
host: '0.0.0.0',
|
235
|
+
exposed_host: 'localhost',
|
236
|
+
port: 8011,
|
237
|
+
live_reload_port: 31108,
|
238
|
+
production: false,
|
239
|
+
open_browser: true,
|
240
|
+
compression_level: (production ? Zip.default_compression : 0)
|
241
|
+
|
|
226
242
|
return 1 unless config = Sunniesnow::Charter::CLI.config
|
227
243
|
dir = Sunniesnow::Charter::PROJECT_DIR
|
228
244
|
project_name = config[:project_name] || File.basename(dir)
|
@@ -268,18 +284,23 @@ Sunniesnow::Charter::CLI::Subcommand.new :serve, option_parser do |host: '0.0.0.
|
|
268
284
|
end
|
269
285
|
end
|
270
286
|
end
|
271
|
-
|
287
|
+
base_url = "http://#{exposed_host}:#{port}"
|
288
|
+
url = URI.join base_url, "#{project_name}.ssc"
|
272
289
|
filewatcher = Filewatcher.new [files_dir, sources_dir, *include_files]
|
273
290
|
Launchy.open "https://sunniesnow.github.io/game/?level-file=online&level-file-online=#{CGI.escape url}" if open_browser
|
274
|
-
build_proc = ->is_first do
|
291
|
+
build_proc = ->is_first, only_charts do
|
275
292
|
puts is_first ? 'Building...' : 'Rebuilding...'
|
276
|
-
|
277
|
-
|
278
|
-
|
293
|
+
build_result = build(live_reload_port:, production:, compression_level:) do |name, chart|
|
294
|
+
live_reload_clients.each { _1.send JSON.generate type: 'chartUpdate', name:, chart: } unless production
|
295
|
+
end
|
296
|
+
puts build_result == 0 ? is_first ? "Finished; access at #{url}" : 'Finished' : 'Failed'
|
297
|
+
live_reload_clients.each { _1.send JSON.generate type: 'update', onlyCharts: only_charts } unless production
|
279
298
|
end
|
280
299
|
filewatcher_thread = Thread.new do
|
281
|
-
build_proc.(true)
|
282
|
-
filewatcher.watch
|
300
|
+
build_proc.(true, false)
|
301
|
+
filewatcher.watch do |changes|
|
302
|
+
build_proc.(false, changes.all? { |filename, event| filename.start_with? sources_dir + '/' })
|
303
|
+
end
|
283
304
|
server.shutdown
|
284
305
|
EM.stop unless production
|
285
306
|
end
|