author | Igor Pashev <igor.pashev@nexenta.com> |
Tue, 25 Oct 2011 14:54:40 +0400 | |
changeset 464 | c51702debae2 |
parent 462 | 12f6fd8fe2bc |
child 465 | c55c69fd07bd |
permissions | -rwxr-xr-x |
459 | 1 |
#!/usr/bin/env perl |
2 |
||
462
12f6fd8fe2bc
Added Nexenta copyrights into tools
Alexander Eremin <a.eremin@nexenta.com>
parents:
460
diff
changeset
|
3 |
# Copyright (c) 2011 Nexenta Systems, Inc. All rights reserved. |
12f6fd8fe2bc
Added Nexenta copyrights into tools
Alexander Eremin <a.eremin@nexenta.com>
parents:
460
diff
changeset
|
4 |
|
459 | 5 |
use strict; |
6 |
use warnings FATAL => 'all'; |
|
7 |
use File::Basename; |
|
8 |
||
9 |
sub blab { |
|
10 |
print 'py2ips: ', @_, "\n"; |
|
11 |
} |
|
12 |
sub warning { |
|
13 |
blab 'WARNING: ', @_; |
|
14 |
sleep 2; |
|
15 |
} |
|
16 |
sub fatal { |
|
17 |
blab 'FATAL: ', @_; |
|
18 |
exit 1; |
|
19 |
} |
|
20 |
sub my_chdir { |
|
21 |
my ($path) = @_; |
|
22 |
chdir $path or fatal "Can't chdir() to `$path': $!"; |
|
23 |
} |
|
24 |
sub my_mkdir { |
|
25 |
my ($path, $mode) = @_; |
|
26 |
if (defined $mode) { |
|
27 |
mkdir $path, oct($mode) |
|
28 |
or fatal "Can't create dir `$path' with mode `$mode': $!"; |
|
29 |
} else { |
|
30 |
mkdir $path |
|
31 |
or fatal "Can't create dir `$path': $!"; |
|
32 |
} |
|
33 |
} |
|
34 |
sub uniq { |
|
35 |
my ($array_ref) = @_; |
|
36 |
my %hash = map { $_, 1 } @$array_ref; |
|
37 |
@$array_ref = keys %hash; |
|
38 |
} |
|
39 |
||
40 |
sub shell_exec { |
|
41 |
my ($cmd) = @_; |
|
42 |
blab "executing `$cmd'"; |
|
43 |
system($cmd); |
|
44 |
if ($? == -1) { |
|
45 |
fatal "failed to execute: $!"; |
|
46 |
} elsif ($? & 127) { |
|
47 |
fatal (printf "child died with signal %d, %s coredump", |
|
48 |
($? & 127), ($? & 128) ? 'with' : 'without') |
|
49 |
} else { |
|
50 |
my $rc = $? >> 8; |
|
51 |
if ($rc != 0) { |
|
52 |
warning "child exited with value $rc"; |
|
53 |
} |
|
54 |
} |
|
55 |
} |
|
56 |
sub write_file { |
|
57 |
my ($filename, $content) = @_; |
|
58 |
blab "Writing file `$filename'"; |
|
59 |
if (open FD, '>', $filename) { |
|
60 |
print FD $content; |
|
61 |
close FD; |
|
62 |
} else { |
|
63 |
fatal "Can't write to file `$filename': $!" |
|
64 |
} |
|
65 |
} |
|
66 |
sub get_output { |
|
67 |
my ($cmd) = @_; |
|
68 |
blab "absorbing `$cmd'"; |
|
69 |
if (open OUT, "$cmd |") { |
|
70 |
my @lines = <OUT>; |
|
71 |
close OUT; |
|
72 |
chomp @lines; |
|
73 |
warning "Empty output from `$cmd'" unless @lines; |
|
74 |
return \@lines; |
|
75 |
} else { |
|
76 |
fatal "Can't execute `$cmd': $!" |
|
77 |
} |
|
78 |
} |
|
79 |
sub get_output_line { |
|
80 |
return (@{get_output @_})[0]; |
|
81 |
} |
|
82 |
||
83 |
sub trim { |
|
84 |
# works with refs: |
|
85 |
$$_ =~ s/^\s*(.*)\s*$/$1/ foreach @_; |
|
86 |
} |
|
87 |
||
88 |
||
89 |
||
90 |
||
91 |
my $pyversion = get_output_line 'python --version 2>&1'; |
|
92 |
if ($pyversion =~ /Python +(\d)\.(\d)\..+/) { |
|
93 |
$pyversion = "$1$2"; |
|
94 |
blab "Python: $pyversion" |
|
95 |
} else { |
|
96 |
fatal "Can't parse Python version" |
|
97 |
} |
|
98 |
||
99 |
foreach my $pkg (@ARGV) { |
|
100 |
# http://pypi.python.org/packages/source/T/TurboKid/TurboKid-1.0.5.tar.gz#md5=ba70daf5aa7121affdea8e7632a3b353 |
|
101 |
$pkg = (split /#/, $pkg)[0]; |
|
102 |
||
103 |
my $archive = basename $pkg; |
|
104 |
my $url_dir = dirname $pkg; |
|
105 |
blab "Working on $pkg"; |
|
106 |
||
107 |
my ($pkg_name, $pkg_version, $arch); |
|
108 |
if ($archive =~ /^(.+)-([^-]+)\.(tar\..+|zip)$/) { |
|
109 |
$pkg_name = $1; |
|
110 |
$pkg_version = $2; |
|
111 |
$arch = $3; |
|
112 |
} else { |
|
113 |
fatal "Can't parse archive name: $archive" |
|
114 |
} |
|
115 |
||
464
c51702debae2
cpan2ips.pl, py2ips.pl: replace "_" by "-" in package names; added Nexenta copyrights
Igor Pashev <igor.pashev@nexenta.com>
parents:
462
diff
changeset
|
116 |
$pkg_name =~ s/_/-/g; |
459 | 117 |
my $pkg_name_lc = lc $pkg_name; |
118 |
blab "Package name: $pkg_name"; |
|
119 |
||
120 |
||
121 |
my_mkdir $pkg_name_lc; |
|
122 |
my_chdir $pkg_name_lc; |
|
123 |
||
124 |
my_mkdir '__srcdir__'; |
|
125 |
my_chdir '__srcdir__'; |
|
126 |
shell_exec qq/wget -O "$archive" "$pkg"/; |
|
127 |
my $sha1sum = get_output_line qq/sha1sum "$archive" | cut -d ' ' -f 1/; |
|
128 |
||
129 |
if ($arch =~ /zip/) { |
|
130 |
shell_exec qq/unzip "$archive"/; |
|
131 |
fatal "Can't find sources (from zip)" unless -d "${pkg_name}-${pkg_version}"; |
|
132 |
shell_exec "mv ${pkg_name}-${pkg_version}/* ."; |
|
133 |
} else { |
|
134 |
shell_exec qq/tar xf "$archive" --strip-component 1/ |
|
135 |
} |
|
136 |
shell_exec qq/python setup.py egg_info/; |
|
137 |
||
138 |
||
139 |
||
140 |
my_chdir '../__srcdir__'; |
|
141 |
shell_exec qq!python setup.py install --root=../__destdir__ --prefix=/usr !; |
|
142 |
||
143 |
# FIXME: versions (kid >= 0.9.6) |
|
144 |
my @pkg_deps = (); |
|
145 |
if ( -f "$pkg_name.egg-info/requires.txt") { |
|
146 |
@pkg_deps = |
|
147 |
map { s/^([-\w]+).*/$1/; lc $_ } |
|
148 |
grep { /^\w/ } |
|
149 |
@{get_output "cat $pkg_name.egg-info/requires.txt"} |
|
150 |
} |
|
151 |
blab "Dependencies: ", (join ', ', @pkg_deps); |
|
152 |
||
153 |
my $pkg_summary = ''; |
|
154 |
for my $dir ( ("$pkg_name.egg-info", '.') ) { |
|
155 |
if ( -f "$dir/PKG-INFO") { |
|
156 |
$pkg_summary = get_output_line "grep Summary: $dir/PKG-INFO | sed 's/Summary: *//'"; |
|
157 |
last; |
|
158 |
} |
|
159 |
} |
|
160 |
my_chdir '..'; |
|
161 |
$pkg_summary =~ s/\.+$//; |
|
162 |
||
163 |
my $ips_manifest = <<MANIFEST; |
|
164 |
<transform file path=usr.*/man/.+ -> default mangler.man.stability uncommitted> |
|
165 |
set name=pkg.fmri value=pkg:/library/python-2/${pkg_name_lc}-$pyversion@\$(IPS_COMPONENT_VERSION),\$(BUILD_VERSION) |
|
166 |
set name=info.classification value="org.opensolaris.category.2008:Development/Python" |
|
167 |
set name=pkg.summary value="$pkg_summary" |
|
168 |
MANIFEST |
|
169 |
$ips_manifest .= "\n"; |
|
170 |
||
171 |
$ips_manifest .= "depend fmri=pkg:/runtime/python-$pyversion type=require\n"; |
|
172 |
$ips_manifest .= "depend fmri=pkg:/library/python-2/${_}-$pyversion type=require\n" |
|
173 |
foreach @pkg_deps; |
|
174 |
||
175 |
$ips_manifest .= "\n"; |
|
176 |
||
177 |
$ips_manifest .= join "\n", |
|
178 |
(map { s![^/]+-packages!vendor-packages!; $_ } |
|
179 |
@{get_output |
|
180 |
"cd __destdir__ && \ |
|
181 |
gfind * -type d -printf 'dir path=%p\\n' \ |
|
182 |
gfind * -type f -printf 'file path=%p\\n' \ |
|
183 |
gfind * -type l -printf 'link path=%p target=%l\\n' \ |
|
184 |
"}); |
|
185 |
||
186 |
$ips_manifest .= "\n"; |
|
187 |
||
188 |
my $makefile = <<MAKEFILE; |
|
189 |
include ../../../make-rules/shared-macros.mk |
|
190 |
COMPONENT_NAME = $pkg_name |
|
191 |
COMPONENT_VERSION = $pkg_version |
|
192 |
COMPONENT_SRC = \$(COMPONENT_NAME)-\$(COMPONENT_VERSION) |
|
193 |
COMPONENT_ARCHIVE = \$(COMPONENT_SRC).$arch |
|
194 |
COMPONENT_ARCHIVE_HASH = sha1:$sha1sum |
|
195 |
COMPONENT_ARCHIVE_URL = $url_dir/\$(COMPONENT_ARCHIVE) |
|
196 |
||
197 |
include \$(WS_TOP)/make-rules/prep.mk |
|
198 |
include \$(WS_TOP)/make-rules/ips.mk |
|
199 |
include \$(WS_TOP)/make-rules/setup.py.mk |
|
200 |
||
201 |
build: \$(BUILD_32) |
|
202 |
install: \$(INSTALL_32) |
|
203 |
||
204 |
COMPONENT_TEST_TARGETS = test |
|
205 |
test: \$(TEST_32) |
|
206 |
||
207 |
BUILD_PKG_DEPENDENCIES = \$(BUILD_TOOLS) |
|
208 |
||
209 |
include \$(WS_TOP)/make-rules/depend.mk |
|
210 |
||
211 |
MAKEFILE |
|
212 |
||
213 |
shell_exec "rm -rf __srcdir__ __destdir__"; |
|
214 |
||
215 |
write_file "$pkg_name_lc-$pyversion.p5m", $ips_manifest; |
|
216 |
write_file 'Makefile', $makefile; |
|
217 |
||
218 |
my_chdir '..'; |
|
219 |
} |
|
220 |
||
221 |
exit 0; |
|
222 |