trmnl_preview 0.19.0 → 0.21.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/CHANGELOG.md +32 -0
- data/README.md +39 -36
- data/db/data/form_fields.yml +1 -0
- data/db/data/framework_versions.yml +9 -1
- data/lib/trmnlp/cli.rb +22 -0
- data/lib/trmnlp/commands/lint.rb +12 -1
- data/lib/trmnlp/config/project.rb +2 -0
- data/lib/trmnlp/context.rb +4 -2
- data/lib/trmnlp/firefox_driver.rb +3 -0
- data/lib/trmnlp/lint/checks/no_unknown_filters.rb +46 -0
- data/lib/trmnlp/lint/diagnostic.rb +3 -5
- data/lib/trmnlp/lint.rb +5 -1
- data/lib/trmnlp/paths.rb +3 -0
- data/lib/trmnlp/qr_code.rb +26 -0
- data/lib/trmnlp/screen_generator.rb +5 -3
- data/lib/trmnlp/screenshot.rb +45 -17
- data/lib/trmnlp/testing/browser.rb +23 -18
- data/lib/trmnlp/testing/page_server.rb +57 -0
- data/lib/trmnlp/testing/plugin.rb +22 -6
- data/lib/trmnlp/testing/publishable_recipe.rb +4 -3
- data/lib/trmnlp/testing/qr_scanner.rb +55 -0
- data/lib/trmnlp/testing/report.rb +1 -1
- data/lib/trmnlp/testing/rspec.rb +26 -4
- data/lib/trmnlp/testing/run.rb +1 -1
- data/lib/trmnlp/testing/screen.rb +76 -8
- data/lib/trmnlp/update_check.rb +94 -0
- data/lib/trmnlp/user_data_assembler.rb +6 -2
- data/lib/trmnlp/version.rb +1 -1
- data/lib/trmnlp.rb +1 -1
- data/templates/init/bin/trmnlp +70 -21
- data/templates/init/tests/plugin_spec.rb +1 -1
- metadata +6 -3
- data/lib/trmnlp/qr_code_intrinsic_size.rb +0 -22
- data/lib/trmnlp/testing/inline_stylesheets.rb +0 -44
data/templates/init/bin/trmnlp
CHANGED
|
@@ -4,10 +4,23 @@
|
|
|
4
4
|
# Use this opportunity to set up environment variables, install dependencies, etc.
|
|
5
5
|
#
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
# Saved on the PATH as `trmnlp`, this script is what `command -v trmnlp` finds: not a gem.
|
|
8
|
+
GEM="$(command -v trmnlp)"
|
|
9
|
+
if [ -n "$GEM" ] && ! [ "$GEM" -ef "$0" ]
|
|
8
10
|
then
|
|
9
|
-
|
|
10
|
-
|
|
11
|
+
exec "$GEM" "$@"
|
|
12
|
+
fi
|
|
13
|
+
|
|
14
|
+
if ! command -v docker &> /dev/null
|
|
15
|
+
then
|
|
16
|
+
echo "Install the trmnl_preview gem:
|
|
17
|
+
|
|
18
|
+
gem install trmnl_preview
|
|
19
|
+
|
|
20
|
+
Or install Docker:
|
|
21
|
+
|
|
22
|
+
https://docs.docker.com/get-docker/"
|
|
23
|
+
exit 1
|
|
11
24
|
fi
|
|
12
25
|
|
|
13
26
|
# Determine XDG config directory on host OS
|
|
@@ -17,28 +30,64 @@ else
|
|
|
17
30
|
CONFIG_DIR="$HOME/.config/trmnlp"
|
|
18
31
|
fi
|
|
19
32
|
|
|
20
|
-
|
|
21
|
-
|
|
33
|
+
# What trmnlp caches is kept as well: a plugin's OAuth tokens, its saved data and transform state.
|
|
34
|
+
CACHE_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/trmnl"
|
|
35
|
+
|
|
36
|
+
mkdir -p "$CONFIG_DIR" "$CACHE_DIR"
|
|
37
|
+
|
|
38
|
+
# Add a tag to stay on one release: trmnl/trmnlp:v0.20.0
|
|
39
|
+
IMAGE=trmnl/trmnlp
|
|
40
|
+
|
|
41
|
+
# A newer release is pulled once a day. With no network, the image already here runs.
|
|
42
|
+
PULLED_AT="$CACHE_DIR/image_pulled"
|
|
43
|
+
if [ -z "$(find "$PULLED_AT" -mtime -1 2> /dev/null)" ]; then
|
|
44
|
+
docker pull --quiet "$IMAGE" > /dev/null 2>&1
|
|
45
|
+
touch "$PULLED_AT"
|
|
22
46
|
fi
|
|
23
47
|
|
|
24
|
-
|
|
48
|
+
# On Linux the container's root is the host's root, and the files trmnlp writes (snapshots, _build,
|
|
49
|
+
# a pulled plugin) would be root's. So trmnlp runs as you, with a home of its own to write in.
|
|
50
|
+
# Docker Desktop and rootless Docker hand the files to you already.
|
|
51
|
+
CONTAINER_HOME=/root
|
|
52
|
+
SECURITY="$(docker info --format '{{.SecurityOptions}}' 2> /dev/null)"
|
|
53
|
+
if [ "$(uname)" = Linux ] && [ "$(id -u)" != 0 ] && [ -n "$SECURITY" ] && [[ "$SECURITY" != *rootless* ]]
|
|
25
54
|
then
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
--
|
|
31
|
-
--
|
|
32
|
-
|
|
33
|
-
|
|
55
|
+
CONTAINER_HOME=/tmp/home
|
|
56
|
+
# .config and .cache are made for you as well: Docker would make them root's to mount the
|
|
57
|
+
# folders below into them, and Firefox hangs when it cannot write there.
|
|
58
|
+
ARGS=(
|
|
59
|
+
--user "$(id -u):$(id -g)"
|
|
60
|
+
--env HOME=/tmp/home
|
|
61
|
+
--tmpfs "/tmp/home:exec,uid=$(id -u),gid=$(id -g)"
|
|
62
|
+
--tmpfs "/tmp/home/.config:uid=$(id -u),gid=$(id -g)"
|
|
63
|
+
--tmpfs "/tmp/home/.cache:exec,uid=$(id -u),gid=$(id -g)"
|
|
64
|
+
)
|
|
34
65
|
fi
|
|
35
66
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
Or install Docker:
|
|
67
|
+
# A terminal only when there is one: CI and scripts have none.
|
|
68
|
+
if [ -t 0 ] && [ -t 1 ]; then
|
|
69
|
+
ARGS+=(--tty)
|
|
70
|
+
fi
|
|
41
71
|
|
|
42
|
-
|
|
72
|
+
# Only serve listens, so every other command can run next to it.
|
|
73
|
+
if [ "$1" = serve ]; then
|
|
74
|
+
PORT=4567
|
|
75
|
+
for ARG in "$@"; do
|
|
76
|
+
case "$PREVIOUS" in -p | --port) PORT="$ARG" ;; esac
|
|
77
|
+
case "$ARG" in --port=*) PORT="${ARG#--port=}" ;; esac
|
|
78
|
+
PREVIOUS="$ARG"
|
|
79
|
+
done
|
|
80
|
+
ARGS+=(--publish "$PORT:$PORT")
|
|
81
|
+
fi
|
|
43
82
|
|
|
44
|
-
|
|
83
|
+
exec docker run \
|
|
84
|
+
--rm \
|
|
85
|
+
--init \
|
|
86
|
+
--interactive \
|
|
87
|
+
"${ARGS[@]}" \
|
|
88
|
+
--env CI \
|
|
89
|
+
--env TRMNL_API_KEY \
|
|
90
|
+
--volume "$CONFIG_DIR:$CONTAINER_HOME/.config/trmnlp" \
|
|
91
|
+
--volume "$CACHE_DIR:$CONTAINER_HOME/.cache/trmnl" \
|
|
92
|
+
--volume "$(pwd):/plugin" \
|
|
93
|
+
"$IMAGE" "$@"
|
|
@@ -10,7 +10,7 @@ RSpec.describe 'My Plugin' do
|
|
|
10
10
|
# The values of the custom fields in src/settings.yml to test with.
|
|
11
11
|
let(:custom_fields) { {} }
|
|
12
12
|
|
|
13
|
-
# Every view on TRMNL's devices, a failing API and every select option, checked for
|
|
13
|
+
# Every view on TRMNL's devices, a failing API and every select option, checked for page errors and leaked values.
|
|
14
14
|
it_behaves_like 'a publishable recipe'
|
|
15
15
|
|
|
16
16
|
# A picture of the full view, compared pixel for pixel on every run. Record it once with
|
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.
|
|
4
|
+
version: 0.21.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Rockwell Schrock
|
|
@@ -433,6 +433,7 @@ files:
|
|
|
433
433
|
- lib/trmnlp/lint/checks/no_custom_filters.rb
|
|
434
434
|
- lib/trmnlp/lint/checks/no_opacity.rb
|
|
435
435
|
- lib/trmnlp/lint/checks/no_size_classes.rb
|
|
436
|
+
- lib/trmnlp/lint/checks/no_unknown_filters.rb
|
|
436
437
|
- lib/trmnlp/lint/checks/recipe_overview_length.rb
|
|
437
438
|
- lib/trmnlp/lint/checks/title_casing.rb
|
|
438
439
|
- lib/trmnlp/lint/checks/title_length.rb
|
|
@@ -450,7 +451,7 @@ files:
|
|
|
450
451
|
- lib/trmnlp/outbound_request.rb
|
|
451
452
|
- lib/trmnlp/paths.rb
|
|
452
453
|
- lib/trmnlp/poller.rb
|
|
453
|
-
- lib/trmnlp/
|
|
454
|
+
- lib/trmnlp/qr_code.rb
|
|
454
455
|
- lib/trmnlp/rails_helpers.rb
|
|
455
456
|
- lib/trmnlp/renderer.rb
|
|
456
457
|
- lib/trmnlp/reporter.rb
|
|
@@ -462,13 +463,14 @@ files:
|
|
|
462
463
|
- lib/trmnlp/testing/certificate_authority.rb
|
|
463
464
|
- lib/trmnlp/testing/device_models.rb
|
|
464
465
|
- lib/trmnlp/testing/frozen_clock.rb
|
|
465
|
-
- lib/trmnlp/testing/inline_stylesheets.rb
|
|
466
466
|
- lib/trmnlp/testing/memory_sampler.rb
|
|
467
467
|
- lib/trmnlp/testing/mock_proxy.rb
|
|
468
468
|
- lib/trmnlp/testing/mock_table.rb
|
|
469
469
|
- lib/trmnlp/testing/node_version.rb
|
|
470
|
+
- lib/trmnlp/testing/page_server.rb
|
|
470
471
|
- lib/trmnlp/testing/plugin.rb
|
|
471
472
|
- lib/trmnlp/testing/publishable_recipe.rb
|
|
473
|
+
- lib/trmnlp/testing/qr_scanner.rb
|
|
472
474
|
- lib/trmnlp/testing/report.html.erb
|
|
473
475
|
- lib/trmnlp/testing/report.rb
|
|
474
476
|
- lib/trmnlp/testing/rspec.rb
|
|
@@ -482,6 +484,7 @@ files:
|
|
|
482
484
|
- lib/trmnlp/transform_client.rb
|
|
483
485
|
- lib/trmnlp/transform_pipeline.rb
|
|
484
486
|
- lib/trmnlp/transform_state.rb
|
|
487
|
+
- lib/trmnlp/update_check.rb
|
|
485
488
|
- lib/trmnlp/user_data_assembler.rb
|
|
486
489
|
- lib/trmnlp/version.rb
|
|
487
490
|
- lib/trmnlp/watcher.rb
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'trmnl/liquid'
|
|
4
|
-
|
|
5
|
-
module TRMNLP
|
|
6
|
-
# Mirrors core's config/initializers/trmnl_liquid_qr_code_intrinsic_size.rb: a view box alone
|
|
7
|
-
# gives the code no size of its own, so it renders at zero width in a shrink-to-fit container.
|
|
8
|
-
module QrCodeIntrinsicSize
|
|
9
|
-
def qr_code(data, size = 11, level = '', view = 'responsive')
|
|
10
|
-
svg = super
|
|
11
|
-
root_element = svg[/<svg[^>]*>/].to_s
|
|
12
|
-
return svg if root_element.include?('width=')
|
|
13
|
-
|
|
14
|
-
side_length = root_element[/viewBox="0 0 (\d+)/, 1]
|
|
15
|
-
return svg unless side_length
|
|
16
|
-
|
|
17
|
-
svg.sub('<svg ', %(<svg width="#{side_length}" height="#{side_length}" style="max-width:100%;height:auto" ))
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
TRMNL::Liquid::Filters.prepend(TRMNLP::QrCodeIntrinsicSize)
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'faraday'
|
|
4
|
-
require 'uri'
|
|
5
|
-
|
|
6
|
-
module TRMNLP
|
|
7
|
-
module Testing
|
|
8
|
-
# Puts a page's linked stylesheets in the page itself. A page written with document.write, as TRMNL and
|
|
9
|
-
# trmnlp write theirs, runs its scripts without waiting for linked stylesheets, so a script that
|
|
10
|
-
# measures text (a layout solver, say) raced them and drew a different board from run to run.
|
|
11
|
-
module InlineStylesheets
|
|
12
|
-
LINK = /<link\b[^>]*\brel=["']stylesheet["'][^>]*>/i
|
|
13
|
-
SCRIPT = %r{<script\b.*?</script>}im
|
|
14
|
-
HREF = /\bhref=["'](https?:[^"']+)["']/i
|
|
15
|
-
CSS_URL = /url\(\s*(['"]?)(?!data:|https?:|#)([^'")]+)\1\s*\)/i
|
|
16
|
-
|
|
17
|
-
module_function
|
|
18
|
-
|
|
19
|
-
def call(html)
|
|
20
|
-
html.gsub(Regexp.union(SCRIPT, LINK)) do |tag|
|
|
21
|
-
next tag if tag.match?(/\A<script/i)
|
|
22
|
-
|
|
23
|
-
url = tag[HREF, 1]
|
|
24
|
-
css = url && stylesheet(url)
|
|
25
|
-
css ? "<style data-href=\"#{url}\">#{css}</style>" : tag
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
# nil when the stylesheet cannot be fetched: the page keeps its link.
|
|
30
|
-
def stylesheet(url)
|
|
31
|
-
cache.fetch(url) do
|
|
32
|
-
response = Faraday.get(url)
|
|
33
|
-
cache[url] = response.success? ? absolute_urls(response.body, url) : nil
|
|
34
|
-
end
|
|
35
|
-
rescue Faraday::Error
|
|
36
|
-
nil
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def absolute_urls(css, base) = css.gsub(CSS_URL) { "url(\"#{URI.join(base, Regexp.last_match(2))}\")" }
|
|
40
|
-
|
|
41
|
-
def cache = @cache ||= {}
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
end
|