2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-04-17 05:16:02 +00:00

98_Installer: add rudimentary visibility for nodejs and python dependencies

git-svn-id: https://svn.fhem.de/fhem/trunk@18892 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
jpawlowski 2019-03-14 00:45:06 +00:00
parent e2743cd3ce
commit dce3393bfc
3 changed files with 303 additions and 90 deletions

View File

@ -1778,6 +1778,18 @@ sub ToDay() {
}
}
},
"x_prereqs_nodejs": {
"runtime": {
"requires": {
"node": 8.0,
"npm": 0
},
"recommends": {
},
"suggests": {
}
}
},
"x_prereqs_binary_exec": {
"runtime": {
"requires": {

View File

@ -217,7 +217,8 @@ my @perlCoreModules = qw(
BEGIN {
# Import from main::
GP_Import(
qw(readingsSingleUpdate
qw(
readingsSingleUpdate
readingsBulkUpdate
readingsBulkUpdateIfChanged
readingsBeginUpdate
@ -239,10 +240,20 @@ BEGIN {
init_done
gettimeofday
InternalTimer
RemoveInternalTimer)
RemoveInternalTimer
LoadModule
)
);
}
# Load dependent FHEM modules as packages,
# no matter if user also defined FHEM devices or not.
# We want to use their functions here :-)
#TODO let this make Meta.pm for me
#LoadModule('apt');
#LoadModule('pypip');
LoadModule('npmjs');
sub Define($$) {
my ( $hash, $def ) = @_;
my @a = split( "[ \t][ \t]*", $def );
@ -1175,6 +1186,7 @@ sub CreateMetadataList ($$$) {
$l .= $colOpenMinWidth . $txtOpen . $mAttrName . $txtClose . $colClose;
# these attributes do not exist under that name in META.json
if ( !defined( $modMeta->{$mAttr} ) ) {
$l .= $colOpen;
@ -1381,14 +1393,25 @@ sub CreateMetadataList ($$$) {
: (
$modMeta->{resources}{bugtracker}{web} =~
m/^(?:https?:\/\/)?forum\.fhem\.de/i ? 'FHEM Forum'
: ''
: (
$modMeta->{resources}{bugtracker}{web} =~
m/^(?:https?:\/\/)?github\.com\/fhem/i
? 'Github Issues: ' . $modMeta->{name}
: $modMeta->{resources}{bugtracker}{web}
)
);
# add prefix if user defined title
$title = 'FHEM Forum: ' . $title
if ( $title ne ''
&& $title !~ m/^FHEM Forum/i
&& $modMeta->{resources}{bugtracker}{web} =~
m/^(?:https?:\/\/)?forum\.fhem\.de/i );
$title = 'Github Issues: ' . $title
if ( $title ne ''
&& $title !~ m/^Github issues/i
&& $modMeta->{resources}{bugtracker}{web} =~
m/^(?:https?:\/\/)?github\.com\/fhem/i );
$l .=
'<a href="'
@ -1525,6 +1548,8 @@ sub CreateMetadataList ($$$) {
$l .= $colClose;
}
# these text attributes can be shown directly
elsif ( !ref( $modMeta->{$mAttr} ) ) {
$l .= $colOpen;
@ -1579,6 +1604,8 @@ sub CreateMetadataList ($$$) {
$l .= $mAttrVal . $colClose;
}
# this attribute is an array and needs further processing
elsif (ref( $modMeta->{$mAttr} ) eq 'ARRAY'
&& @{ $modMeta->{$mAttr} } > 0
&& $modMeta->{$mAttr}[0] ne '' )
@ -1651,6 +1678,8 @@ m/^([^<>\n\r]+?)(?:\s+(\(last release only\)))?(?:\s+(?:<(.*)>))?$/
$l .= $colClose;
}
# woops, we don't know how to handle this attribute
else {
$l .= $colOpen . '?' . $colClose;
}
@ -1673,7 +1702,7 @@ m/^([^<>\n\r]+?)(?:\s+(\(last release only\)))?(?:\s+(?:<(.*)>))?$/
push @ret, 'This FHEM module is currently ' . $moduleUsage . '.'
unless ( $modName eq 'Global' );
push @ret, '<h4>Perl Modules</h4>';
push @ret, '<h4>Perl Packages</h4>';
if ( defined( $modMeta->{prereqs} )
&& defined( $modMeta->{prereqs}{runtime} ) )
{
@ -1816,6 +1845,232 @@ m/^([^<>\n\r]+?)(?:\s+(\(last release only\)))?(?:\s+(?:<(.*)>))?$/
. $lb;
}
if ( defined( $modMeta->{x_prereqs_nodejs} )
&& defined( $modMeta->{x_prereqs_nodejs}{runtime} ) )
{
push @ret, '<h4>Node.js Packages</h4>';
my @mAttrs = qw(
requires
recommends
suggests
);
push @ret, $tableOpen;
push @ret, $colOpenMinWidth . $txtOpen . 'Name' . $txtClose . $colClose;
push @ret,
$colOpenMinWidth . $txtOpen . 'Importance' . $txtClose . $colClose;
push @ret,
$colOpenMinWidth . $txtOpen . 'Status' . $txtClose . $colClose;
my $linecount = 1;
foreach my $mAttr (@mAttrs) {
next
unless ( defined( $modMeta->{x_prereqs_nodejs}{runtime}{$mAttr} )
&& keys %{ $modMeta->{x_prereqs_nodejs}{runtime}{$mAttr} } >
0 );
foreach my $prereq (
sort keys %{ $modMeta->{x_prereqs_nodejs}{runtime}{$mAttr} } )
{
my $l = $linecount % 2 == 0 ? $rowOpenEven : $rowOpenOdd;
my $importance = $mAttr;
$importance = 'required' if ( $mAttr eq 'requires' );
$importance = 'recommended' if ( $mAttr eq 'recommends' );
$importance = 'suggested' if ( $mAttr eq 'suggests' );
my $version =
$modMeta->{x_prereqs_nodejs}{runtime}{$mAttr}{$prereq};
$version = '' if ( !defined($version) || $version eq '0' );
my $check = __IsInstalledNodejs($prereq);
my $installed = '';
if ($check) {
if ( $check =~ m/^\d+\./ ) {
my $nverReq =
$version ne ''
? $version
: 0;
my $nverInst = $check;
#TODO suport for version range:
#https://metacpan.org/pod/CPAN::Meta::Spec#Version-Range
if ( $nverReq > 0 && $nverInst < $nverReq ) {
$installed .=
$colorRed
. 'OUTDATED'
. $colorClose . ' ('
. $check . ')';
}
else {
$installed = 'installed';
}
}
else {
$installed = 'installed';
}
}
else {
$installed = $colorRed . 'MISSING' . $colorClose
if ( $importance eq 'required' );
}
$installed = $colorGreen . $installed . $colorClose;
$prereq =
'<a href="https://www.npmjs.com/package/'
. $prereq
. '" target="_blank">'
. $prereq . '</a>'
if ($html);
$l .=
$colOpenMinWidth
. $prereq
. ( $version ne '' ? " ($version)" : '' )
. $colClose;
$l .= $colOpenMinWidth . $importance . $colClose;
$l .= $colOpenMinWidth . $installed . $colClose;
$l .= $rowClose;
push @ret, $l;
$linecount++;
}
}
push @ret, $tableClose;
}
if ( defined( $modMeta->{x_prereqs_python} )
&& defined( $modMeta->{x_prereqs_python}{runtime} ) )
{
push @ret, '<h4>Python Packages</h4>';
my @mAttrs = qw(
requires
recommends
suggests
);
push @ret, $tableOpen;
push @ret, $colOpenMinWidth . $txtOpen . 'Name' . $txtClose . $colClose;
push @ret,
$colOpenMinWidth . $txtOpen . 'Importance' . $txtClose . $colClose;
push @ret,
$colOpenMinWidth . $txtOpen . 'Status' . $txtClose . $colClose;
my $linecount = 1;
foreach my $mAttr (@mAttrs) {
next
unless ( defined( $modMeta->{x_prereqs_python}{runtime}{$mAttr} )
&& keys %{ $modMeta->{x_prereqs_python}{runtime}{$mAttr} } >
0 );
foreach my $prereq (
sort keys %{ $modMeta->{x_prereqs_python}{runtime}{$mAttr} } )
{
my $l = $linecount % 2 == 0 ? $rowOpenEven : $rowOpenOdd;
my $importance = $mAttr;
$importance = 'required' if ( $mAttr eq 'requires' );
$importance = 'recommended' if ( $mAttr eq 'recommends' );
$importance = 'suggested' if ( $mAttr eq 'suggests' );
my $version =
$modMeta->{x_prereqs_python}{runtime}{$mAttr}{$prereq};
$version = '' if ( !defined($version) || $version eq '0' );
my $check = __IsInstalledPython($prereq);
my $installed = '';
if ($check) {
if ( $check =~ m/^\d+\./ ) {
my $nverReq =
$version ne ''
? $version
: 0;
my $nverInst = $check;
#TODO suport for version range:
#https://metacpan.org/pod/CPAN::Meta::Spec#Version-Range
if ( $nverReq > 0 && $nverInst < $nverReq ) {
$installed .=
$colorRed
. 'OUTDATED'
. $colorClose . ' ('
. $check . ')';
}
else {
$installed = 'installed';
}
}
else {
$installed = 'installed';
}
}
else {
$installed = $colorRed . 'MISSING' . $colorClose
if ( $importance eq 'required' );
}
my $isPerlPragma = ModuleIsPerlPragma($prereq);
my $isPerlCore = $isPerlPragma ? 0 : ModuleIsPerlCore($prereq);
my $isFhem =
$isPerlPragma || $isPerlCore ? 0 : ModuleIsInternal($prereq);
if ( $isPerlPragma || $isPerlCore || $prereq eq 'perl' ) {
$installed =
$installed ne 'installed'
? "$installed (Perl built-in)"
: 'built-in';
}
elsif ($isFhem) {
$installed =
$installed ne 'installed'
? "$installed (FHEM included)"
: 'included';
}
elsif ( $installed eq 'installed' ) {
$installed = $colorGreen . $installed . $colorClose;
}
$prereq =
'<a href="https://metacpan.org/pod/'
. $prereq
. '" target="_blank">'
. $prereq . '</a>'
if ( $html
&& !$isFhem
&& !$isPerlCore
&& !$isPerlPragma
&& $prereq ne 'perl' );
$l .=
$colOpenMinWidth
. $prereq
. ( $version ne '' ? " ($version)" : '' )
. $colClose;
$l .= $colOpenMinWidth . $importance . $colClose;
$l .= $colOpenMinWidth . $installed . $colClose;
$l .= $rowClose;
push @ret, $l;
$linecount++;
}
}
push @ret, $tableClose;
}
push @ret, 'Based on data generated by ' . $modMeta->{generated_by};
return $header . join( "\n", @ret ) . $footer;
@ -1865,6 +2120,24 @@ sub __IsInstalledPerl($) {
}
}
# Checks whether a NodeJS package is installed in the system
sub __IsInstalledNodejs($) {
return 0 unless ( __PACKAGE__ eq caller(0) );
return 0 unless (@_);
my ($pkg) = @_;
return 0;
}
# Checks whether a Python package is installed in the system
sub __IsInstalledPython($) {
return 0 unless ( __PACKAGE__ eq caller(0) );
return 0 unless (@_);
my ($pkg) = @_;
return 0;
}
sub ModuleIsPerlCore {
my ($module) = @_;
return grep ( /^$module$/, @perlCoreModules )
@ -2050,7 +2323,8 @@ sub ToDay() {
"HttpUtils": 0,
"File::stat": 0,
"Encode": 0,
"version": 0
"version": 0,
"FHEM::npmjs": 0
},
"recommends": {
"Perl::PrereqScanner::NotQuiteLite": 0,
@ -2062,8 +2336,7 @@ sub ToDay() {
},
"resources": {
"bugtracker": {
"web": "https://forum.fhem.de/index.php/board,44.0.html",
"x_web_title": "FHEM Forum: Unterstützende Dienste"
"web": "https://github.com/fhem/Installer/issues"
}
}
}

View File

@ -362,7 +362,15 @@ sub import(@) {
__GetUpdatedata() unless ( defined($coreUpdate) );
__GetMaintainerdata() unless ( keys %moduleMaintainers > 0 );
if ( $pkg ne "main" ) {
#TODO Export a function to main context so that
# a device may use metadata to load Perl dependencies from META.json.
# This will provide a central place to maintain module dependencies
# w/o source code analysis.
if ( $pkg eq "main" ) {
}
# Not sure yet what else could be done by just loading the module
else {
}
}
@ -1721,26 +1729,6 @@ sub __SetXVersion {
}
}
},
"x_prereqs_nodejs": {
"runtime": {
"requires": {
},
"recommends": {
},
"suggests": {
}
}
},
"x_prereqs_python": {
"runtime": {
"requires": {
},
"recommends": {
},
"suggests": {
}
}
},
"x_prereqs_binary_exec": {
"runtime": {
"requires": {
@ -1793,11 +1781,11 @@ sub __SetXVersion {
=for :application/json;q=META.json fhem.pl
{
"abstract": "FHEM® is a Perl server for house automation",
"description": "FHEM® (registered trademark) is a GPL'd perl server for house automation. It is used to automate some common tasks in the household like switching lamps / shutters / heating / etc. and to log events like temperature / humidity / power consumption.\\n\\nThe program runs as a server, you can control it via web or smartphone frontends, telnet or TCP/IP directly.\\n\\nIn order to use FHEM you'll need a 24/7 server (NAS, RPi, PC, MacMini, etc) with a perl interpreter and some attached hardware like the CUL-, EnOcean-, Z-Wave-USB-Stick, etc. to access the actors and sensors.\\n\\nIt is pronounced without the h, like in feminine.",
"description": "FHEM® (registered trademark) is a GPL'd Perl server for house automation. It is used to automate some common tasks in the household like switching lamps / shutters / heating / etc. and to log events like temperature / humidity / power consumption.\\n\\nThe program runs as a server, you can control it via web or smartphone frontends, telnet or TCP/IP directly.\\n\\nIn order to use FHEM you'll need a 24/7 server (NAS, RPi, PC, Mac Mini, etc.) with a Perl interpreter and some attached hardware like the CUL-, EnOcean-, Z-Wave-USB-Stick, etc. to access the actors and sensors.\\n\\nIt is pronounced without the h, like in feminine.",
"x_lang": {
"de": {
"abstract": "FHEM® ist ein Perl Server zur Hausautomatisierung",
"description": "FHEM® (eingetragene Marke) ist ein in Perl geschriebener, GPL lizensierter Server für die Heimautomatisierung. Man kann mit FHEM häufig auftretende Aufgaben automatisieren, wie z.Bsp. Lampen / Rollladen / Heizung / usw. schalten, oder Ereignisse wie Temperatur / Feuchtigkeit / Stromverbrauch protokollieren und visualisieren.\\n\\nDas Programm läuft als Server, man kann es über WEB, dedizierte Smartphone Apps oder telnet bedienen, TCP Schnittstellen für JSON und XML existieren ebenfalls.\\n\\nUm es zu verwenden benötigt man einen 24/7 Rechner (NAS, RPi, PC, MacMini, etc) mit einem Perl Interpreter und angeschlossene Hardware-Komponenten wie CUL-, EnOcean-, Z-Wave-USB-Stick, etc. für einen Zugang zu den Aktoren und Sensoren.\\n\\nAusgesprochen wird es ohne h, wie bei feminin."
"description": "FHEM® (eingetragene Marke) ist ein in Perl geschriebener, GPL lizensierter Server für die Heimautomatisierung. Man kann mit FHEM häufig auftretende Aufgaben automatisieren, wie z.Bsp. Lampen / Rollladen / Heizung / usw. schalten, oder Ereignisse wie Temperatur / Feuchtigkeit / Stromverbrauch protokollieren und visualisieren.\\n\\nDas Programm läuft als Server, man kann es über WEB, dedizierte Smartphone Apps oder telnet bedienen, TCP Schnittstellen für JSON und XML existieren ebenfalls.\\n\\nUm es zu verwenden benötigt man einen 24/7 Rechner (NAS, RPi, PC, Mac Mini, etc.) mit einem Perl Interpreter und angeschlossene Hardware-Komponenten wie CUL-, EnOcean-, Z-Wave-USB-Stick, etc. für einen Zugang zu den Aktoren und Sensoren.\\n\\nAusgesprochen wird es ohne h, wie bei feminin."
}
},
"keywords": [
@ -1905,66 +1893,6 @@ sub __SetXVersion {
}
}
},
"x_prereqs_nodejs": {
"runtime": {
"requires": {
},
"recommends": {
},
"suggests": {
}
}
},
"x_prereqs_python": {
"runtime": {
"requires": {
},
"recommends": {
},
"suggests": {
}
}
},
"x_prereqs_binary_exec": {
"runtime": {
"requires": {
},
"recommends": {
},
"suggests": {
}
}
},
"x_prereqs_sudo": {
"runtime": {
"requires": {
},
"recommends": {
},
"suggests": {
}
}
},
"x_prereqs_permissions_fileown": {
"runtime": {
"requires": {
},
"recommends": {
},
"suggests": {
}
}
},
"x_prereqs_permissions_filemod": {
"runtime": {
"requires": {
},
"recommends": {
},
"suggests": {
}
}
},
"resources": {
"x_copyright": {
"web": "https://verein.fhem.de/"