[Buildroot] [scanrock 1/5] utils/scanrock: new utility for Luarocks infrastructure
Francois Perrad
fperrad at gmail.com
Sun Oct 21 16:32:55 UTC 2018
Signed-off-by: Francois Perrad <francois.perrad at gadz.org>
---
docs/manual/adding-packages-luarocks.txt | 12 ++
utils/rockspec2br.lua | 238 +++++++++++++++++++++++
utils/scanrock | 128 ++++++++++++
3 files changed, 378 insertions(+)
create mode 100644 utils/rockspec2br.lua
create mode 100755 utils/scanrock
diff --git a/docs/manual/adding-packages-luarocks.txt b/docs/manual/adding-packages-luarocks.txt
index ec3d4e7cc..8b28c6fa8 100644
--- a/docs/manual/adding-packages-luarocks.txt
+++ b/docs/manual/adding-packages-luarocks.txt
@@ -50,6 +50,18 @@ Finally, on line 16, we invoke the +luarocks-package+
macro that generates all the Makefile rules that actually allows the
package to be built.
+Most of these data can be retrieved in the +rock+ and +rockspec+,
+which are fetched from https://luarocks.org.
+So, this file and the Config.in can be generated by running
+the script +utils/scanrock foo lua-foo+ in the Buildroot directory
+(or in a br2-external tree).
+This script creates a Config.in file and lua-foo.mk file for the
+requested package.
+You should still manually edit the result.
+
+* The +package/Config.in+ file has to be updated manually to include the
+ generated Config.in files.
+
[[luarocks-package-reference]]
==== +luarocks-package+ reference
diff --git a/utils/rockspec2br.lua b/utils/rockspec2br.lua
new file mode 100644
index 000000000..b3bc146e6
--- /dev/null
+++ b/utils/rockspec2br.lua
@@ -0,0 +1,238 @@
+--[[
+
+Copyright (C) 2018 by Francois Perrad <francois.perrad at gadz.org>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+This script is a part of Buildroot.
+
+]]
+
+local function usage ()
+ print [[
+Usage:
+ utils/rockspec2br [-name foo] [-subdir foo-3.2] [-license LICENSE] foo-3.2-1.rockspec
+]]
+end
+
+local function escape (s)
+ return s:gsub('-', '%%-'):gsub('%.', '%%.')
+end
+
+local function fsname (name)
+ return name:lower():gsub('_', '-')
+end
+
+local function brname (name)
+ return name:upper():gsub('-', '_')
+end
+
+local function brlicense (license)
+ if license:match('MIT/X') then
+ return 'MIT'
+ end
+ return license
+end
+
+local function wrap (txt, max)
+ local lines = {}
+ local line = ''
+ for word in txt:gmatch('(%S+)') do
+ if line:len() + word:len() > max - 1 then
+ lines[#lines+1] = line
+ line = ''
+ end
+ if line == '' then
+ line = word
+ else
+ line = line .. ' ' .. word
+ end
+ end
+ lines[#lines+1] = line
+ return lines
+end
+
+local br_libname = {
+ curl = 'libcurl',
+ fastcgi = 'libfcgi',
+ fuse = 'libfuse',
+ iconv = 'libiconv',
+}
+
+local function get_native_dependencies ()
+ local t = {}
+ local d = external_dependencies
+ if d then
+ if d.platforms and d.platforms.unix then
+ d = d.platforms.unix
+ end
+ for k in pairs(d) do
+ if k ~= 'platforms' then
+ k = k:lower()
+ if k ~= 'crypto' then
+ t[#t+1] = br_libname[k] or k
+ end
+ end
+ end
+ table.sort(t)
+ end
+ return t
+end
+
+local br_name = {
+ basexx = 'lua-basexx',
+ bit32 = 'lua-bit32',
+ compat53 = 'lua-compat53',
+ cqueues = 'lua-cqueues',
+ datafile = 'lua-datafile',
+ fifo = 'lua-fifo',
+ flu = 'lua-flu',
+ http = 'lua-http',
+ lpeg_patterns = 'lua-lpeg-patterns',
+ valua = 'lua-valua',
+ sailor = 'lua-sailor',
+}
+
+local function get_dependencies ()
+ local t = {}
+ for i = 1, #dependencies do
+ local dep = dependencies[i]:match('^(%S+)')
+ if dep ~= 'lua' then
+ t[#t+1] = br_name[dep] or dep
+ end
+ end
+ table.sort(t)
+ return t
+end
+
+local function generate_config (name)
+ local only_luajit = name:match('^lj')
+ local summary = description.summary or '???'
+ local homepage = description.homepage or '???'
+ local native_dependencies = get_native_dependencies()
+ local dependencies = get_dependencies()
+ local fname = 'package/' .. name .. '/Config.in'
+ local f = assert(io.open(fname, 'w'))
+ print('write ' .. fname)
+ f:write('config BR2_PACKAGE_' .. brname(name) .. '\n')
+ f:write('\tbool "' .. name .. '"\n')
+ if only_luajit then
+ f:write('\tdepends on BR2_PACKAGE_LUAJIT\n')
+ end
+ for i = 1, #native_dependencies do
+ f:write('\tselect BR2_PACKAGE_' .. brname(native_dependencies[i]) .. '\n')
+ end
+ for i = 1, #dependencies do
+ f:write('\tselect BR2_PACKAGE_' .. brname(dependencies[i]) .. ' # runtime\n')
+ end
+ f:write('\thelp\n')
+ f:write('\t ' .. table.concat(wrap(summary, 62), '\n\t ') .. '\n')
+ f:write('\n\t ' .. homepage .. '\n')
+ if only_luajit then
+ f:write('\ncomment "' .. name .. ' needs LuaJIT"\n')
+ f:write('\tdepends on !BR2_PACKAGE_LUAJIT\n')
+ end
+ f:close()
+end
+
+local function generate_mk (name, subdir, license_file)
+ local need_name_upstream = false
+ local need_version_upstream = false
+ local name_upstream = package
+ local version = version
+ local version_upstream = version:match('^([^-]+)-')
+ local revision = version:match('-(%d+)$')
+ local license = description.license
+ if subdir then
+ local root = subdir:match('^(.-)-' .. escape(version) .. '$')
+ if root then
+ subdir = root .. '-$(' .. brname(name) .. '_VERSION)'
+ end
+ root = subdir:match('^(.--[Vv])' .. escape(version_upstream) .. '$')
+ if root then
+ need_version_upstream = true
+ subdir = root .. '$(' .. brname(name) .. '_VERSION_UPSTREAM)'
+ end
+ root = subdir:match('^(.-)-' .. escape(version_upstream) .. '$')
+ if root then
+ if root == name then
+ subdir = nil
+ elseif root == name_upstream then
+ subdir = nil
+ need_name_upstream = true
+ else
+ need_version_upstream = true
+ subdir = root .. '-$(' .. brname(name) .. '_VERSION_UPSTREAM)'
+ end
+ end
+ end
+ local native_dependencies = get_native_dependencies()
+ local fname = 'package/' .. name .. '/' .. name .. '.mk'
+ local f = assert(io.open(fname, 'w'))
+ print('write ' .. fname)
+ f:write('################################################################################\n')
+ f:write('#\n')
+ f:write('# ' .. name .. '\n')
+ f:write('#\n')
+ f:write('################################################################################\n')
+ f:write('\n')
+ if need_version_upstream then
+ f:write(brname(name) .. '_VERSION_UPSTREAM = ' .. version_upstream .. '\n')
+ f:write(brname(name) .. '_VERSION = $(' .. brname(name) .. '_VERSION_UPSTREAM)-' .. revision .. '\n')
+ else
+ f:write(brname(name) .. '_VERSION = ' .. version .. '\n')
+ end
+ if name ~= name_upstream:lower() or need_name_upstream then
+ f:write(brname(name) .. '_NAME_UPSTREAM = ' .. name_upstream .. '\n')
+ end
+ if subdir then
+ f:write(brname(name) .. '_SUBDIR = ' .. subdir .. '\n')
+ end
+ if license then
+ f:write(brname(name) .. '_LICENSE = ' .. brlicense(license) .. '\n')
+ end
+ if license_file then
+ f:write(brname(name) .. '_LICENSE_FILES = $(' .. brname(name) .. '_SUBDIR)/' .. license_file .. '\n')
+ end
+ if #native_dependencies > 0 then
+ f:write(brname(name) .. '_DEPENDENCIES = ' .. table.concat(native_dependencies, ' ') .. '\n')
+ end
+ f:write('\n$(eval $(luarocks-package))\n')
+ f:close()
+end
+
+local name, subdir, license
+local i = 1
+if arg[i] == '-name' then
+ name = arg[i + 1]
+ i = i + 2
+end
+if arg[i] == '-subdir' then
+ subdir = arg[i + 1]
+ i = i + 2
+end
+if arg[i] == '-license' then
+ license = arg[i + 1]
+ i = i + 2
+end
+local rockspec = arg[i]
+if not rockspec then
+ usage()
+else
+ assert(loadfile(rockspec))()
+ name = fsname(name or package)
+ generate_config(name)
+ generate_mk(name, subdir, license)
+end
diff --git a/utils/scanrock b/utils/scanrock
new file mode 100755
index 000000000..3c13b3228
--- /dev/null
+++ b/utils/scanrock
@@ -0,0 +1,128 @@
+#!/usr/bin/env perl
+
+use 5.010;
+use strict;
+use warnings;
+use Fatal qw(open close opendir closedir);
+
+use Getopt::Long;
+use Pod::Usage;
+use Cwd;
+use Digest::SHA;
+use File::Temp qw(tempdir);
+
+my ($help, $man);
+GetOptions( 'help|?' => \$help,
+ 'man' => \$man,
+) or pod2usage(-exitval => 1);
+pod2usage(-exitval => 0) if $help;
+pod2usage(-exitval => 0, -verbose => 2) if $man;
+pod2usage(-exitval => 1) if scalar @ARGV == 0;
+
+my $rockname = shift @ARGV;
+my $fsname = shift @ARGV || $rockname;
+my $cwd = getcwd();
+my $tmpdir = tempdir( CLEANUP => 1 );
+
+qx{luarocks download --source ${rockname}};
+my $rock = glob q{*.src.rock};
+
+chdir $tmpdir;
+qx{luarocks unpack ${cwd}/${rock}};
+my $unpackdir = glob q{*};
+chdir $unpackdir;
+my $rockspec = File::Spec->rel2abs( glob q{*.rockspec} );
+opendir(my $dh, q{.});
+my @subdir = grep { m|^[^\.]| && -d } readdir($dh);
+my $subdir = shift @subdir;
+closedir $dh;
+chdir $subdir;
+my @license = glob q{COPY* LICENSE* doc/LICENSE* doc/license* doc/us/license*};
+my $license = shift @license;
+chdir $cwd;
+
+if ($license) {
+ print qx{lua utils/rockspec2br.lua -name ${fsname} -subdir ${subdir} -license ${license} ${rockspec}};
+}
+else {
+ print qx{lua utils/rockspec2br.lua -name ${fsname} -subdir ${subdir} ${rockspec}};
+}
+
+my $dirname = q{package/} . $fsname;
+my $hashname = $dirname . q{/} . $fsname . q{.hash};
+mkdir $dirname unless -d $dirname;
+my $sha256 = Digest::SHA->new(256)->addfile( $rock )->hexdigest();
+say qq{write ${hashname}};
+open my $fh, q{>}, $hashname;
+say {$fh} q{# computed by scanrock};
+say {$fh} qq{sha256 ${sha256} ${rock}};
+if ($license) {
+ $sha256 = Digest::SHA->new(256)->addfile( qq{${tmpdir}/${unpackdir}/${subdir}/${license}} )->hexdigest();
+ say {$fh} qq{sha256 ${sha256} ${subdir}/${license}};
+}
+close $fh;
+
+unlink $rock;
+
+__END__
+
+=head1 NAME
+
+utils/scanrock foo [lua-foo]
+
+=head1 SYNOPSIS
+
+utils/scanrock [options] rockname [brname]
+
+ Options:
+ -help
+ -man
+
+=head1 OPTIONS
+
+=over 8
+
+=item B<-help>
+
+Prints a brief help message and exits.
+
+=item B<-man>
+
+Prints the manual page and exits.
+
+=back
+
+=head1 DESCRIPTION
+
+This script creates templates of the Buildroot package files for a
+Luarock module.
+
+Most of the job is delegated to C<luarocks> and to the script
+C<utils/rockspec2br.lua>, so your $(HOST_DIR)/bin must append to PATH.
+
+After running this script, it is necessary to check the generated files.
+
+See the Buildroot documentation for details on the usage of the Luarock
+infrastructure.
+
+=head1 LICENSE
+
+Copyright (C) 2018 by Francois Perrad <francois.perrad at gadz.org>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+This script is a part of Buildroot.
+
+=cut
--
2.17.1
More information about the buildroot
mailing list