github.com/mackerelio/mackerel-agent-plugins@v0.89.3/tool/gen_mackerel_plugin.pl (about) 1 #!/usr/bin/env perl 2 use 5.014; 3 use warnings; 4 use utf8; 5 use autodie; 6 use IO::File; 7 use JSON::PP; 8 9 my $PLUGIN_PREFIX = 'mackerel-plugin-'; 10 my $PACKAGE_NAME = 'mackerel-agent-plugins'; 11 12 # refer Mackerel::ReleaseUtils 13 sub replace { 14 my ($glob, $code) = @_; 15 for my $file (glob $glob) { 16 my $content = $code->(slurp_utf8($file), $file); 17 $content .= "\n" if $content !~ /\n\z/ms; 18 19 # for keeping permission 20 append_file($file, $content); 21 } 22 } 23 24 sub retrieve_plugins { 25 # exclude plugins which has been moved to other repositories 26 sort map {s/^$PLUGIN_PREFIX//; $_} grep { -e "$_/lib" } <$PLUGIN_PREFIX*>; 27 } 28 29 sub update_readme { 30 my $plugins = shift; 31 my $external_plugins = shift; 32 33 my $doc_links = ''; 34 my %doc_links_lines; 35 for my $plug (@$plugins) { 36 $doc_links_lines{$plug} = "* [$PLUGIN_PREFIX$plug](./$PLUGIN_PREFIX$plug/README.md)\n" 37 } 38 for my $plug (@$external_plugins) { 39 my $link = sprintf "https://%s/blob/main/README.md", $plug->{'repository'}; 40 $doc_links_lines{$plug->{name}} = "* [$PLUGIN_PREFIX$plug->{name}]($link)\n" 41 } 42 43 for my $key (sort keys %doc_links_lines) { 44 $doc_links .= $doc_links_lines{$key}; 45 } 46 47 replace 'README.md' => sub { 48 my $readme = shift; 49 my $plu_reg = qr/$PLUGIN_PREFIX[-0-9a-zA-Z_]+/; 50 my $plu_reg_readme = qr/\.\/$PLUGIN_PREFIX[-0-9a-zA-Z_]+|https:\/\/github\.com\/mackerelio\/[-0-0a-zA-Z_]+\/blob\/main/; 51 $readme =~ s!(?:\* \[$plu_reg\]\($plu_reg_readme/README\.md\)\n)+!$doc_links!ms; 52 $readme; 53 }; 54 } 55 56 sub update_packaging_specs { 57 my @plugins = @_; 58 my $for_in = 'for i in ' . join(' ', @plugins) . '; do'; 59 60 my $replace_sub = sub { 61 my $content = shift; 62 $content =~ s/for i in.*?;\s*do/$for_in/ms; 63 $content; 64 }; 65 replace $_, $replace_sub for ("packaging/rpm/$PACKAGE_NAME*.spec", "packaging/deb*/debian/rules", "packaging/tar/build.sh"); 66 } 67 68 #### 69 # file utility 70 #### 71 72 sub slurp_utf8 { 73 my $filename = shift; 74 my $fh = IO::File->new($filename, "<:utf8"); 75 local $/; 76 <$fh>; 77 } 78 sub write_file { 79 my $filename = shift; 80 my $content = shift; 81 my $fh = IO::File->new($filename, ">:utf8"); 82 print $fh $content; 83 $fh->close; 84 } 85 sub append_file { 86 my $filename = shift; 87 my $content = shift; 88 my $fh = IO::File->new($filename, "+>:utf8"); 89 print $fh $content; 90 $fh->close; 91 } 92 93 sub load_packaging_confg { 94 decode_json(slurp_utf8('packaging/config.json')); 95 } 96 97 #### 98 # some file generate task 99 #### 100 101 sub subtask { 102 my $config = load_packaging_confg; 103 my @plugins = retrieve_plugins; 104 update_readme(\@plugins, $config->{'external-plugins'}); 105 106 my @all_plugins = ( 107 @{ $config->{plugins} }, 108 map { $_->{name} } @{ $config->{'external-plugins'} }, 109 ); 110 update_packaging_specs(sort @all_plugins); 111 } 112 113 subtask(); 114 115 #### 116 # go:generate task 117 #### 118 119 my @plugins = sort @{ load_packaging_confg()->{plugins}}; 120 my @external_plugins = sort { $a->{name} cmp $b->{name} } @{ load_packaging_confg()->{'external-plugins'}}; 121 122 sub resolve_package { 123 my $plug = shift; 124 $plug =~ s/-//g; 125 "mp$plug"; 126 } 127 128 my $imports = ""; 129 my $case = ""; 130 my $plugs = ""; 131 for my $plug (@plugins) { 132 my $pkg = "mp$plug"; 133 $pkg =~ s/-//g; 134 $imports .= sprintf qq[\t"github.com/mackerelio/mackerel-agent-plugins/mackerel-plugin-%s/lib"\n], $plug; 135 $case .= sprintf qq[\tcase "%s":\n\t\t%s.Do()\n], $plug, $pkg; 136 $plugs .= sprintf qq[\t"%s",\n], $plug; 137 } 138 for my $pluginfo (@external_plugins) { 139 my $plug = $pluginfo->{name}; 140 my $pkg = "mp$plug"; 141 $pkg =~ s/-//g; 142 $imports .= sprintf qq[\t"%s/lib"\n], $pluginfo->{repository}; 143 $case .= sprintf qq[\tcase "%s":\n\t\t%s.Do()\n], $plug, $pkg; 144 $plugs .= sprintf qq[\t"%s",\n], $plug; 145 } 146 147 my $mackerel_plugin_gen = qq!// Code generated by "tool/gen_mackerel_plugin.pl"; DO NOT EDIT 148 package main 149 150 import ( 151 "fmt" 152 153 $imports) 154 155 func runPlugin(plug string) error { 156 switch plug { 157 ${case}\tdefault: 158 return fmt.Errorf("unknown plugin: %q", plug) 159 } 160 return nil 161 } 162 163 var plugins = []string{ 164 $plugs}!; 165 166 say $mackerel_plugin_gen;