at 15.09-beta 5.0 kB view raw
1#! /run/current-system/sw/bin/perl -w 2 3use strict; 4use CPANPLUS::Backend; 5use YAML::XS; 6use JSON; 7 8my $module_name = $ARGV[0]; 9die "syntax: $0 <MODULE-NAME>\n" unless defined $module_name; 10 11my $cb = CPANPLUS::Backend->new; 12 13my @modules = $cb->search(type => "name", allow => [$module_name]); 14die "module $module_name not found\n" if scalar @modules == 0; 15die "multiple packages that match module $module_name\n" if scalar @modules > 1; 16my $module = $modules[0]; 17 18sub pkg_to_attr { 19 my ($pkg_name) = @_; 20 my $attr_name = $pkg_name; 21 $attr_name =~ s/-\d.*//; # strip version 22 return "LWP" if $attr_name eq "libwww-perl"; 23 $attr_name =~ s/-//g; 24 return $attr_name; 25} 26 27sub get_pkg_name { 28 my ($module) = @_; 29 my $pkg_name = $module->package; 30 $pkg_name =~ s/\.tar.*//; 31 $pkg_name =~ s/\.zip//; 32 return $pkg_name; 33} 34 35my $pkg_name = get_pkg_name $module; 36my $attr_name = pkg_to_attr $pkg_name; 37 38print STDERR "attribute name: ", $attr_name, "\n"; 39print STDERR "module: ", $module->module, "\n"; 40print STDERR "version: ", $module->version, "\n"; 41print STDERR "package: ", $module->package, , " (", $pkg_name, ", ", $attr_name, ")\n"; 42print STDERR "path: ", $module->path, "\n"; 43 44my $tar_path = $module->fetch(); 45print STDERR "downloaded to: $tar_path\n"; 46print STDERR "sha-256: ", $module->status->checksum_value, "\n"; 47 48my $pkg_path = $module->extract(); 49print STDERR "unpacked to: $pkg_path\n"; 50 51my $meta; 52if (-e "$pkg_path/META.yml") { 53 eval { 54 $meta = YAML::XS::LoadFile("$pkg_path/META.yml"); 55 }; 56 if ($@) { 57 system("iconv -f windows-1252 -t utf-8 '$pkg_path/META.yml' > '$pkg_path/META.yml.tmp'"); 58 $meta = YAML::XS::LoadFile("$pkg_path/META.yml.tmp"); 59 } 60} elsif (-e "$pkg_path/META.json") { 61 local $/; 62 open(my $fh, '<', "$pkg_path/META.json") or die; 63 $meta = decode_json(<$fh>); 64} else { 65 warn "package has no META.yml or META.json\n"; 66} 67 68print STDERR "metadata: ", encode_json($meta), "\n" if defined $meta; 69 70# Map a module to the attribute corresponding to its package 71# (e.g. HTML::HeadParser will be mapped to HTMLParser, because that 72# module is in the HTML-Parser package). 73sub module_to_pkg { 74 my ($module_name) = @_; 75 my @modules = $cb->search(type => "name", allow => [$module_name]); 76 if (scalar @modules == 0) { 77 # Fallback. 78 $module_name =~ s/:://g; 79 return $module_name; 80 } 81 my $module = $modules[0]; 82 my $attr_name = pkg_to_attr(get_pkg_name $module); 83 print STDERR "mapped dep $module_name to $attr_name\n"; 84 return $attr_name; 85} 86 87sub get_deps { 88 my ($type) = @_; 89 my $deps; 90 if (defined $meta->{prereqs}) { 91 die "unimplemented"; 92 } elsif ($type eq "runtime") { 93 $deps = $meta->{requires}; 94 } elsif ($type eq "configure") { 95 $deps = $meta->{configure_requires}; 96 } elsif ($type eq "build") { 97 $deps = $meta->{build_requires}; 98 } 99 my @res; 100 foreach my $n (keys %{$deps}) { 101 next if $n eq "perl"; 102 # Hacky way to figure out if this module is part of Perl. 103 if ($n !~ /^JSON/ && $n !~ /^YAML/ && $n !~ /^Module::Pluggable/) { 104 eval "use $n;"; 105 if (!$@) { 106 print STDERR "skipping Perl-builtin module $n\n"; 107 next; 108 } 109 } 110 push @res, module_to_pkg($n); 111 } 112 return @res; 113} 114 115sub uniq { 116 return keys %{{ map { $_ => 1 } @_ }}; 117} 118 119my @build_deps = sort(uniq(get_deps("configure"), get_deps("build"), get_deps("test"))); 120print STDERR "build deps: @build_deps\n"; 121 122my @runtime_deps = sort(uniq(get_deps("runtime"))); 123print STDERR "runtime deps: @runtime_deps\n"; 124 125my $homepage = $meta->{resources}->{homepage}; 126print STDERR "homepage: $homepage\n" if defined $homepage; 127 128my $description = $meta->{abstract}; 129if (defined $description) { 130 $description = uc(substr($description, 0, 1)) . substr($description, 1); # capitalise first letter 131 $description =~ s/\.$//; # remove period at the end 132 $description =~ s/\s*$//; 133 $description =~ s/^\s*//; 134 print STDERR "description: $description\n"; 135} 136 137my $license = $meta->{license}; 138if (defined $license) { 139 $license = "perl5" if $license eq "perl_5"; 140 print STDERR "license: $license\n"; 141} 142 143my $build_fun = -e "$pkg_path/Build.PL" && ! -e "$pkg_path/Makefile.PL" ? "buildPerlModule" : "buildPerlPackage"; 144 145print STDERR "===\n"; 146 147print <<EOF; 148 $attr_name = $build_fun { 149 name = "$pkg_name"; 150 src = fetchurl { 151 url = mirror://cpan/${\$module->path}/${\$module->package}; 152 sha256 = "${\$module->status->checksum_value}"; 153 }; 154EOF 155print <<EOF if scalar @build_deps > 0; 156 buildInputs = [ @build_deps ]; 157EOF 158print <<EOF if scalar @runtime_deps > 0; 159 propagatedBuildInputs = [ @runtime_deps ]; 160EOF 161print <<EOF; 162 meta = { 163EOF 164print <<EOF if defined $homepage; 165 homepage = $homepage; 166EOF 167print <<EOF if defined $description; 168 description = "$description"; 169EOF 170print <<EOF if defined $license; 171 license = "$license"; 172EOF 173print <<EOF; 174 }; 175 }; 176EOF