trmnl_preview 0.31.0 → 0.31.1
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/CHANGELOG.md +8 -0
- data/db/data/framework_versions.yml +3 -1
- data/lib/trmnlp/renderer.rb +4 -3
- data/lib/trmnlp/testing/certificate_authority.rb +2 -0
- data/lib/trmnlp/transform_backend/python.rb +37 -0
- data/lib/trmnlp/transform_backend/subprocess.rb +4 -1
- data/lib/trmnlp/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b21d300476e67904c34d0187c12b11c59904e67429ead767147d24d50ca1db9d
|
|
4
|
+
data.tar.gz: 5e77e6666b47b187f558d04c158907cc0441e90899f7e444cea1cc136a49a6cd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: eedd5d2c1275ac5f7a8dbc4767472e0dc5e1ff456ea352e3bbb6373190c0f98b04d8fe56f14cddcc8a2982ec57dd1ec21037d5a0c3d37b856c98830db5f81826
|
|
7
|
+
data.tar.gz: 7e9e0209e2102edf63ccc05efe67ed69912b206cae2f4c8e33d8bc67b8f83349cc8b1f35e2694b3246e6179c487e15368746ebfa259495db9306361dca834559
|
data/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
|
|
2
2
|
# Changelog
|
|
3
3
|
|
|
4
|
+
## 0.31.1
|
|
5
|
+
|
|
6
|
+
- A view with no `.liquid` file draws the shared markup alone, as TRMNL does when a recipe keeps all of its markup in shared. Before, trmnlp drew "Missing template" there, so `trmnlp test` showed a blank screen for a recipe that draws on TRMNL. A view with no file and no shared markup still says "Missing template".
|
|
7
|
+
|
|
8
|
+
- `trmnlp test` mocks the HTTPS requests of a Python transform on Python 3.13 and newer, which the Docker image ships. Before, Python 3.13 refused the test proxy's certificate ("Missing Authority Key Identifier"), so every request failed and the screens showed the transform's error path.
|
|
9
|
+
|
|
10
|
+
- A Python transform can `import requests`, as on TRMNL, where it is installed. When the Python on your PATH does not have it, trmnlp makes a virtual environment with it in `~/.cache/trmnl/python` the first time and runs Python transforms there. Before, such a transform failed with `No module named 'requests'` and `trmnlp test` drew its error screen. The Docker image now has it installed.
|
|
11
|
+
|
|
4
12
|
## 0.31.0
|
|
5
13
|
|
|
6
14
|
- `trmnlp test`'s publishable recipe draws the full view with each boolean field on and off, as `"true"` and `"false"`, the strings TRMNL saves. Before, only select fields were drawn with each option, so a recipe that breaks or goes blank with a switch off passed.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Mirrored from the TRMNL design-system source.
|
|
2
2
|
# Refresh with `rake framework:sync` — do not edit manually.
|
|
3
|
-
latest: 3.4.
|
|
3
|
+
latest: 3.4.3
|
|
4
4
|
versions:
|
|
5
5
|
- number: 0.0.1
|
|
6
6
|
released_at: '2024-06-22'
|
|
@@ -98,3 +98,5 @@ versions:
|
|
|
98
98
|
released_at: '2026-10-14'
|
|
99
99
|
- number: 3.4.2
|
|
100
100
|
released_at: '2026-10-14'
|
|
101
|
+
- number: 3.4.3
|
|
102
|
+
released_at: '2026-10-15'
|
data/lib/trmnlp/renderer.rb
CHANGED
|
@@ -63,7 +63,9 @@ module TRMNLP
|
|
|
63
63
|
# of 500-ing. Anything that's not a RenderError bubbles up as a bug.
|
|
64
64
|
def render_liquid_template(view, device: {})
|
|
65
65
|
template_path = paths.template(view)
|
|
66
|
-
|
|
66
|
+
unless template_path.exist? || paths.shared_template.exist?
|
|
67
|
+
raise RenderError, "Missing template: #{template_path}"
|
|
68
|
+
end
|
|
67
69
|
|
|
68
70
|
parse_and_render(template_path, device:)
|
|
69
71
|
end
|
|
@@ -89,8 +91,7 @@ module TRMNLP
|
|
|
89
91
|
end
|
|
90
92
|
|
|
91
93
|
def full_markup(template_path)
|
|
92
|
-
|
|
93
|
-
shared.exist? ? shared.read + template_path.read : template_path.read
|
|
94
|
+
[paths.shared_template, template_path].select(&:exist?).map(&:read).join
|
|
94
95
|
end
|
|
95
96
|
|
|
96
97
|
def liquid_environment
|
|
@@ -57,6 +57,8 @@ module TRMNLP
|
|
|
57
57
|
|
|
58
58
|
def add_extensions(certificate, authority, host)
|
|
59
59
|
factory = OpenSSL::X509::ExtensionFactory.new(authority ? certificate : @certificate, certificate)
|
|
60
|
+
certificate.add_extension(factory.create_extension('subjectKeyIdentifier', 'hash'))
|
|
61
|
+
certificate.add_extension(factory.create_extension('authorityKeyIdentifier', 'keyid:always'))
|
|
60
62
|
if authority
|
|
61
63
|
certificate.add_extension(factory.create_extension('basicConstraints', 'CA:TRUE', true))
|
|
62
64
|
certificate.add_extension(factory.create_extension('keyUsage', 'keyCertSign,cRLSign', true))
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'xdg'
|
|
4
|
+
|
|
5
|
+
module TRMNLP
|
|
6
|
+
module TransformBackend
|
|
7
|
+
# TRMNL's serverless Python has requests installed. A Python without it runs transforms from a
|
|
8
|
+
# virtual environment in the cache that has it, made once; if that fails, the Python runs as it is.
|
|
9
|
+
module Python
|
|
10
|
+
module_function
|
|
11
|
+
|
|
12
|
+
def interpreter(python, venv_dir: XDG.new.cache_home.join('trmnl', 'python'))
|
|
13
|
+
resolved[python] ||= imports_requests?(python) ? python : venv_python(python, venv_dir)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def venv_python(python, venv_dir)
|
|
17
|
+
venv_dir.dirname.mkpath
|
|
18
|
+
venv = venv_dir.join(Gem.win_platform? ? 'Scripts/python.exe' : 'bin/python').to_s
|
|
19
|
+
created = File.open("#{venv_dir}.lock", File::RDWR | File::CREAT) do |lock|
|
|
20
|
+
lock.flock(File::LOCK_EX)
|
|
21
|
+
imports_requests?(venv) || created_venv?(python, venv_dir, venv)
|
|
22
|
+
end
|
|
23
|
+
created ? venv : python
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def created_venv?(python, venv_dir, venv)
|
|
27
|
+
succeeds?(python, '-m', 'venv', '--clear', venv_dir.to_s) && succeeds?(venv, '-m', 'pip', 'install', 'requests')
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def imports_requests?(python) = succeeds?(python, '-c', 'import requests')
|
|
31
|
+
|
|
32
|
+
def succeeds?(*command) = system(*command, out: File::NULL, err: File::NULL) == true
|
|
33
|
+
|
|
34
|
+
def resolved = @resolved ||= {}
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -4,6 +4,7 @@ require 'open3'
|
|
|
4
4
|
require 'tmpdir'
|
|
5
5
|
|
|
6
6
|
require_relative '../transform_client'
|
|
7
|
+
require_relative 'python'
|
|
7
8
|
require_relative 'which'
|
|
8
9
|
require_relative 'wrapper'
|
|
9
10
|
|
|
@@ -52,7 +53,9 @@ module TRMNLP
|
|
|
52
53
|
output_path = File.join(dir, 'output.json')
|
|
53
54
|
src_path = File.join(dir, "transform.#{spec[:ext]}")
|
|
54
55
|
File.write(src_path, Wrapper.for(language, code, sink_for(language, output_path)))
|
|
55
|
-
|
|
56
|
+
command = Which.resolve(spec[:cmds])
|
|
57
|
+
command = Python.interpreter(command) if language == 'python'
|
|
58
|
+
run_process(command, src_path, stdin, timeout_seconds, output_path)
|
|
56
59
|
end
|
|
57
60
|
rescue Errno::ENOENT, Errno::EACCES => e
|
|
58
61
|
failure("interpreter not available: #{e.message}")
|
data/lib/trmnlp/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: trmnl_preview
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.31.
|
|
4
|
+
version: 0.31.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Rockwell Schrock
|
|
@@ -500,6 +500,7 @@ files:
|
|
|
500
500
|
- lib/trmnlp/testing/snapshot.rb
|
|
501
501
|
- lib/trmnlp/testing/text_ink.rb
|
|
502
502
|
- lib/trmnlp/transform_backend/http.rb
|
|
503
|
+
- lib/trmnlp/transform_backend/python.rb
|
|
503
504
|
- lib/trmnlp/transform_backend/subprocess.rb
|
|
504
505
|
- lib/trmnlp/transform_backend/which.rb
|
|
505
506
|
- lib/trmnlp/transform_backend/wrapper.rb
|