processing 1.4.0 → 1.5.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/.github/workflows/release-gem.yml +2 -49
- data/.github/workflows/tag.yml +5 -28
- data/.github/workflows/test-draw.yml +11 -6
- data/.github/workflows/test.yml +1 -37
- data/ChangeLog.md +13 -0
- data/Gemfile.lock +25 -15
- data/VERSION +1 -1
- data/lib/processing/all.rb +19 -15
- data/lib/processing/context.rb +7 -4
- data/lib/processing/font.rb +11 -3
- data/lib/processing/graphics_context.rb +7 -2
- data/lib/processing/shader.rb +17 -11
- data/lib/processing/window.rb +8 -6
- data/processing.gemspec +5 -5
- data/test/browser.rb +4 -0
- data/test/test_graphics_context.rb +99 -0
- data/test/test_image.rb +19 -0
- metadata +11 -12
- data/.github/workflows/utils.rb +0 -127
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 76374671234065ea70aed78db67df170da655638e1e10dc3cd392d12a8f8c9bf
|
|
4
|
+
data.tar.gz: c8387066f1cfa2f276c557cd882639663bc17b947aef89e4b68b701b276ca1f2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f4c1b08e0f857eed89b7c07c004445270ec6cb24da946571d8c088dfd38ee5d68baab706a4d4d67c4374a8d7b60a5cbd3aa8de919a286714b3ab25a0500fbd34
|
|
7
|
+
data.tar.gz: d98a30c04ba898afc44852fc08f0d4b2b74e3f894df3a4f31c38d21442cc4ace3e74dd3eafff90a61f301fd1eca7adc4793622d533d46a1966b5671cd3a78956
|
|
@@ -9,52 +9,5 @@ permissions:
|
|
|
9
9
|
|
|
10
10
|
jobs:
|
|
11
11
|
release:
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
steps:
|
|
15
|
-
- name: ruby 3.2
|
|
16
|
-
uses: ruby/setup-ruby@v1
|
|
17
|
-
with:
|
|
18
|
-
ruby-version: 3.2
|
|
19
|
-
|
|
20
|
-
- name: checkout
|
|
21
|
-
uses: actions/checkout@v4
|
|
22
|
-
|
|
23
|
-
- name: setup gems
|
|
24
|
-
run: bundle install
|
|
25
|
-
|
|
26
|
-
- name: setup dependencies
|
|
27
|
-
run: "ruby -I.github/workflows -rutils -e 'setup_dependencies'"
|
|
28
|
-
|
|
29
|
-
- name: packages
|
|
30
|
-
run: bundle exec rake packages
|
|
31
|
-
|
|
32
|
-
- name: setup zig
|
|
33
|
-
if: github.event.repository.name == 'reflex-terminal'
|
|
34
|
-
uses: mlugg/setup-zig@v2
|
|
35
|
-
with:
|
|
36
|
-
version: 0.16.0
|
|
37
|
-
|
|
38
|
-
- name: test
|
|
39
|
-
run: bundle exec rake test
|
|
40
|
-
|
|
41
|
-
- name: create gem
|
|
42
|
-
id: gem
|
|
43
|
-
run: |
|
|
44
|
-
bundle exec rake gem
|
|
45
|
-
echo path=$(ruby -e 'print Dir.glob("*.gem").first') >> $GITHUB_OUTPUT
|
|
46
|
-
|
|
47
|
-
- name: create github release
|
|
48
|
-
env:
|
|
49
|
-
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
50
|
-
run: ruby -I.github/workflows -rutils -e 'release(*ARGV)' ./${{ steps.gem.outputs.path }}
|
|
51
|
-
|
|
52
|
-
- name: upload to rubygems
|
|
53
|
-
env:
|
|
54
|
-
GEM_HOST_API_KEY: ${{ secrets.RUBYGEMS_AUTH_TOKEN }}
|
|
55
|
-
run: |
|
|
56
|
-
mkdir -p $HOME/.gem
|
|
57
|
-
touch $HOME/.gem/credentials
|
|
58
|
-
chmod 0600 $HOME/.gem/credentials
|
|
59
|
-
printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
|
|
60
|
-
bundle exec rake upload
|
|
12
|
+
uses: xord/xot/.github/workflows/release-gem.yml@master
|
|
13
|
+
secrets: inherit
|
data/.github/workflows/tag.yml
CHANGED
|
@@ -1,35 +1,12 @@
|
|
|
1
1
|
name: Tag
|
|
2
2
|
|
|
3
3
|
on:
|
|
4
|
-
|
|
4
|
+
workflow_run:
|
|
5
|
+
workflows: [Test]
|
|
6
|
+
types: [completed]
|
|
5
7
|
branches: [master]
|
|
6
8
|
|
|
7
9
|
jobs:
|
|
8
10
|
tag:
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
steps:
|
|
12
|
-
- name: ruby 3.2
|
|
13
|
-
uses: ruby/setup-ruby@v1
|
|
14
|
-
with:
|
|
15
|
-
ruby-version: 3.2
|
|
16
|
-
|
|
17
|
-
- name: checkout
|
|
18
|
-
uses: actions/checkout@v4
|
|
19
|
-
with:
|
|
20
|
-
fetch-depth: 0
|
|
21
|
-
token: ${{ secrets.PAT }}
|
|
22
|
-
|
|
23
|
-
- name: setup dependencies
|
|
24
|
-
run: "ruby -I.github/workflows -rutils -e 'setup_dependencies only: :xot'"
|
|
25
|
-
|
|
26
|
-
- name: setup user name and email
|
|
27
|
-
run: |
|
|
28
|
-
git config --global user.email "xordog@gmail.com"
|
|
29
|
-
git config --global user.name "xord"
|
|
30
|
-
|
|
31
|
-
- name: tag versions
|
|
32
|
-
run: "ruby -I.github/workflows -rutils -e 'tag_versions'"
|
|
33
|
-
|
|
34
|
-
- name: push tags
|
|
35
|
-
run: git push origin --tags
|
|
11
|
+
uses: xord/xot/.github/workflows/tag.yml@master
|
|
12
|
+
secrets: inherit
|
|
@@ -10,19 +10,24 @@ jobs:
|
|
|
10
10
|
runs-on: macos-latest
|
|
11
11
|
|
|
12
12
|
steps:
|
|
13
|
-
- name: ruby 3.2
|
|
14
|
-
uses: ruby/setup-ruby@v1
|
|
15
|
-
with:
|
|
16
|
-
ruby-version: 3.2
|
|
17
|
-
|
|
18
13
|
- name: checkout
|
|
19
14
|
uses: actions/checkout@v4
|
|
20
15
|
|
|
16
|
+
- name: setup ruby
|
|
17
|
+
uses: ruby/setup-ruby@v1
|
|
18
|
+
with:
|
|
19
|
+
ruby-version: 3.3
|
|
20
|
+
|
|
21
21
|
- name: setup gems
|
|
22
22
|
run: bundle install
|
|
23
23
|
|
|
24
|
+
- name: setup xot
|
|
25
|
+
run: git clone -q --depth 1 https://github.com/xord/xot.git "${{ runner.temp }}/xot"
|
|
26
|
+
|
|
24
27
|
- name: setup dependencies
|
|
25
|
-
|
|
28
|
+
env:
|
|
29
|
+
RUBYLIB: ${{ runner.temp }}/xot/lib
|
|
30
|
+
run: ruby -rxot/rake -e 'setup_dependencies'
|
|
26
31
|
|
|
27
32
|
- name: setup chrome
|
|
28
33
|
uses: browser-actions/setup-chrome@latest
|
data/.github/workflows/test.yml
CHANGED
|
@@ -7,40 +7,4 @@ on:
|
|
|
7
7
|
|
|
8
8
|
jobs:
|
|
9
9
|
test:
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
steps:
|
|
13
|
-
- name: ruby 3.2
|
|
14
|
-
uses: ruby/setup-ruby@v1
|
|
15
|
-
with:
|
|
16
|
-
ruby-version: 3.2
|
|
17
|
-
|
|
18
|
-
- name: checkout
|
|
19
|
-
uses: actions/checkout@v4
|
|
20
|
-
|
|
21
|
-
- name: setup gems
|
|
22
|
-
run: bundle install
|
|
23
|
-
|
|
24
|
-
- name: setup dependencies
|
|
25
|
-
run: "ruby -I.github/workflows -rutils -e 'setup_dependencies'"
|
|
26
|
-
|
|
27
|
-
- name: packages
|
|
28
|
-
run: bundle exec rake verbose packages
|
|
29
|
-
|
|
30
|
-
- name: setup zig
|
|
31
|
-
if: github.event.repository.name == 'reflex-terminal'
|
|
32
|
-
uses: mlugg/setup-zig@v2
|
|
33
|
-
with:
|
|
34
|
-
version: 0.16.0
|
|
35
|
-
|
|
36
|
-
- name: vendor
|
|
37
|
-
run: bundle exec rake vendor
|
|
38
|
-
|
|
39
|
-
- name: lib
|
|
40
|
-
run: bundle exec rake verbose lib
|
|
41
|
-
|
|
42
|
-
- name: ext
|
|
43
|
-
run: bundle exec rake verbose ext
|
|
44
|
-
|
|
45
|
-
- name: test
|
|
46
|
-
run: bundle exec rake verbose test
|
|
10
|
+
uses: xord/xot/.github/workflows/test.yml@master
|
data/ChangeLog.md
CHANGED
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
# processing ChangeLog
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
## [v1.5.0] - 2026-11-04
|
|
5
|
+
|
|
6
|
+
- [BREAKING] loadPixels and updatePixels exchange straight alpha, not premultiplied
|
|
7
|
+
- [BREAKING] A shader from createShader sees premultiplied samples from texMap and must emit premultiplied color
|
|
8
|
+
- [BREAKING] Report wheel deltas in pixels, in the same direction, on every platform (from reflex)
|
|
9
|
+
- Add TextBounds#to_a
|
|
10
|
+
|
|
11
|
+
- Fix half-transparent images, tinted images and translucent shapes on a Graphics coming out darker than in p5.js
|
|
12
|
+
- Fix GRAY, INVERT, THRESHOLD and BLUR breaking the alpha of a Graphics with transparent pixels
|
|
13
|
+
- Fix mouseOver and mouseOut defined by def in a sketch never being called
|
|
14
|
+
- Fix a canceled press, as by a menu popping up, becoming a click
|
|
15
|
+
|
|
16
|
+
|
|
4
17
|
## [v1.4.0] - 2026-08-04
|
|
5
18
|
|
|
6
19
|
- Add mouseOver/mouseOut blocks to the sketch
|
data/Gemfile.lock
CHANGED
|
@@ -4,31 +4,26 @@ GEM
|
|
|
4
4
|
addressable (2.9.0)
|
|
5
5
|
public_suffix (>= 2.0.2, < 8.0)
|
|
6
6
|
base64 (0.3.0)
|
|
7
|
-
concurrent-ruby (1.3.
|
|
8
|
-
ferrum (0.
|
|
7
|
+
concurrent-ruby (1.3.8)
|
|
8
|
+
ferrum (0.18.0)
|
|
9
9
|
addressable (~> 2.5)
|
|
10
10
|
base64 (~> 0.2)
|
|
11
11
|
concurrent-ruby (~> 1.1)
|
|
12
|
-
webrick (~> 1.7)
|
|
13
12
|
websocket-driver (~> 0.7)
|
|
14
|
-
power_assert (3.0
|
|
15
|
-
public_suffix (
|
|
16
|
-
rake (13.
|
|
13
|
+
power_assert (3.1.0)
|
|
14
|
+
public_suffix (7.0.5)
|
|
15
|
+
rake (13.4.2)
|
|
17
16
|
rexml (3.4.4)
|
|
18
|
-
test-unit (3.7.
|
|
17
|
+
test-unit (3.7.8)
|
|
19
18
|
power_assert
|
|
20
|
-
|
|
21
|
-
websocket-driver (0.8.0)
|
|
19
|
+
websocket-driver (0.8.2)
|
|
22
20
|
base64
|
|
23
21
|
websocket-extensions (>= 0.1.0)
|
|
24
22
|
websocket-extensions (0.1.5)
|
|
25
|
-
yard (0.9.
|
|
23
|
+
yard (0.9.45)
|
|
26
24
|
|
|
27
25
|
PLATFORMS
|
|
28
|
-
|
|
29
|
-
arm64-darwin-21
|
|
30
|
-
arm64-darwin-23
|
|
31
|
-
arm64-darwin-24
|
|
26
|
+
ruby
|
|
32
27
|
|
|
33
28
|
DEPENDENCIES
|
|
34
29
|
ferrum
|
|
@@ -37,5 +32,20 @@ DEPENDENCIES
|
|
|
37
32
|
test-unit
|
|
38
33
|
yard
|
|
39
34
|
|
|
35
|
+
CHECKSUMS
|
|
36
|
+
addressable (2.9.0) sha256=7fdf6ac3660f7f4e867a0838be3f6cf722ace541dd97767fa42bc6cfa980c7af
|
|
37
|
+
base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b
|
|
38
|
+
bundler (4.0.20) sha256=7978a8ac648767f5e635bc522445b79e80a52b907a39a36c2d8085ed6bc762ae
|
|
39
|
+
concurrent-ruby (1.3.8) sha256=b2f1be836e968ccc78ccfce277ea79c72a88633f22306782c16ff23fb415d1e1
|
|
40
|
+
ferrum (0.18.0) sha256=4cb8be16e352fc1d75f087e9214b34ec1b93ba932410c730a4724909ca89d7c6
|
|
41
|
+
power_assert (3.1.0) sha256=fefe98ed5d3140628138f3f9f9194d6ece01f1320e69700d3c928adca7518251
|
|
42
|
+
public_suffix (7.0.5) sha256=1a8bb08f1bbea19228d3bed6e5ed908d1cb4f7c2726d18bd9cadf60bc676f623
|
|
43
|
+
rake (13.4.2) sha256=cb825b2bd5f1f8e91ca37bddb4b9aaf345551b4731da62949be002fa89283701
|
|
44
|
+
rexml (3.4.4) sha256=19e0a2c3425dfbf2d4fc1189747bdb2f849b6c5e74180401b15734bc97b5d142
|
|
45
|
+
test-unit (3.7.8) sha256=689d1ca53f4d46f678b4e5d68d8e4294f87fc5e8b9238cc4de7c5727e8d65943
|
|
46
|
+
websocket-driver (0.8.2) sha256=97c556b019bf3410b4961002ac501621e9322d3f8a7bc02161a09301cc4c4146
|
|
47
|
+
websocket-extensions (0.1.5) sha256=1c6ba63092cda343eb53fc657110c71c754c56484aad42578495227d717a8241
|
|
48
|
+
yard (0.9.45) sha256=52e211493f7cb8a3ebf7e104a25a1e73937a3103092545d34cb88fafebb3dc51
|
|
49
|
+
|
|
40
50
|
BUNDLED WITH
|
|
41
|
-
|
|
51
|
+
4.0.20
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.
|
|
1
|
+
1.5.0
|
data/lib/processing/all.rb
CHANGED
|
@@ -17,7 +17,7 @@ module Processing
|
|
|
17
17
|
setup draw
|
|
18
18
|
keyPressed keyReleased keyTyped
|
|
19
19
|
mousePressed mouseReleased mouseMoved mouseDragged
|
|
20
|
-
mouseClicked doubleClicked mouseWheel
|
|
20
|
+
mouseClicked doubleClicked mouseOver mouseOut mouseWheel
|
|
21
21
|
touchStarted touchEnded touchMoved
|
|
22
22
|
windowMoved windowResized motion
|
|
23
23
|
]
|
|
@@ -35,12 +35,12 @@ module Processing
|
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
# @private
|
|
38
|
-
def self.setup__(window_class, context_class)
|
|
38
|
+
def self.setup__(window_class, context_class, *args, **kwargs)
|
|
39
39
|
tmpdir__.tap {|dir| FileUtils.rm_r dir.to_s if dir.directory?} unless Xot.wasm?
|
|
40
40
|
|
|
41
41
|
w = (ENV['WIDTH'] || 500).to_i
|
|
42
42
|
h = (ENV['HEIGHT'] || 500).to_i
|
|
43
|
-
window_class.new w, h, context_class: context_class
|
|
43
|
+
window_class.new w, h, *args, context_class: context_class, **kwargs
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
# @private
|
|
@@ -56,19 +56,23 @@ module Processing
|
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
# @private
|
|
59
|
-
def self.alias_snake_case_methods__(
|
|
60
|
-
|
|
61
|
-
.
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
59
|
+
def self.alias_snake_case_methods__(*modules, recursive: 1)
|
|
60
|
+
modules.each do |mod|
|
|
61
|
+
to_snake_case__(mod.instance_methods false)
|
|
62
|
+
.reject {|camel, _| camel =~ SUFFIX_PRIVATE}
|
|
63
|
+
.reject {|camel, snake| camel == snake}
|
|
64
|
+
.each do |camel, snake|
|
|
65
|
+
mod.remove_method snake if mod.method_defined?(snake, false)
|
|
66
|
+
mod.alias_method snake, camel
|
|
67
|
+
end
|
|
68
|
+
if recursive > 0
|
|
69
|
+
mod.constants.map {mod.const_get _1}
|
|
70
|
+
.flatten
|
|
71
|
+
.select {_1.class == Module || _1.class == Class}
|
|
72
|
+
.each {|inner_class|
|
|
73
|
+
alias_snake_case_methods__ inner_class, recursive: recursive - 1
|
|
74
|
+
}
|
|
66
75
|
end
|
|
67
|
-
if recursive > 0
|
|
68
|
-
klass.constants.map {klass.const_get _1}
|
|
69
|
-
.flatten
|
|
70
|
-
.select {_1.class == Module || _1.class == Class}
|
|
71
|
-
.each {|inner_class| alias_snake_case_methods__ inner_class, recursive - 1}
|
|
72
76
|
end
|
|
73
77
|
end
|
|
74
78
|
|
data/lib/processing/context.rb
CHANGED
|
@@ -127,17 +127,20 @@ module Processing
|
|
|
127
127
|
@touchStartedBlock__&.call
|
|
128
128
|
end
|
|
129
129
|
|
|
130
|
-
|
|
130
|
+
pointerEnded = -> e, click {
|
|
131
131
|
updatePointerStates.call e
|
|
132
132
|
updatePointersPressedAndReleased.call e, false
|
|
133
133
|
if e.any? {|p| p.id == @pointer__.id}
|
|
134
134
|
@mouseReleasedBlock__&.call
|
|
135
|
-
@mouseClickedBlock__&.call if e.click_count > 0
|
|
136
|
-
@doubleClickedBlock__&.call if e.click_count == 2
|
|
135
|
+
@mouseClickedBlock__&.call if click && e.click_count > 0
|
|
136
|
+
@doubleClickedBlock__&.call if click && e.click_count == 2
|
|
137
137
|
end
|
|
138
138
|
@touchEndedBlock__&.call
|
|
139
139
|
@pointersReleased__.clear
|
|
140
|
-
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
@window__.pointer_up = proc {|e| pointerEnded.call e, true}
|
|
143
|
+
@window__.pointer_cancel = proc {|e| pointerEnded.call e, false}
|
|
141
144
|
|
|
142
145
|
@window__.pointer_move = proc do |e|
|
|
143
146
|
updatePointerStates.call e
|
data/lib/processing/font.rb
CHANGED
|
@@ -75,6 +75,11 @@ module Processing
|
|
|
75
75
|
#
|
|
76
76
|
class TextBounds
|
|
77
77
|
|
|
78
|
+
# @private
|
|
79
|
+
def initialize(x, y, w, h)
|
|
80
|
+
@x, @y, @w, @h = x, y, w, h
|
|
81
|
+
end
|
|
82
|
+
|
|
78
83
|
# Horizontal position
|
|
79
84
|
#
|
|
80
85
|
attr_reader :x
|
|
@@ -91,9 +96,12 @@ module Processing
|
|
|
91
96
|
#
|
|
92
97
|
attr_reader :h
|
|
93
98
|
|
|
94
|
-
#
|
|
95
|
-
|
|
96
|
-
|
|
99
|
+
# Returns the bounding box as an array.
|
|
100
|
+
#
|
|
101
|
+
# @return [Array<Numeric>] [x, y, w, h]
|
|
102
|
+
#
|
|
103
|
+
def to_a()
|
|
104
|
+
[x, y, w, h]
|
|
97
105
|
end
|
|
98
106
|
|
|
99
107
|
# Returns a string containing a human-readable representation of object.
|
|
@@ -1785,7 +1785,7 @@ module Processing
|
|
|
1785
1785
|
else
|
|
1786
1786
|
y -= font.ascent
|
|
1787
1787
|
end
|
|
1788
|
-
x, y = x.round, y.round unless font.smooth
|
|
1788
|
+
x, y = x.round, y.round unless font.smooth?
|
|
1789
1789
|
@painter__.text str, x, y
|
|
1790
1790
|
nil
|
|
1791
1791
|
end
|
|
@@ -3204,7 +3204,8 @@ module Processing
|
|
|
3204
3204
|
def createFont(name, size, smooth: true)
|
|
3205
3205
|
size ||= FONT_SIZE_DEFAULT__
|
|
3206
3206
|
size = FONT_SIZE_MAX__ if size > FONT_SIZE_MAX__
|
|
3207
|
-
Font.new Rays::Font.new(
|
|
3207
|
+
Font.new Rays::Font.new(
|
|
3208
|
+
name, size, weight: :normal, italic: false, smooth: smooth)
|
|
3208
3209
|
end
|
|
3209
3210
|
|
|
3210
3211
|
# Creates a new image object.
|
|
@@ -3329,6 +3330,10 @@ module Processing
|
|
|
3329
3330
|
# }
|
|
3330
3331
|
# ```
|
|
3331
3332
|
#
|
|
3333
|
+
# Colors sampled from the 'texMap' uniform are premultiplied by their
|
|
3334
|
+
# alpha, and gl_FragColor is blended as premultiplied too, so a fragment
|
|
3335
|
+
# shader should keep rgb scaled by alpha. 'vertColor' is straight alpha.
|
|
3336
|
+
#
|
|
3332
3337
|
# @overload createShader(vertPath, fragPath)
|
|
3333
3338
|
# @overload createShader(vertSource, fragSource)
|
|
3334
3339
|
#
|
data/lib/processing/shader.rb
CHANGED
|
@@ -112,9 +112,12 @@ module Processing
|
|
|
112
112
|
varying vec4 vertTexCoord;
|
|
113
113
|
varying vec4 vertColor;
|
|
114
114
|
void main() {
|
|
115
|
-
vec4
|
|
116
|
-
|
|
117
|
-
|
|
115
|
+
vec4 tex = texture2D(texMap, vertTexCoord.xy);
|
|
116
|
+
vec4 col = vec4(vertColor.rgb * vertColor.a, vertColor.a);
|
|
117
|
+
vec3 rgb = tex.a > 0.0 ? tex.rgb / tex.a : tex.rgb;
|
|
118
|
+
float gray = rgb.r * 0.3 + rgb.g * 0.59 + rgb.b * 0.11;
|
|
119
|
+
float value = gray > threshold ? 1.0 : 0.0;
|
|
120
|
+
gl_FragColor = vec4(vec3(value * tex.a), tex.a) * col;
|
|
118
121
|
}
|
|
119
122
|
END
|
|
120
123
|
|
|
@@ -124,9 +127,10 @@ module Processing
|
|
|
124
127
|
varying vec4 vertTexCoord;
|
|
125
128
|
varying vec4 vertColor;
|
|
126
129
|
void main() {
|
|
127
|
-
vec4
|
|
128
|
-
|
|
129
|
-
|
|
130
|
+
vec4 tex = texture2D(texMap, vertTexCoord.xy);
|
|
131
|
+
vec4 col = vec4(vertColor.rgb * vertColor.a, vertColor.a);
|
|
132
|
+
float gray = tex.r * 0.3 + tex.g * 0.59 + tex.b * 0.11;
|
|
133
|
+
gl_FragColor = vec4(vec3(gray), tex.a) * col;
|
|
130
134
|
}
|
|
131
135
|
END
|
|
132
136
|
|
|
@@ -136,8 +140,9 @@ module Processing
|
|
|
136
140
|
varying vec4 vertTexCoord;
|
|
137
141
|
varying vec4 vertColor;
|
|
138
142
|
void main() {
|
|
139
|
-
vec4
|
|
140
|
-
|
|
143
|
+
vec4 tex = texture2D(texMap, vertTexCoord.xy);
|
|
144
|
+
vec4 col = vec4(vertColor.rgb * vertColor.a, vertColor.a);
|
|
145
|
+
gl_FragColor = vec4(tex.a - tex.rgb, tex.a) * col;
|
|
141
146
|
}
|
|
142
147
|
END
|
|
143
148
|
|
|
@@ -157,7 +162,7 @@ module Processing
|
|
|
157
162
|
}
|
|
158
163
|
void main() {
|
|
159
164
|
float sigma = radius * 0.5;
|
|
160
|
-
|
|
165
|
+
vec4 sum = vec4(0.0);
|
|
161
166
|
float total_weight = 0.0;
|
|
162
167
|
for (float y = -radius; y < radius; y += 1.0)
|
|
163
168
|
for (float x = -radius; x < radius; x += 1.0) {
|
|
@@ -168,10 +173,11 @@ module Processing
|
|
|
168
173
|
texcoord.x < vertTexCoordMin.x || vertTexCoordMax.x < texcoord.x ||
|
|
169
174
|
texcoord.y < vertTexCoordMin.y || vertTexCoordMax.y < texcoord.y
|
|
170
175
|
) continue;
|
|
171
|
-
|
|
176
|
+
sum += texture2D(texMap, texcoord) * weight;
|
|
172
177
|
total_weight += weight;
|
|
173
178
|
}
|
|
174
|
-
|
|
179
|
+
vec4 col = vec4(vertColor.rgb * vertColor.a, vertColor.a);
|
|
180
|
+
gl_FragColor = sum / total_weight * col;
|
|
175
181
|
}
|
|
176
182
|
END
|
|
177
183
|
|
data/lib/processing/window.rb
CHANGED
|
@@ -32,7 +32,8 @@ module Processing
|
|
|
32
32
|
|
|
33
33
|
attr_accessor :setup, :update, :draw, :move, :resize, :motion,
|
|
34
34
|
:key_down, :key_up,
|
|
35
|
-
:pointer_down, :pointer_up, :pointer_move, :
|
|
35
|
+
:pointer_down, :pointer_up, :pointer_move, :pointer_cancel,
|
|
36
|
+
:pointer_enter, :pointer_leave, :wheel,
|
|
36
37
|
:note_on, :note_off, :control_change,
|
|
37
38
|
:before_draw, :after_draw, :update_window, :update_canvas
|
|
38
39
|
|
|
@@ -114,11 +115,12 @@ module Processing
|
|
|
114
115
|
|
|
115
116
|
def on_canvas_pointer(e)
|
|
116
117
|
block = case e.action
|
|
117
|
-
when :down
|
|
118
|
-
when :up
|
|
119
|
-
when :move
|
|
120
|
-
when :
|
|
121
|
-
when :
|
|
118
|
+
when :down then @pointer_down
|
|
119
|
+
when :up then @pointer_up
|
|
120
|
+
when :move then @pointer_move
|
|
121
|
+
when :cancel then @pointer_cancel
|
|
122
|
+
when :enter then @pointer_enter
|
|
123
|
+
when :leave then @pointer_leave
|
|
122
124
|
end
|
|
123
125
|
draw_canvas {call_block block, e} if block
|
|
124
126
|
end
|
data/processing.gemspec
CHANGED
|
@@ -11,7 +11,7 @@ Gem::Specification.new do |s|
|
|
|
11
11
|
|
|
12
12
|
ext = Processing::Extension
|
|
13
13
|
name = ext.name true
|
|
14
|
-
rdocs = glob.call
|
|
14
|
+
rdocs = glob.call(*%w[README])
|
|
15
15
|
|
|
16
16
|
s.name = name
|
|
17
17
|
s.version = ext.version
|
|
@@ -26,10 +26,10 @@ Gem::Specification.new do |s|
|
|
|
26
26
|
s.required_ruby_version = '>= 3.0.0'
|
|
27
27
|
|
|
28
28
|
s.add_dependency 'rexml'
|
|
29
|
-
s.add_dependency 'xot', '~> 0.
|
|
30
|
-
s.add_dependency 'rucy', '~> 0.
|
|
31
|
-
s.add_dependency 'rays', '~> 0.
|
|
32
|
-
s.add_dependency 'reflexion', '~> 0.
|
|
29
|
+
s.add_dependency 'xot', '~> 0.5.0'
|
|
30
|
+
s.add_dependency 'rucy', '~> 0.5.0'
|
|
31
|
+
s.add_dependency 'rays', '~> 0.5.0'
|
|
32
|
+
s.add_dependency 'reflexion', '~> 0.7.0'
|
|
33
33
|
|
|
34
34
|
s.files = `git ls-files`.split $/
|
|
35
35
|
s.test_files = s.files.grep %r{^(test|spec|features)/}
|
data/test/browser.rb
CHANGED
|
@@ -57,6 +57,10 @@ def get_p5rb_html(width, height, draw_src, webgl: false)
|
|
|
57
57
|
}
|
|
58
58
|
</script>
|
|
59
59
|
<script type="text/ruby">
|
|
60
|
+
class JS::Object
|
|
61
|
+
def beginDraw() = block_given? ? yield(self) : nil
|
|
62
|
+
def endDraw() = nil
|
|
63
|
+
end
|
|
60
64
|
def setup()
|
|
61
65
|
createCanvas #{width}, #{height}#{webgl ? ', WEBGL' : ''}
|
|
62
66
|
end
|
|
@@ -34,6 +34,27 @@ class TestGraphicsContext < Test::Unit::TestCase
|
|
|
34
34
|
assert_equal G::ADD, g.blendMode
|
|
35
35
|
|
|
36
36
|
assert_raise {g.blendMode LEFT}
|
|
37
|
+
|
|
38
|
+
header = <<~END
|
|
39
|
+
blendMode BLEND
|
|
40
|
+
noStroke
|
|
41
|
+
background 100, 150, 200
|
|
42
|
+
fill 200, 100, 50
|
|
43
|
+
rect 100, 100, 400, 400
|
|
44
|
+
END
|
|
45
|
+
footer = <<~END
|
|
46
|
+
rect 300, 300, 400, 400
|
|
47
|
+
END
|
|
48
|
+
%w[BLEND ADD LIGHTEST DARKEST EXCLUSION MULTIPLY SCREEN].each do |mode|
|
|
49
|
+
assert_p5_draw header, "blendMode #{mode}; fill 50, 200, 100", footer
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# LIGHTEST and DARKEST are left out: p5 lerps between the destination
|
|
53
|
+
# and max/min by the source alpha, which fixed-function GL_MAX/GL_MIN
|
|
54
|
+
# blending cannot express
|
|
55
|
+
%w[BLEND ADD EXCLUSION MULTIPLY SCREEN].each do |mode|
|
|
56
|
+
assert_p5_draw header, "blendMode #{mode}; fill 50, 200, 100, 128", footer
|
|
57
|
+
end
|
|
37
58
|
end
|
|
38
59
|
|
|
39
60
|
def test_strokeCap()
|
|
@@ -69,6 +90,27 @@ class TestGraphicsContext < Test::Unit::TestCase
|
|
|
69
90
|
assert_p5_draw header, 'strokeJoin ROUND', footer
|
|
70
91
|
end
|
|
71
92
|
|
|
93
|
+
def test_tint()
|
|
94
|
+
header = <<~END
|
|
95
|
+
noStroke
|
|
96
|
+
background 0, 255, 0
|
|
97
|
+
unless @img
|
|
98
|
+
@img = createGraphics 400, 400
|
|
99
|
+
@img.beginDraw
|
|
100
|
+
@img.noStroke
|
|
101
|
+
@img.background 255, 0, 0
|
|
102
|
+
@img.endDraw
|
|
103
|
+
end
|
|
104
|
+
END
|
|
105
|
+
footer = <<~END
|
|
106
|
+
image @img, 100, 100
|
|
107
|
+
END
|
|
108
|
+
assert_p5_draw header, '', footer
|
|
109
|
+
assert_p5_draw header, 'tint 255, 128', footer
|
|
110
|
+
assert_p5_draw header, 'tint 128, 255', footer
|
|
111
|
+
assert_p5_draw header, 'tint 0, 0, 255, 128', footer
|
|
112
|
+
end
|
|
113
|
+
|
|
72
114
|
def test_textFont()
|
|
73
115
|
graphics do |g|
|
|
74
116
|
arial10 = g.createFont 'Arial', 10
|
|
@@ -698,6 +740,47 @@ class TestGraphicsContext < Test::Unit::TestCase
|
|
|
698
740
|
assert_p5_fill_stroke src, 'endShape CLOSE'
|
|
699
741
|
end
|
|
700
742
|
|
|
743
|
+
def test_image_with_alpha()
|
|
744
|
+
header = <<~END
|
|
745
|
+
noStroke
|
|
746
|
+
background 0, 255, 0
|
|
747
|
+
unless @img
|
|
748
|
+
@img = createGraphics 400, 400
|
|
749
|
+
@img.beginDraw
|
|
750
|
+
@img.noStroke
|
|
751
|
+
@img.fill 255, 255, 255, 128
|
|
752
|
+
@img.rect 0, 0, 400, 400
|
|
753
|
+
@img.endDraw
|
|
754
|
+
end
|
|
755
|
+
END
|
|
756
|
+
assert_p5_draw header, 'image @img, 100, 100'
|
|
757
|
+
end
|
|
758
|
+
|
|
759
|
+
def test_image_with_filter()
|
|
760
|
+
header = -> filter {<<~END}
|
|
761
|
+
noStroke
|
|
762
|
+
background 0, 255, 0
|
|
763
|
+
unless @img
|
|
764
|
+
@img = createGraphics 400, 400
|
|
765
|
+
@img.beginDraw
|
|
766
|
+
@img.noStroke
|
|
767
|
+
@img.fill 200, 100, 50, 128
|
|
768
|
+
@img.rect 0, 0, 400, 400
|
|
769
|
+
@img.endDraw
|
|
770
|
+
@img.filter #{filter}
|
|
771
|
+
end
|
|
772
|
+
END
|
|
773
|
+
footer = <<~END
|
|
774
|
+
image @img, 100, 100
|
|
775
|
+
END
|
|
776
|
+
# GRAY weighs rgb as Processing does (0.3, 0.59, 0.11) while p5 uses the
|
|
777
|
+
# CIE luminance (0.2126, 0.7152, 0.0722), which puts the two a few steps
|
|
778
|
+
# apart
|
|
779
|
+
assert_p5_draw header['GRAY'], footer, threshold: THRESHOLD_TO_BE_FIXED
|
|
780
|
+
assert_p5_draw header['INVERT'], footer
|
|
781
|
+
assert_p5_draw header['THRESHOLD'], footer
|
|
782
|
+
end
|
|
783
|
+
|
|
701
784
|
def test_pixels()
|
|
702
785
|
g = graphics 2, 2
|
|
703
786
|
|
|
@@ -719,6 +802,22 @@ class TestGraphicsContext < Test::Unit::TestCase
|
|
|
719
802
|
assert_raise(ArgumentError) {g.updatePixels}
|
|
720
803
|
end
|
|
721
804
|
|
|
805
|
+
def test_pixels_with_alpha()
|
|
806
|
+
g = graphics 2, 2 do |g|
|
|
807
|
+
g.noStroke
|
|
808
|
+
g.fill 255, 255, 255, 128
|
|
809
|
+
g.rect 0, 0, 1, 1
|
|
810
|
+
end
|
|
811
|
+
|
|
812
|
+
g.loadPixels
|
|
813
|
+
assert_equal [0x80ffffff, 0, 0, 0], g.pixels
|
|
814
|
+
|
|
815
|
+
g.pixels.replace [0x80ffffff, 0x40ff0000, 0, 0]
|
|
816
|
+
g.updatePixels
|
|
817
|
+
g.loadPixels
|
|
818
|
+
assert_equal [0x80ffffff, 0x40ff0000, 0, 0], g.pixels
|
|
819
|
+
end
|
|
820
|
+
|
|
722
821
|
def test_pixels_and_modified_flags()
|
|
723
822
|
drawRect = -> g, x, *rgb do
|
|
724
823
|
g.beginDraw do
|
data/test/test_image.rb
CHANGED
|
@@ -37,6 +37,13 @@ class TestImage < Test::Unit::TestCase
|
|
|
37
37
|
assert_equal g.color(0, 0, 255), i.get(0, 1)
|
|
38
38
|
end
|
|
39
39
|
|
|
40
|
+
def test_get_color_with_alpha()
|
|
41
|
+
g = graphics
|
|
42
|
+
i = image(2, 2) {fill 1, 0, 0, 0.5; rect 0, 0, 1, 1}
|
|
43
|
+
|
|
44
|
+
assert_equal g.color(255, 0, 0, 128), i.get(0, 0)
|
|
45
|
+
end
|
|
46
|
+
|
|
40
47
|
def test_pixels()
|
|
41
48
|
i = image 2, 2
|
|
42
49
|
|
|
@@ -58,6 +65,18 @@ class TestImage < Test::Unit::TestCase
|
|
|
58
65
|
assert_raise(ArgumentError) {i.updatePixels}
|
|
59
66
|
end
|
|
60
67
|
|
|
68
|
+
def test_pixels_with_alpha()
|
|
69
|
+
i = image(2, 2) {fill 1, 1, 1, 0.5; rect 0, 0, 1, 1}
|
|
70
|
+
|
|
71
|
+
i.loadPixels
|
|
72
|
+
assert_equal [0x80ffffff, 0, 0, 0], i.pixels
|
|
73
|
+
|
|
74
|
+
i.pixels.replace [0x80ffffff, 0x40ff0000, 0, 0]
|
|
75
|
+
i.updatePixels
|
|
76
|
+
i.loadPixels
|
|
77
|
+
assert_equal [0x80ffffff, 0x40ff0000, 0, 0], i.pixels
|
|
78
|
+
end
|
|
79
|
+
|
|
61
80
|
def test_inspect()
|
|
62
81
|
assert_match %r|#<Processing::Image:0x\w{16}>|, image.inspect
|
|
63
82
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: processing
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- xordog
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-11-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rexml
|
|
@@ -30,56 +30,56 @@ dependencies:
|
|
|
30
30
|
requirements:
|
|
31
31
|
- - "~>"
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: 0.
|
|
33
|
+
version: 0.5.0
|
|
34
34
|
type: :runtime
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
38
|
- - "~>"
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: 0.
|
|
40
|
+
version: 0.5.0
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
42
|
name: rucy
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
|
44
44
|
requirements:
|
|
45
45
|
- - "~>"
|
|
46
46
|
- !ruby/object:Gem::Version
|
|
47
|
-
version: 0.
|
|
47
|
+
version: 0.5.0
|
|
48
48
|
type: :runtime
|
|
49
49
|
prerelease: false
|
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
51
|
requirements:
|
|
52
52
|
- - "~>"
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
|
-
version: 0.
|
|
54
|
+
version: 0.5.0
|
|
55
55
|
- !ruby/object:Gem::Dependency
|
|
56
56
|
name: rays
|
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
|
58
58
|
requirements:
|
|
59
59
|
- - "~>"
|
|
60
60
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: 0.
|
|
61
|
+
version: 0.5.0
|
|
62
62
|
type: :runtime
|
|
63
63
|
prerelease: false
|
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
65
|
requirements:
|
|
66
66
|
- - "~>"
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
|
-
version: 0.
|
|
68
|
+
version: 0.5.0
|
|
69
69
|
- !ruby/object:Gem::Dependency
|
|
70
70
|
name: reflexion
|
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
|
72
72
|
requirements:
|
|
73
73
|
- - "~>"
|
|
74
74
|
- !ruby/object:Gem::Version
|
|
75
|
-
version: 0.
|
|
75
|
+
version: 0.7.0
|
|
76
76
|
type: :runtime
|
|
77
77
|
prerelease: false
|
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
|
79
79
|
requirements:
|
|
80
80
|
- - "~>"
|
|
81
81
|
- !ruby/object:Gem::Version
|
|
82
|
-
version: 0.
|
|
82
|
+
version: 0.7.0
|
|
83
83
|
description: Creative Coding Framework has API compatible to Processing or p5.js.
|
|
84
84
|
email: xordog@gmail.com
|
|
85
85
|
executables: []
|
|
@@ -91,7 +91,6 @@ files:
|
|
|
91
91
|
- ".github/workflows/tag.yml"
|
|
92
92
|
- ".github/workflows/test-draw.yml"
|
|
93
93
|
- ".github/workflows/test.yml"
|
|
94
|
-
- ".github/workflows/utils.rb"
|
|
95
94
|
- ".gitignore"
|
|
96
95
|
- ".yardopts"
|
|
97
96
|
- CLAUDE.md
|
|
@@ -164,7 +163,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
164
163
|
- !ruby/object:Gem::Version
|
|
165
164
|
version: '0'
|
|
166
165
|
requirements: []
|
|
167
|
-
rubygems_version: 3.
|
|
166
|
+
rubygems_version: 3.5.22
|
|
168
167
|
signing_key:
|
|
169
168
|
specification_version: 4
|
|
170
169
|
summary: Processing compatible Creative Coding Framework.
|
data/.github/workflows/utils.rb
DELETED
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
require 'shellwords'
|
|
2
|
-
|
|
3
|
-
ALL_REPO = 'xord/all'
|
|
4
|
-
ALL_DIR = '../all'
|
|
5
|
-
ALL_FETCH_DEPTH = 100
|
|
6
|
-
|
|
7
|
-
RENAMES = {reflex: 'reflexion'}
|
|
8
|
-
|
|
9
|
-
def sh(cmd)
|
|
10
|
-
puts cmd
|
|
11
|
-
system cmd
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def setup_dependencies(only: nil)
|
|
15
|
-
gemspec_path = `git ls-files`.lines(chomp: true).find {|l| l =~ /\.gemspec$/}
|
|
16
|
-
return unless gemspec_path
|
|
17
|
-
|
|
18
|
-
gemspec = File.read gemspec_path
|
|
19
|
-
name = File.basename gemspec_path, '.gemspec'
|
|
20
|
-
|
|
21
|
-
exts = File.readlines('Rakefile')
|
|
22
|
-
.map {|l| l[%r|^\s*require\W+([\w\-\_]+)/extension\W+$|, 1]}
|
|
23
|
-
.compact
|
|
24
|
-
.reject {|ext| ext == name}
|
|
25
|
-
exts = exts & [only].flatten.map(&:to_s) if only
|
|
26
|
-
return if exts.empty?
|
|
27
|
-
|
|
28
|
-
unless setup_dependencies_via_monorepo(exts)
|
|
29
|
-
setup_dependencies_via_each_repo_by_version(gemspec, exts)
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
exts.each {|ext| sh %( cd ../#{ext} && rake ext )}
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def setup_dependencies_via_monorepo(exts)
|
|
36
|
-
return false unless checkout_monorepo
|
|
37
|
-
exts.each {|ext| sh %( ln -snf all/#{ext} ../#{ext} )}
|
|
38
|
-
true
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def checkout_monorepo()
|
|
42
|
-
uuid = `git log -1 --format=%B`[/^\[\[([0-9a-fA-F-]+)\]\]$/, 1]
|
|
43
|
-
return false unless uuid
|
|
44
|
-
|
|
45
|
-
commit = setup_monorepo uuid
|
|
46
|
-
return false unless commit
|
|
47
|
-
|
|
48
|
-
Dir.chdir(ALL_DIR) {sh %( git checkout -q #{commit} )}
|
|
49
|
-
true
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def setup_monorepo(uuid)
|
|
53
|
-
unless File.directory? ALL_DIR
|
|
54
|
-
url = "https://github.com/#{ALL_REPO}.git"
|
|
55
|
-
sh %( git clone --no-tags --depth #{ALL_FETCH_DEPTH} #{url} #{ALL_DIR} )
|
|
56
|
-
end
|
|
57
|
-
loop do
|
|
58
|
-
commit = find_monorepo_commit uuid
|
|
59
|
-
return commit if commit
|
|
60
|
-
|
|
61
|
-
deepened = Dir.chdir ALL_DIR do
|
|
62
|
-
before = `git rev-list --count HEAD`.to_i
|
|
63
|
-
sh %( git fetch --deepen #{ALL_FETCH_DEPTH} )
|
|
64
|
-
`git rev-list --count HEAD`.to_i > before
|
|
65
|
-
end
|
|
66
|
-
return nil unless deepened
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
def find_monorepo_commit(uuid)
|
|
71
|
-
Dir.chdir ALL_DIR do
|
|
72
|
-
out = `git log origin/HEAD -F --grep="[[#{uuid}]]" --format=%H -1`.strip
|
|
73
|
-
out.empty? ? nil : out
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
def setup_dependencies_via_each_repo_by_version(gemspec, exts)
|
|
78
|
-
exts.each do |ext|
|
|
79
|
-
gem = RENAMES[ext.to_sym].then {|s| s || ext}
|
|
80
|
-
ver = gemspec[/add_dependency.*['"]#{gem}['"].*['"]\s*~>\s*([\d\.]+)\s*['"]/, 1]
|
|
81
|
-
opts = '-c advice.detachedHead=false --depth 1'
|
|
82
|
-
clone = "git clone #{opts} https://github.com/xord/#{ext}.git ../#{ext}"
|
|
83
|
-
|
|
84
|
-
# 'rake subtree:push' pushes all subrepos, so cloning by new tag
|
|
85
|
-
# often fails before tagging each new tag
|
|
86
|
-
sh %( #{clone} --branch v#{ver} || #{clone} )
|
|
87
|
-
end
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
def tag_versions()
|
|
91
|
-
changes = changelogs
|
|
92
|
-
tags = `git tag`.lines chomp: true
|
|
93
|
-
vers = `git log --oneline ./VERSION`
|
|
94
|
-
.lines(chomp: true)
|
|
95
|
-
.map {|line| line.split.first[/^\w+$/]}
|
|
96
|
-
.map {|sha| [`git cat-file -p #{sha}:./VERSION 2>/dev/null`[/[\d\.]+/], sha]}
|
|
97
|
-
.select {|ver, sha| ver && sha}
|
|
98
|
-
.reverse
|
|
99
|
-
.to_h
|
|
100
|
-
|
|
101
|
-
vers.to_a.reverse.each do |ver, sha|
|
|
102
|
-
tag = "v#{ver}"
|
|
103
|
-
break if tags.include?(tag)
|
|
104
|
-
sh %( git tag -a -m \"#{changes[tag]&.gsub '"', '\\"'}\" #{tag} #{sha} )
|
|
105
|
-
end
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
def release(*paths)
|
|
109
|
-
tag = ENV['GITHUB_REF']&.sub(%r|^refs/tags/|, '') || raise('GITHUB_REF tag not set')
|
|
110
|
-
notes = (changelogs[tag] || '').shellescape
|
|
111
|
-
paths = paths.flatten.join ' '
|
|
112
|
-
|
|
113
|
-
sh(%( gh release create #{tag} #{paths} --notes #{notes} )) ||
|
|
114
|
-
sh(%( gh release upload #{tag} #{paths} --clobber )) ||
|
|
115
|
-
raise('failed to upload to releases')
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
def changelogs()
|
|
119
|
-
File.read('ChangeLog.md')
|
|
120
|
-
.split(/^\s*##\s*\[\s*(v[\d\.]+)\s*\].*$/)
|
|
121
|
-
.slice(1..)
|
|
122
|
-
.each_slice(2)
|
|
123
|
-
.to_h
|
|
124
|
-
.transform_values(&:strip!)
|
|
125
|
-
rescue Errno::ENOENT
|
|
126
|
-
raise 'failed to get changelogs'
|
|
127
|
-
end
|