App-Netdisco
view release on metacpan or search on metacpan
lib/App/Netdisco/Util/SiteLocal.pm view on Meta::CPAN
package App::Netdisco::Util::SiteLocal;
use strict;
use warnings;
use File::Find ();
use Dancer ':syntax';
use Path::Class qw/dir file/;
use base 'Exporter';
our @EXPORT = ();
our @EXPORT_OK = qw/ scan_site_local scan_shadowed_files
site_local_rules site_local_paths /;
our %EXPORT_TAGS = (all => \@EXPORT_OK);
=head1 NAME
App::Netdisco::Util::SiteLocal - find site-local files broken by shipped changes
=head1 DESCRIPTION
Site-local templates override shipped ones by relative path, so they keep
calling APIs that later releases removed. Most of the removals below fail
silently in the browser, which is why this exists: nothing else reports them.
Detection only. This module never writes to a file and never logs.
=cut
# One row per shipped removal. A later rung adds a row here and nothing else.
#
# `pattern` is matched against each line of each file under the scanned paths.
# `release` is the release that removed or deprecated the thing, for the report
# to cite.
my @RULES = (
{
name => 'he-js',
release => '2.105002',
pattern => qr/\bhe\s*\.\s*(?:encode|decode)\s*\(/,
advice => 'he.js was removed. Use DataTable.util.escapeHtml(), which is '
. 'loaded on every page already.',
},
{
name => 'history-js',
release => '2.105004',
# History with a capital H is history.js. The browser's own object is
# lowercase, so the case distinction is the whole test. window.History
# still exists after the removal, as the DOM interface constructor, so a
# site's `window.History && ...` guard stops running its branch and never
# throws. That silence is why this rule matters more than it looks.
pattern => qr/\bHistory\s*\.\s*(?:pushState|replaceState|getState|Adapter|enabled|log)\b/,
advice => 'history.js was removed, and the browser no longer drives '
. 'the address bar at all. Let the pane response say where it '
. 'went, with an HX-Push-Url or HX-Replace-Url header, and drop '
. 'the history call and any popstate listener beside it.',
},
{
name => 'natural-js',
release => '2.105004',
# Both the registered sort-type names and the two ways a DataTables column
# asks for one. A column asking for a type nothing registers falls back to
# string sorting, so the rows are quietly in the wrong order.
#
# The key's own quotes are optional because both spellings are common: a
# JSON-shaped config writes "sType", a JavaScript object literal writes
# sType bare, and a pattern requiring one silently misses the other.
pattern => qr/natural-(?:asc|desc)\b|["']?(?:type|sType)["']?\s*:\s*["']natural["']/,
advice => 'natural.js was removed. Use a built-in DataTables type, or '
. 'the portsort or versionsort plug-ins netdisco still ships.',
},
{
name => 'do-search',
release => '2.105006',
# The only rule here whose subject still works: do_search forwards to htmx
# rather than throwing, so a site that ignores this keeps loading its tab.
# Reported anyway, because the console notice only reaches whoever opens
# devtools.
pattern => qr/\bdo_search\s*\(/,
advice => 'do_search() now only forwards to htmx and will be removed in a '
. 'future release. Give the form the hx-get, hx-target, hx-headers, '
. 'hx-indicator and hx-sync attributes that share/views/device.tt '
. 'uses, '
. 'then drop the do_search call from the submit handler.',
},
{
name => 'datatabledefaults-include',
release => '2.109000',
pattern => qr/INCLUDE\s+['"]ajax\/datatabledefaults\.tt['"]/,
advice => 'ajax/datatabledefaults.tt was removed. Delete the INCLUDE and '
. 'move the table options into the data-nd-table attribute, as '
. 'share/views/ajax/device/ports.tt now does.',
},
{
name => 'has-sidebar-global',
release => '2.109000',
pattern => qr/has_sidebar\s*\[/,
advice => 'the has_sidebar global was removed. The sidebar visibility '
. 'marker is now a hidden input carrying data-nd-has-sidebar '
. 'for the tab and a 0 or 1 value, as '
. 'share/views/sidebar/report/portlog.tt shows.',
( run in 1.583 second using v1.01-cache-2.11-cpan-54e63673c56 )