2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-04-15 03:59:11 +00:00

98_Installer: add initial version of FHEM Installer

git-svn-id: https://svn.fhem.de/fhem/trunk@18848 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
jpawlowski 2019-03-10 14:31:07 +00:00
parent 8009dc6143
commit 63c3ac4dec
16 changed files with 1923 additions and 215 deletions

View File

@ -26,7 +26,7 @@ sub RESIDENTS_Initialize($) {
. "rgr_states:multiple-strict,home,gotosleep,asleep,awoken,absent,gone rgr_lang:EN,DE rgr_noDuration:0,1 rgr_showAllStates:0,1 rgr_wakeupDevice " . "rgr_states:multiple-strict,home,gotosleep,asleep,awoken,absent,gone rgr_lang:EN,DE rgr_noDuration:0,1 rgr_showAllStates:0,1 rgr_wakeupDevice "
. $readingFnAttributes; . $readingFnAttributes;
return FHEM::Meta::Load( __FILE__, $hash ); return FHEM::Meta::InitMod( __FILE__, $hash );
} }
# module Fn #################################################################### # module Fn ####################################################################

View File

@ -31,7 +31,7 @@ sub GUEST_Initialize($) {
$hash->{AttrList} .= " " . $hash->{AttrPrefix} . $_; $hash->{AttrList} .= " " . $hash->{AttrPrefix} . $_;
} }
return FHEM::Meta::Load( __FILE__, $hash ); return FHEM::Meta::InitMod( __FILE__, $hash );
} }
1; 1;

View File

@ -31,7 +31,7 @@ sub ROOMMATE_Initialize($) {
$hash->{AttrList} .= " " . $hash->{AttrPrefix} . $_; $hash->{AttrList} .= " " . $hash->{AttrPrefix} . $_;
} }
return FHEM::Meta::Load( __FILE__, $hash ); return FHEM::Meta::InitMod( __FILE__, $hash );
} }
1; 1;

View File

@ -21,7 +21,7 @@ sub npmjs_Initialize($) {
. "npmglobal:1,0 " . "npmglobal:1,0 "
. $readingFnAttributes; . $readingFnAttributes;
return FHEM::Meta::Load( __FILE__, $modHash ); return FHEM::Meta::InitMod( __FILE__, $modHash );
} }
# define package # define package
@ -99,7 +99,7 @@ sub Define($$) {
$attr{$name}{alias} = 'Node.js Package Update Status'; $attr{$name}{alias} = 'Node.js Package Update Status';
$attr{$name}{devStateIcon} = $attr{$name}{devStateIcon} =
'npm.updates.available:security@red:outdated npm.is.up.to.date:security@green:outdated .*npm.outdated.*in.progress:system_fhem_reboot@orange .*in.progress:system_fhem_update@orange warning.*:message_attention@orange error.*:message_attention@red'; 'npm.updates.available:security@red:outdated npm.is.up.to.date:security@green:outdated .*npm.outdated.*in.progress:system_fhem_reboot@orange .*in.progress:system_fhem_update@orange warning.*:message_attention@orange error.*:message_attention@red';
$attr{$name}{group} = 'System'; $attr{$name}{group} = 'Update';
$attr{$name}{icon} = 'npm-old'; $attr{$name}{icon} = 'npm-old';
$attr{$name}{room} = 'System'; $attr{$name}{room} = 'System';
} }
@ -408,7 +408,7 @@ sub Set($$@) {
# return Usage: # return Usage:
else { else {
my $list = ""; my $list = '';
if ( !defined( $hash->{".fhem"}{npm}{nodejsversions} ) ) { if ( !defined( $hash->{".fhem"}{npm}{nodejsversions} ) ) {
$list = $list =
@ -574,7 +574,7 @@ sub Get($$@) {
return $ret; return $ret;
} }
else { else {
my $list = ""; my $list = '';
$list .= " showOutdatedList:noArg" $list .= " showOutdatedList:noArg"
if ( defined( $hash->{".fhem"}{npm}{outdatedpackages} ) if ( defined( $hash->{".fhem"}{npm}{outdatedpackages} )
and scalar keys %{ $hash->{".fhem"}{npm}{outdatedpackages} } > 0 ); and scalar keys %{ $hash->{".fhem"}{npm}{outdatedpackages} } > 0 );
@ -638,7 +638,7 @@ sub DoModuleTrigger($$@) {
$noreplace = 1 unless ( defined($noreplace) ); $noreplace = 1 unless ( defined($noreplace) );
$TYPE = $hash->{TYPE} unless ( defined($TYPE) ); $TYPE = $hash->{TYPE} unless ( defined($TYPE) );
return "" return ''
unless ( defined($TYPE) unless ( defined($TYPE)
&& defined( $modules{$TYPE} ) && defined( $modules{$TYPE} )
&& defined($eventString) && defined($eventString)
@ -660,7 +660,7 @@ sub DoModuleTrigger($$@) {
# This is a global event on module level and in device context # This is a global event on module level and in device context
return "$event: missing device name" return "$event: missing device name"
if ( !defined($dev) || $dev eq "" ); if ( !defined($dev) || $dev eq '' );
return DoTrigger( "global", "$TYPE:$eventString", $noreplace ); return DoTrigger( "global", "$TYPE:$eventString", $noreplace );
} }
@ -803,13 +803,13 @@ sub ExecuteNpmCommand($) {
my $npm = {}; my $npm = {};
$npm->{debug} = $cmd->{debug}; $npm->{debug} = $cmd->{debug};
my $cmdPrefix = ""; my $cmdPrefix = '';
my $cmdSuffix = ""; my $cmdSuffix = '';
if ( $cmd->{host} =~ /^(?:(.*)@)?([^:]+)(?::(\d+))?$/ if ( $cmd->{host} =~ /^(?:(.*)@)?([^:]+)(?::(\d+))?$/
&& lc($2) ne "localhost" ) && lc($2) ne "localhost" )
{ {
my $port = ""; my $port = '';
if ($3) { if ($3) {
$port = "-p $3 "; $port = "-p $3 ";
} }
@ -830,7 +830,7 @@ sub ExecuteNpmCommand($) {
# wrap SSH command # wrap SSH command
$cmdPrefix .= $cmdPrefix .=
'ssh -oBatchMode=yes ' . $port . ( $1 ? "$1@" : "" ) . $2 . ' \''; 'ssh -oBatchMode=yes ' . $port . ( $1 ? "$1@" : '' ) . $2 . ' \'';
$cmdSuffix = '\' 2>&1'; $cmdSuffix = '\' 2>&1';
} }
@ -907,7 +907,7 @@ sub ExecuteNpmCommand($) {
} }
} }
else { else {
my @packages = ""; my @packages = '';
foreach my $package ( split / /, $1 ) { foreach my $package ( split / /, $1 ) {
next next
unless ( $package =~ unless ( $package =~
@ -929,14 +929,14 @@ sub ExecuteNpmCommand($) {
push @packages, $package; push @packages, $package;
} }
my $pkglist = join( ' ', @packages ); my $pkglist = join( ' ', @packages );
return unless ( $pkglist ne "" ); return unless ( $pkglist ne '' );
$npm->{npminstall} =~ s/%PACKAGES%/$pkglist/gi; $npm->{npminstall} =~ s/%PACKAGES%/$pkglist/gi;
} }
print qq($npm->{npminstall}\n) if ( $npm->{debug} == 1 ); print qq($npm->{npminstall}\n) if ( $npm->{debug} == 1 );
$response = NpmInstall($npm); $response = NpmInstall($npm);
} }
elsif ( $cmd->{cmd} =~ /^uninstall (.+)/ ) { elsif ( $cmd->{cmd} =~ /^uninstall (.+)/ ) {
my @packages = ""; my @packages = '';
foreach my $package ( split / /, $1 ) { foreach my $package ( split / /, $1 ) {
next next
unless ( $package =~ unless ( $package =~
@ -944,13 +944,13 @@ sub ExecuteNpmCommand($) {
push @packages, $package; push @packages, $package;
} }
my $pkglist = join( ' ', @packages ); my $pkglist = join( ' ', @packages );
return unless ( $pkglist ne "" ); return unless ( $pkglist ne '' );
$npm->{npmuninstall} =~ s/%PACKAGES%/$pkglist/gi; $npm->{npmuninstall} =~ s/%PACKAGES%/$pkglist/gi;
print qq($npm->{npmuninstall}\n) if ( $npm->{debug} == 1 ); print qq($npm->{npmuninstall}\n) if ( $npm->{debug} == 1 );
$response = NpmUninstall($npm); $response = NpmUninstall($npm);
} }
elsif ( $cmd->{cmd} =~ /^update(?: (.+))?/ ) { elsif ( $cmd->{cmd} =~ /^update(?: (.+))?/ ) {
my $pkglist = ""; my $pkglist = '';
if ( defined($1) ) { if ( defined($1) ) {
my @packages; my @packages;
foreach my $package ( split / /, $1 ) { foreach my $package ( split / /, $1 ) {
@ -1029,7 +1029,7 @@ sub RetrieveNpmOutput($$) {
my $p = shift; my $p = shift;
my $h = {}; my $h = {};
return $h unless ( defined($p) && $p ne "" ); return $h unless ( defined($p) && $p ne '' );
# first try to interprete text as JSON directly # first try to interprete text as JSON directly
my $decode_json = eval { decode_json($p) }; my $decode_json = eval { decode_json($p) };
@ -1344,21 +1344,21 @@ sub CreateInstalledList($$) {
my $html = defined( $hash->{CL} ) && $hash->{CL}{TYPE} eq "FHEMWEB" ? 1 : 0; my $html = defined( $hash->{CL} ) && $hash->{CL}{TYPE} eq "FHEMWEB" ? 1 : 0;
$packages = $hash->{".fhem"}{npm}{listedpackages}{dependencies}; $packages = $hash->{".fhem"}{npm}{listedpackages}{dependencies};
my $header = ""; my $header = '';
my $footer = ""; my $footer = '';
if ($html) { if ($html) {
$header = '<html><table style="min-width: 450px;" class="block wide">'; $header = '<html><table style="min-width: 450px;" class="block wide">';
$footer = '</table></html>'; $footer = '</table></html>';
} }
my $rowOpen = ""; my $rowOpen = '';
my $rowOpenEven = ""; my $rowOpenEven = '';
my $rowOpenOdd = ""; my $rowOpenOdd = '';
my $colOpen = ""; my $colOpen = '';
my $txtOpen = ""; my $txtOpen = '';
my $txtClose = ""; my $txtClose = '';
my $colClose = "\t\t\t"; my $colClose = "\t\t\t";
my $rowClose = ""; my $rowClose = '';
if ($html) { if ($html) {
$rowOpen = '<tr>'; $rowOpen = '<tr>';
@ -1417,21 +1417,21 @@ sub CreateOutdatedList($$) {
$packages = $hash->{".fhem"}{npm}{outdatedpackages}; $packages = $hash->{".fhem"}{npm}{outdatedpackages};
my $npmglobal = ( AttrVal( $hash->{NAME}, 'npmglobal', 1 ) eq '1' ? 1 : 0 ); my $npmglobal = ( AttrVal( $hash->{NAME}, 'npmglobal', 1 ) eq '1' ? 1 : 0 );
my $header = ""; my $header = '';
my $footer = ""; my $footer = '';
if ($html) { if ($html) {
$header = '<html><table style="min-width: 450px;" class="block wide">'; $header = '<html><table style="min-width: 450px;" class="block wide">';
$footer = '</table></html>'; $footer = '</table></html>';
} }
my $rowOpen = ""; my $rowOpen = '';
my $rowOpenEven = ""; my $rowOpenEven = '';
my $rowOpenOdd = ""; my $rowOpenOdd = '';
my $colOpen = ""; my $colOpen = '';
my $txtOpen = ""; my $txtOpen = '';
my $txtClose = ""; my $txtClose = '';
my $colClose = "\t\t\t"; my $colClose = "\t\t\t";
my $rowClose = ""; my $rowClose = '';
if ($html) { if ($html) {
$rowOpen = '<tr>'; $rowOpen = '<tr>';
@ -1748,7 +1748,7 @@ sub ToDay() {
"node", "node",
"npm" "npm"
], ],
"version": "v1.0.4", "version": "v1.0.5",
"release_status": "stable", "release_status": "stable",
"author": [ "author": [
"Julian Pawlowski <julian.pawlowski@gmail.com>" "Julian Pawlowski <julian.pawlowski@gmail.com>"
@ -1762,7 +1762,7 @@ sub ToDay() {
"prereqs": { "prereqs": {
"runtime": { "runtime": {
"requires": { "requires": {
"FHEM": 5.00918623, "FHEM": 5.00918799,
"perl": 5.014, "perl": 5.014,
"GPUtils": 0, "GPUtils": 0,
"JSON": 0, "JSON": 0,
@ -1881,20 +1881,9 @@ sub ToDay() {
} }
}, },
"resources": { "resources": {
"license": [
"https://fhem.de/#License"
],
"homepage": "https://fhem.de/",
"bugtracker": { "bugtracker": {
"web": "https://forum.fhem.de/index.php/board,29.0.html", "web": "https://forum.fhem.de/index.php/board,29.0.html",
"x_web_title": "Sonstige Systeme" "x_web_title": "FHEM Forum: Sonstige Systeme"
},
"repository": {
"type": "svn",
"url": "https://svn.fhem.de/fhem/",
"x_branch_master": "trunk",
"x_branch_dev": "trunk",
"web": "https://svn.fhem.de/"
} }
} }
} }

View File

@ -268,7 +268,7 @@ sub HP1000_Initialize($) {
}, },
}; };
return FHEM::Meta::Load( __FILE__, $hash ); return FHEM::Meta::InitMod( __FILE__, $hash );
} }
# regular Fn ################################################################## # regular Fn ##################################################################

View File

@ -295,7 +295,7 @@ sub Wunderground_Initialize($) {
'wind_speed_mph' => { rtype => 'mph', formula_symbol => 'Ws' } 'wind_speed_mph' => { rtype => 'mph', formula_symbol => 'Ws' }
}; };
return FHEM::Meta::Load( __FILE__, $hash ); return FHEM::Meta::InitMod( __FILE__, $hash );
} }
# regular Fn ################################################################## # regular Fn ##################################################################

View File

@ -60,7 +60,7 @@ sub ENIGMA2_Initialize($) {
}, },
}; };
return FHEM::Meta::Load( __FILE__, $hash ); return FHEM::Meta::InitMod( __FILE__, $hash );
} }
# regular Fn ################################################################## # regular Fn ##################################################################

View File

@ -249,7 +249,7 @@ sub LaMetric2_Initialize($$) {
#$hash->{parseParams} = 1; # not possible due to legacy msg command schema #$hash->{parseParams} = 1; # not possible due to legacy msg command schema
$hash->{'.msgParams'} = { parseParams => 1, }; $hash->{'.msgParams'} = { parseParams => 1, };
return FHEM::Meta::Load( __FILE__, $hash ); return FHEM::Meta::InitMod( __FILE__, $hash );
} }
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------

View File

@ -50,7 +50,7 @@ sub PHTV_Initialize($) {
}; };
FHEM_colorpickerInit(); FHEM_colorpickerInit();
return FHEM::Meta::Load( __FILE__, $hash ); return FHEM::Meta::InitMod( __FILE__, $hash );
} }
# regular Fn ################################################################## # regular Fn ##################################################################

View File

@ -25,7 +25,7 @@ sub Pushover_Initialize($$) {
#$hash->{parseParams} = 1; # not possible due to legacy msg command schema #$hash->{parseParams} = 1; # not possible due to legacy msg command schema
$hash->{'.msgParams'} = { parseParams => 1, }; $hash->{'.msgParams'} = { parseParams => 1, };
return FHEM::Meta::Load( __FILE__, $hash ); return FHEM::Meta::InitMod( __FILE__, $hash );
} }
# regular Fn ################################################################## # regular Fn ##################################################################

View File

@ -58,7 +58,7 @@ sub THINKINGCLEANER_Initialize($) {
}, },
}; };
return FHEM::Meta::Load( __FILE__, $hash ); return FHEM::Meta::InitMod( __FILE__, $hash );
} }
# regular Fn ################################################################## # regular Fn ##################################################################

View File

@ -146,7 +146,7 @@ sub msgConfig_Initialize($) {
addToAttrList($_); addToAttrList($_);
} }
return FHEM::Meta::Load( __FILE__, $hash ); return FHEM::Meta::InitMod( __FILE__, $hash );
} }
# regular Fn ################################################################## # regular Fn ##################################################################

View File

@ -18,7 +18,7 @@ sub GEOFANCY_Initialize($) {
$hash->{SetFn} = "GEOFANCY_Set"; $hash->{SetFn} = "GEOFANCY_Set";
$hash->{AttrList} = "devAlias disable:0,1 " . $readingFnAttributes; $hash->{AttrList} = "devAlias disable:0,1 " . $readingFnAttributes;
return FHEM::Meta::Load( __FILE__, $hash ); return FHEM::Meta::InitMod( __FILE__, $hash );
} }
# regular Fn ################################################################## # regular Fn ##################################################################

1647
fhem/FHEM/98_Installer.pm Normal file

File diff suppressed because it is too large Load Diff

View File

@ -37,37 +37,25 @@ return "$@" if ($@);
return $ret if ($ret); return $ret if ($ret);
use version 0.77; our $VERSION = $META{version}; use version 0.77; our $VERSION = $META{version};
our $coreUpdate; # sub import(@) {
our %corePackageUpdates; # my $pkg = caller(0);
our %coreFileUpdates; #
# if ( $pkg ne "main" ) {
# }
# }
our %moduleUpdates; # Loads Metadata for single module, based on filename
our %packageUpdates; sub InitMod($$;$) {
our %fileUpdates;
sub import(@) {
my $pkg = caller(0);
# Initially load update information
# to be ready for meta analysis
__GetUpdatedata() unless ( defined($coreUpdate) );
if ( $pkg ne "main" ) {
}
}
# Loads Metadata for a module
sub Load($$;$) {
my ( $filePath, $modHash, $runInLoop ) = @_; my ( $filePath, $modHash, $runInLoop ) = @_;
my $ret = __PutMetadata( $filePath, $modHash, 1, $runInLoop ); my $ret = __PutMetadata( $filePath, $modHash, 1, $runInLoop );
if ($@) { if ($@) {
Log 1, __PACKAGE__ . "::Load: ERROR: \$\@:\n" . $@; Log 1, __PACKAGE__ . "::InitMod: ERROR: \$\@:\n" . $@;
return "$@"; return "$@";
} }
elsif ($ret) { elsif ($ret) {
Log 1, __PACKAGE__ . "::Load: ERROR: \$ret:\n" . $ret; Log 1, __PACKAGE__ . "::InitMod: ERROR: \$ret:\n" . $ret;
return $ret; return $ret;
} }
@ -92,33 +80,70 @@ sub Load($$;$) {
return undef; return undef;
} }
#TODO allow to have array of module names as optional parameter, use keys %modules when not given # Load Metadata for a list of modules
# Then make this function to be called by X_Initialize(). Problem: We don't know the module name yet, just filename. sub Load(;$$) {
# So maybe one can give wither filepath or modulename as parameter? my ( $modList, $reload ) = @_;
# Load Metadata for non-loaded modules
sub LoadAll(;$$) {
my ( $unused, $reload ) = @_;
my $t = TimeNow(); my $t = TimeNow();
my $v = __PACKAGE__->VERSION(); my $v = __PACKAGE__->VERSION();
my @rets; my @rets;
my $unused = 0;
my @lmodules;
# if modList is undefined or is equal to '1'
if ( !$modList || ( !ref($modList) && $modList eq '1' ) ) {
$unused = 1 if ( $modList && $modList eq '1' );
foreach ( keys %modules ) {
# Only process loaded modules
# unless unused modules were
# explicitly requested
push @lmodules,
$_
if (
$unused
|| ( defined( $modules{$_}{LOADED} )
&& $modules{$_}{LOADED} eq '1' )
);
}
}
# if a single module name was given
elsif ( !ref($modList) ) {
push @lmodules, $modList;
}
# if a list of module names was given
elsif ( ref($modList) eq 'ARRAY' ) {
foreach ( @{$modList} ) {
push @lmodules, $_;
}
}
# if a hash was given, assume every
# key is a module name
elsif ( ref($modList) eq 'HASH' ) {
foreach ( keys %{$modList} ) {
push @lmodules, $_;
}
}
# Wrong method use
else {
$@ = __PACKAGE__ . "::Load: ERROR: Unknown parameter value";
Log 1, $@;
return "$@";
}
__GetUpdatedata() if ($reload); __GetUpdatedata() if ($reload);
foreach my $modName ( keys %modules ) { foreach my $modName (@lmodules) {
# Only add META to loaded modules
# if not enforced for all
next
unless (
$unused
|| ( defined( $modules{$modName}{LOADED} )
&& $modules{$modName}{LOADED} eq '1' )
);
# Abort when module file was not indexed by # Abort when module file was not indexed by
# fhem.pl before. # fhem.pl before.
# Only continue if META was not loaded # Only continue if META was not loaded
# or should explicitly reloaded. # or should explicitly be reloaded.
next next
if ( if (
!defined( $modules{$modName}{ORDER} ) !defined( $modules{$modName}{ORDER} )
@ -141,15 +166,17 @@ sub LoadAll(;$$) {
. $modName . '.pm'; . $modName . '.pm';
} }
my $ret = Load( $filePath, $modules{$modName}, 1 ); my $ret = InitMod( $filePath, $modules{$modName}, 1 );
push @rets, $@ if ( $@ && $@ ne "" ); push @rets, $@ if ( $@ && $@ ne '' );
push @rets, $ret if ( $ret && $ret ne "" ); push @rets, $ret if ( $ret && $ret ne '' );
$modules{$modName}{META}{generated_by} = $META{name} . " $v, $t" $modules{$modName}{META}{generated_by} = $META{name} . " $v, $t"
if ( defined( $modules{$modName}{META} ) ); if ( defined( $modules{$modName}{META} ) );
}
SetInternals( $defs{'global'} ); foreach my $devName ( devspec2array( 'TYPE=' . $modName ) ) {
SetInternals( $defs{$devName} );
}
}
if (@rets) { if (@rets) {
$@ = join( "\n", @rets ); $@ = join( "\n", @rets );
@ -176,13 +203,13 @@ sub SetInternals($) {
return 0 return 0
unless ( defined( $modHash->{LOADED} ) && $modHash->{LOADED} eq '1' ); unless ( defined( $modHash->{LOADED} ) && $modHash->{LOADED} eq '1' );
$devHash->{'.FhemMetaInternalss'} = 1; $devHash->{'.FhemMetaInternals'} = 1;
__CopyMetaToInternals( $devHash, $modMeta ); __CopyMetaToInternals( $devHash, $modMeta );
return 1; return 1;
} }
# Get meta data # Get metadata
sub Get($$) { sub Get($$) {
my ( $devHash, $field ) = @_; my ( $devHash, $field ) = @_;
$devHash = $defs{$devHash} unless ( ref($devHash) ); $devHash = $defs{$devHash} unless ( ref($devHash) );
@ -208,10 +235,10 @@ sub Get($$) {
sub __CopyMetaToInternals { sub __CopyMetaToInternals {
return 0 unless ( __PACKAGE__ eq caller(0) ); return 0 unless ( __PACKAGE__ eq caller(0) );
my ( $devHash, $modMeta ) = @_; my ( $devHash, $modMeta ) = @_;
return unless ( defined( $devHash->{'.FhemMetaInternalss'} ) ); return unless ( defined( $devHash->{'.FhemMetaInternals'} ) );
return unless ( defined($modMeta) && ref($modMeta) eq "HASH" ); return unless ( defined($modMeta) && ref($modMeta) eq "HASH" );
$devHash->{FUPDATE} = $modMeta->{x_version} $devHash->{FVERSION} = $modMeta->{x_version}
if ( defined( $modMeta->{x_version} ) ); if ( defined( $modMeta->{x_version} ) );
} }
@ -238,7 +265,7 @@ sub __PutMetadata {
return undef; return undef;
} }
# Extract meta data from FHEM module file # Extract metadata from FHEM module file
sub __GetMetadata { sub __GetMetadata {
return 0 unless ( __PACKAGE__ eq caller(0) ); return 0 unless ( __PACKAGE__ eq caller(0) );
my ( $filePath, $modMeta, $runInLoop, $metaSection ) = @_; my ( $filePath, $modMeta, $runInLoop, $metaSection ) = @_;
@ -287,9 +314,9 @@ sub __GetMetadata {
} }
my $searchComments = 1; # not in use, see below my $searchComments = 1; # not in use, see below
my $currentJson = ""; my $currentJson = '';
while ( my $l = <$fh> ) { while ( my $l = <$fh> ) {
next if ( $l eq "" || $l =~ m/^\s+$/ ); next if ( $l eq '' || $l =~ m/^\s+$/ );
# # Track comments section at the beginning of the document # # Track comments section at the beginning of the document
# if ( $searchComments && $l !~ m/^#|\s*$/ ) { # if ( $searchComments && $l !~ m/^#|\s*$/ ) {
@ -338,7 +365,7 @@ m/(\$Id\: ((?:([0-9]+)_)?([\w]+)\.([\w]+))\s([0-9]+)\s((([0-9]+)-([0-9]+)-([0-9]
# $authorName = $authorMail # $authorName = $authorMail
# if ( $authorName && $authorName =~ m/written| from| by/i ); # if ( $authorName && $authorName =~ m/written| from| by/i );
# #
# $authorName = "" unless ($authorName); # $authorName = '' unless ($authorName);
# } # }
###### ######
@ -423,7 +450,7 @@ m/^=for\s+:application\/json;q=META\.json\s+([^\s\.]+\.[^\s\.]+)\s*$/i
{ {
$skip = 0; $skip = 0;
$currentJson = $1; $currentJson = $1;
$json{$currentJson} = ""; $json{$currentJson} = '';
} }
elsif ( !$skip elsif ( !$skip
&& $l =~ m/^=end\s+:application\/json\;q=META\.json/i ) && $l =~ m/^=end\s+:application\/json\;q=META\.json/i )
@ -441,7 +468,7 @@ m/^=for\s+:application\/json;q=META\.json\s+([^\s\.]+\.[^\s\.]+)\s*$/i
seek $fh, 0, 0; seek $fh, 0, 0;
while ( my $l = <$fh> ) { while ( my $l = <$fh> ) {
next if ( $l eq "" || $l =~ m/^\s+$/ ); next if ( $l eq '' || $l =~ m/^\s+$/ );
# Only seek the document until code starts # Only seek the document until code starts
if ( $l !~ m/^#/ && $l !~ m/^=[A-Za-z]+/i ) { if ( $l !~ m/^#/ && $l !~ m/^=[A-Za-z]+/i ) {
@ -649,7 +676,7 @@ m/(^#\s+(?:\d{1,2}\.\d{1,2}\.(?:\d{2}|\d{4})\s+)?[^v\d]*(v?(?:\d{1,3}\.\d{1,3}(?
} }
######## ########
# Meta data refactoring starts here # Metadata refactoring starts here
# #
#TODO #TODO
@ -702,7 +729,7 @@ m/(^#\s+(?:\d{1,2}\.\d{1,2}\.(?:\d{2}|\d{4})\s+)?[^v\d]*(v?(?:\d{1,3}\.\d{1,3}(?
push @{ $modMeta->{x_file} }, $version; push @{ $modMeta->{x_file} }, $version;
# Do not use repeating 0 in version # Do not use repeating 0 in version
$modMeta->{version} =~ s/\.0{2,}/\.0/g $modMeta->{version} = version->parse( $modMeta->{version} )->stringify
if ( defined( $modMeta->{version} ) ); if ( defined( $modMeta->{version} ) );
$@ .= $@ .=
@ -740,14 +767,8 @@ m/(^#\s+(?:\d{1,2}\.\d{1,2}\.(?:\d{2}|\d{4})\s+)?[^v\d]*(v?(?:\d{1,3}\.\d{1,3}(?
); );
$modMeta->{abstract} = $item_summary $modMeta->{abstract} = $item_summary
if ( $item_summary && !defined( $modMeta->{abstract} ) ); if ( $item_summary && !defined( $modMeta->{abstract} ) );
$modMeta->{x_lang}{DE}{abstract} = $item_summary_DE $modMeta->{x_lang}{de}{abstract} = $item_summary_DE
if ( $item_summary_DE && !defined( $modMeta->{x_lang}{DE}{abstract} ) ); if ( $item_summary_DE && !defined( $modMeta->{x_lang}{de}{abstract} ) );
$modMeta->{description} = "./docs/commandref.html#" . $modMeta->{x_file}[4]
unless ( defined( $modMeta->{description} ) );
$modMeta->{x_lang}{DE}{description} =
"./docs/commandref_DE.html#" . $modMeta->{x_file}[4]
unless ( defined( $modMeta->{x_lang}{DE}{description} ) );
# Only when this package is reading its own metadata. # Only when this package is reading its own metadata.
# Other modules shall get this added elsewhere for performance reasons # Other modules shall get this added elsewhere for performance reasons
@ -762,6 +783,12 @@ m/(^#\s+(?:\d{1,2}\.\d{1,2}\.(?:\d{2}|\d{4})\s+)?[^v\d]*(v?(?:\d{1,3}\.\d{1,3}(?
$META{name} . ' ' . __PACKAGE__->VERSION() . ', ' . TimeNow(); $META{name} . ' ' . __PACKAGE__->VERSION() . ', ' . TimeNow();
} }
# mandatory
unless ( $modMeta->{description} ) {
$modMeta->{description} = 'n/a';
}
# mandatory
unless ( $modMeta->{release_status} ) { unless ( $modMeta->{release_status} ) {
if ( defined( $modMeta->{x_vcs} ) ) { if ( defined( $modMeta->{x_vcs} ) ) {
$modMeta->{release_status} = 'stable'; $modMeta->{release_status} = 'stable';
@ -771,6 +798,7 @@ m/(^#\s+(?:\d{1,2}\.\d{1,2}\.(?:\d{2}|\d{4})\s+)?[^v\d]*(v?(?:\d{1,3}\.\d{1,3}(?
} }
} }
# mandatory
unless ( $modMeta->{license} ) { unless ( $modMeta->{license} ) {
if ( defined( $modMeta->{x_vcs} ) ) { if ( defined( $modMeta->{x_vcs} ) ) {
$modMeta->{license} = 'GPL_2'; $modMeta->{license} = 'GPL_2';
@ -780,6 +808,7 @@ m/(^#\s+(?:\d{1,2}\.\d{1,2}\.(?:\d{2}|\d{4})\s+)?[^v\d]*(v?(?:\d{1,3}\.\d{1,3}(?
} }
} }
# mandatory
unless ( $modMeta->{author} ) { unless ( $modMeta->{author} ) {
if ( defined( $modMeta->{x_vcs} ) ) { if ( defined( $modMeta->{x_vcs} ) ) {
$modMeta->{author} = [ $modMeta->{x_vcs}[15] . ' <>' ]; $modMeta->{author} = [ $modMeta->{x_vcs}[15] . ' <>' ];
@ -797,6 +826,66 @@ m/(^#\s+(?:\d{1,2}\.\d{1,2}\.(?:\d{2}|\d{4})\s+)?[^v\d]*(v?(?:\d{1,3}\.\d{1,3}(?
} }
} }
unless ( defined( $modMeta->{resources} )
&& defined( $modMeta->{resources}{license} ) )
{
if ( defined( $modMeta->{x_vcs} ) ) {
$modMeta->{resources}{license} =
['https://fhem.de/#License'];
}
}
unless ( defined( $modMeta->{resources} )
&& defined( $modMeta->{resources}{bugtracker} ) )
{
if ( defined( $modMeta->{x_vcs} ) ) {
$modMeta->{resources}{bugtracker}{web} = 'https://forum.fhem.de/';
}
}
unless ( defined( $modMeta->{resources} )
&& defined( $modMeta->{resources}{x_wiki} ) )
{
if ( defined( $modMeta->{x_vcs} ) ) {
$modMeta->{resources}{x_wiki}{web} = 'https://wiki.fhem.de/';
$modMeta->{resources}{x_wiki}{modpath} = 'wiki/';
}
}
unless ( defined( $modMeta->{resources} )
&& defined( $modMeta->{resources}{x_commandref} ) )
{
if ( defined( $modMeta->{x_vcs} ) ) {
$modMeta->{resources}{x_commandref}{web} =
'https://fhem.de/commandref.html';
$modMeta->{resources}{x_commandref}{modpath} = '#';
}
}
unless ( defined( $modMeta->{resources} )
&& defined( $modMeta->{resources}{x_support_community} ) )
{
if ( defined( $modMeta->{x_vcs} ) ) {
$modMeta->{resources}{x_support_community}{web} =
'https://forum.fhem.de/';
}
}
unless ( defined( $modMeta->{resources} )
&& defined( $modMeta->{resources}{repository} ) )
{
if ( defined( $modMeta->{x_vcs} ) ) {
$modMeta->{resources}{repository}{type} = 'svn';
$modMeta->{resources}{repository}{web} =
'https://svn.fhem.de/trac/browser/';
$modMeta->{resources}{repository}{url} =
'https://svn.fhem.de/fhem/';
$modMeta->{resources}{repository}{x_branch_master} = 'trunk';
$modMeta->{resources}{repository}{x_branch_dev} = 'trunk';
$modMeta->{resources}{repository}{x_filepath} = 'fhem/FHEM/';
}
}
# Static meta information # Static meta information
$modMeta->{dynamic_config} = 1; $modMeta->{dynamic_config} = 1;
$modMeta->{'meta-spec'} = { $modMeta->{'meta-spec'} = {
@ -811,80 +900,13 @@ m/(^#\s+(?:\d{1,2}\.\d{1,2}\.(?:\d{2}|\d{4})\s+)?[^v\d]*(v?(?:\d{1,3}\.\d{1,3}(?
return undef; return undef;
} }
# Set x_version based on existing meta data
sub __SetXVersion {
return 0 unless ( __PACKAGE__ eq caller(0) );
my ($modMeta) = @_;
my $modName = $modMeta->{x_file}[4];
delete $modMeta->{x_version} if ( defined( $modMeta->{x_version} ) );
# Special handling for fhem.pl
if ( $modMeta->{x_file}[2] eq 'fhem.pl' ) {
$modMeta->{x_version} = 'fhem.pl:' . $modMeta->{version};
}
# Generate extended version info based
# on base revision
elsif ( defined( $modMeta->{x_file}[7] eq 'generated/vcs' ) ) {
$modMeta->{x_version} =
$modMeta->{x_file}[2] . ':'
. (
$modMeta->{version} =~ m/0+\.0+(?:\.0+)?$/
? '?'
: $modMeta->{version}
);
}
# Generate generic version to fill the gap
elsif ( defined( $modMeta->{x_file}[7] eq 'generated/blank' ) ) {
$modMeta->{x_version} = $modMeta->{x_file}[2] . ':?';
}
# Generate extended version info with added base revision
elsif ( defined( $modMeta->{x_vcs} )
&& $modMeta->{x_vcs}[5] ne '' )
{
$modMeta->{x_version} =
$modMeta->{x_file}[2] . ':'
. (
$modMeta->{version} =~ m/^v0+\.0+(?:\.0+)*?$/
? '?'
: $modMeta->{version}
)
. '-s' # assume we only have Subversion for now
. $modMeta->{x_vcs}[5];
}
if ( defined( $modMeta->{x_version} ) ) {
# Add modified date to extended version
if ( defined( $modMeta->{x_vcs} ) ) {
$modMeta->{x_version} .= '/' . $modMeta->{x_vcs}[7];
# #FIXME can't use modified time because FHEM Update currently
# # does not set it based on controls_fhem.txt :-(
# # We need the block size from controls_fhem.txt here but
# # doesn't make sense to load that file here...
# $modMeta->{x_version} .= '/' . $modMeta->{x_file}[6][9][2];
# $modMeta->{x_version} .= '+modified'
# if ( defined( $modMeta->{x_vcs} )
# && $modMeta->{x_vcs}[16] ne $modMeta->{x_file}[6][9][0] );
}
else {
$modMeta->{x_version} .= '/' . $modMeta->{x_file}[6][9][2];
}
}
}
sub __GetUpdatedata { sub __GetUpdatedata {
return 0 unless ( __PACKAGE__ eq caller(0) ); return 0 unless ( __PACKAGE__ eq caller(0) );
my $fh; my $fh;
my @fileList; my @fileList;
# if there are 3rd party source file repositories involved # if there are 3rd party source file repositories involved
if ( open( $fh, '<' . './FHEM/controls.txt' ) ) { if ( open( $fh, '<' . $attr{global}{modpath} . '/FHEM/controls.txt' ) ) {
while ( my $l = <$fh> ) { while ( my $l = <$fh> ) {
push @fileList, $1 if ( $l =~ m/([^\/\s]+)$/ ); push @fileList, $1 if ( $l =~ m/([^\/\s]+)$/ );
} }
@ -898,7 +920,7 @@ sub __GetUpdatedata {
# loop through control files # loop through control files
foreach my $file (@fileList) { foreach my $file (@fileList) {
if ( open( $fh, '<' . './FHEM/' . $file ) ) { if ( open( $fh, '<' . $attr{global}{modpath} . '/FHEM/' . $file ) ) {
my $filePrefix; my $filePrefix;
my $srcRepoName; my $srcRepoName;
my $fileExtension; my $fileExtension;
@ -1063,6 +1085,65 @@ m/^((\S+) (((....)-(..)-(..))_((..):(..):(..))) (\d+) (?:\.\/)?((.+\/)?((?:(\d+)
} }
} }
# Set x_version based on existing metadata
sub __SetXVersion {
return 0 unless ( __PACKAGE__ eq caller(0) );
my ($modMeta) = @_;
my $modName = $modMeta->{x_file}[4];
delete $modMeta->{x_version} if ( defined( $modMeta->{x_version} ) );
# Special handling for fhem.pl
if ( $modMeta->{x_file}[2] eq 'fhem.pl' ) {
$modMeta->{x_version} = 'fhem.pl:' . $modMeta->{version};
}
# Generate extended version info based
# on base revision
elsif ( defined( $modMeta->{x_vcs} ) ) {
$modMeta->{x_version} =
$modMeta->{x_file}[2] . ':'
. (
$modMeta->{version} =~ m/^v0+\.0+(?:\.0+)*?$/
? '?'
: $modMeta->{version}
)
. (
$modMeta->{x_file}[7] ne 'generated/vcs'
&& $modMeta->{x_vcs}[5] ne ''
? '-s' # assume we only have Subversion for now
. $modMeta->{x_vcs}[5]
: ''
);
}
# Generate generic version to fill the gap
elsif ( defined( $modMeta->{x_file}[7] eq 'generated/blank' ) ) {
$modMeta->{x_version} = $modMeta->{x_file}[2] . ':?';
}
if ( defined( $modMeta->{x_version} ) ) {
# Add modified date to extended version
if ( defined( $modMeta->{x_vcs} ) ) {
$modMeta->{x_version} .= '/' . $modMeta->{x_vcs}[7];
# #FIXME can't use modified time because FHEM Update currently
# # does not set it based on controls_fhem.txt :-(
# # We need the block size from controls_fhem.txt here but
# # doesn't make sense to load that file here...
# $modMeta->{x_version} .= '/' . $modMeta->{x_file}[6][9][2];
# $modMeta->{x_version} .= '+modified'
# if ( defined( $modMeta->{x_vcs} )
# && $modMeta->{x_vcs}[16] ne $modMeta->{x_file}[6][9][0] );
}
else {
$modMeta->{x_version} .= '/' . $modMeta->{x_file}[6][9][2];
}
}
}
1; 1;
=pod =pod
@ -1084,7 +1165,7 @@ m/^((\S+) (((....)-(..)-(..))_((..):(..):(..))) (\d+) (?:\.\/)?((.+\/)?((?:(\d+)
"metadata", "metadata",
"meta" "meta"
], ],
"version": "v0.1.2", "version": "v0.1.3",
"release_status": "testing", "release_status": "testing",
"author": [ "author": [
"Julian Pawlowski <julian.pawlowski@gmail.com>" "Julian Pawlowski <julian.pawlowski@gmail.com>"
@ -1206,20 +1287,9 @@ m/^((\S+) (((....)-(..)-(..))_((..):(..):(..))) (\d+) (?:\.\/)?((.+\/)?((?:(\d+)
} }
}, },
"resources": { "resources": {
"license": [
"https://fhem.de/#License"
],
"homepage": "https://fhem.de/",
"bugtracker": { "bugtracker": {
"web": "https://forum.fhem.de/index.php/board,48.0.html", "web": "https://forum.fhem.de/index.php/board,48.0.html",
"x_web_title": "FHEM Development" "x_web_title": "FHEM Forum: FHEM Development"
},
"repository": {
"type": "svn",
"url": "https://svn.fhem.de/fhem/",
"x_branch_master": "trunk",
"x_branch_dev": "trunk",
"web": "https://svn.fhem.de/"
} }
} }
} }
@ -1239,6 +1309,7 @@ m/^((\S+) (((....)-(..)-(..))_((..):(..):(..))) (\d+) (?:\.\/)?((.+\/)?((?:(\d+)
"fhem", "fhem",
"fhem-core" "fhem-core"
], ],
"x_copyright": "FHEM e.V., Rudolf König <vorstand@fhem.de>",
"author": [ "author": [
"Rudolf König <r.koenig@koeniglich.de>" "Rudolf König <r.koenig@koeniglich.de>"
], ],
@ -1271,7 +1342,6 @@ m/^((\S+) (((....)-(..)-(..))_((..):(..):(..))) (\d+) (?:\.\/)?((.+\/)?((?:(\d+)
}, },
"suggests": { "suggests": {
"Compress::Zlib": 0, "Compress::Zlib": 0,
"configDB": 0,
"FHEM::WinService": 0, "FHEM::WinService": 0,
"IO::Socket::INET6": 0, "IO::Socket::INET6": 0,
"Socket6": 0 "Socket6": 0
@ -1396,20 +1466,21 @@ m/^((\S+) (((....)-(..)-(..))_((..):(..):(..))) (\d+) (?:\.\/)?((.+\/)?((?:(\d+)
} }
}, },
"resources": { "resources": {
"license": [ "x_copyright": {
"https://fhem.de/#License" "web": "https://verein.fhem.de/"
],
"homepage": "https://fhem.de/",
"bugtracker": {
"web": "https://forum.fhem.de/",
"x_web_title": "FHEM Forum"
}, },
"x_privacy": {
"web": "https://fhem.de/Impressum.html#Datenschutz",
"title": "FHEM Data Privacy Statement"
},
"homepage": "https://fhem.de/",
"repository": { "repository": {
"type": "svn", "type": "svn",
"web": "https://svn.fhem.de/trac/browser/",
"url": "https://svn.fhem.de/fhem/", "url": "https://svn.fhem.de/fhem/",
"x_branch_master": "trunk", "x_branch_master": "trunk",
"x_branch_dev": "trunk", "x_branch_dev": "trunk",
"web": "https://svn.fhem.de/" "x_filepath": "fhem/"
} }
} }
} }

View File

@ -476,6 +476,7 @@ FHEM/98_HTTPMOD.pm stefanstrobel Sonstiges
FHEM/98_Hyperion.pm DeeSPe Beleuchtung FHEM/98_Hyperion.pm DeeSPe Beleuchtung
FHEM/98_IF.pm damian-s Automatisierung FHEM/98_IF.pm damian-s Automatisierung
FHEM/98_inotify.pm marvin78 Automatisierung FHEM/98_inotify.pm marvin78 Automatisierung
FHEM/98_Installer.pm loredo Unterstuetzende Dienste
FHEM/98_JsonList2.pm rudolfkoenig Automatisierung FHEM/98_JsonList2.pm rudolfkoenig Automatisierung
FHEM/98_logProxy.pm justme1968 Frontends/SVG Plots logProxy FHEM/98_logProxy.pm justme1968 Frontends/SVG Plots logProxy
FHEM/98_mark.pm betateilchen Sonstiges FHEM/98_mark.pm betateilchen Sonstiges