Skip to content

Commit 5612ab1

Browse files
committed
spec-cleaner perl version is out of date for years, rewrite it to python3
1 parent 9b398c6 commit 5612ab1

1 file changed

Lines changed: 63 additions & 326 deletions

File tree

spec-cleaner

Lines changed: 63 additions & 326 deletions
Original file line numberDiff line numberDiff line change
@@ -1,328 +1,65 @@
1-
#!/usr/bin/perl
2-
#
3-
# A script to clean up spec files and bring them closer to ROSA packaging policies
4-
#
5-
# Author: Denis Silakov, ROSA, denis.silakov@rosalab.com
6-
#
7-
8-
$spec = $ARGV[0];
9-
$newspec = $ARGV[1];
10-
11-
use Env qw(SPEC_LEAVE_CHANGELOG);
12-
13-
$pkgname = $spec;
14-
$pkgname =~ s/\.spec$//;
15-
16-
if (!$newspec) {
17-
$newspec = $spec.".tmp";
18-
}
19-
20-
if (@ARGV < 1) {
21-
die "Usage: $0 OLD_SPEC [NEW_SPEC]";
22-
}
23-
24-
$changelog = 0;
25-
26-
# List of macros known to be variables, so they should be embraced with '{}'
27-
my @vars = (
28-
'name',
29-
'version',
30-
'release',
31-
'eposh',
32-
'EVRD',
33-
'py_ver',
34-
'buildroot',
35-
'optflags',
36-
'ldflags',
37-
'build_ldflags',
38-
'_bindir',
39-
'_libdir',
40-
'rlibdir',
41-
'_sbindir',
42-
'_mandir',
43-
'_datadir',
44-
'_sysconfdir',
45-
'_webappconfdir',
46-
'_webconfdir',
47-
'_jvmcommonsysconfdir',
48-
'_jvmsysconfdir',
49-
'_mavendepmapfragdir',
50-
'_mavendepmapdir',
51-
'_initddir',
52-
'_sys_macros_dir',
53-
'_systemdconfdir',
54-
'_systemdrootdir',
55-
'_systemgeneratordir',
56-
'_systemshutdowndir',
57-
'_systemunitdir',
58-
'_unitdir',
59-
'_userunitdir',
60-
'_sharedstatedir',
61-
'_desktopdir',
62-
'_gamesbindir',
63-
'_includedir',
64-
'firefox_pluginsdir',
65-
'_jnidir',
66-
'_jvmcommonlibdir',
67-
'_jvmjardir',
68-
'_jvmdir',
69-
'_jvmprivdir',
70-
'_kde_plugindir',
71-
'_menudir',
72-
'_qt_bindir',
73-
'_qt_demodir',
74-
'_qt_exampledir',
75-
'_qt_importdir',
76-
'qt4include',
77-
'_qt_includedir',
78-
'qt4plugins',
79-
'_qt_plugindir',
80-
'qt4dir',
81-
'_qt_translationdir',
82-
'_systemdlibexecdir',
83-
'tcl_sitearch',
84-
'_usergeneratordir',
85-
'sampler_libdir',
86-
'_kde_applicationsdir',
87-
'_kde_appsdir',
88-
'_kde_configdir',
89-
'_qt_docdir',
90-
'_lispdir',
91-
'_xfontdir',
92-
'_gamesdatadir',
93-
'_icons16dir',
94-
'_icons192dir',
95-
'_icons22dir',
96-
'_icons48dir',
97-
'_icons64dir',
98-
'_icons96dir',
99-
'_iconsbasedir',
100-
'_iconsscaldir',
101-
'_iconsdir',
102-
'_liconsdir',
103-
'_miconsdir',
104-
'_infodir',
105-
'_javadocdir',
106-
'_javadir',
107-
'_jvmcommondatadir',
108-
'_jvmdatadir',
109-
'_localedir',
110-
'_mavenpomdir',
111-
'php_pear_dir',
112-
'_rpm_helper_dir',
113-
'_spec_helper_dir',
114-
'_systemddatadir',
115-
'_userunitdir',
116-
'_prefix',
117-
'tcl_sitelib',
118-
'_filetriggers_dir',
119-
'_localstatedir',
120-
'_logdir',
121-
'_repackage_dir',
122-
'ruby_gemdir',
123-
'ruby_ridir',
124-
'ruby_libdir',
125-
'ruby_sitelibdir',
126-
'ruby_vendorlibdir',
127-
'ruby_sitedir',
128-
'ruby_vendordir',
129-
'py3_platsitedir',
130-
'py3_platlibdir',
131-
'py3_incdir',
132-
'py_incdir',
133-
'py_platsitedir',
134-
'py_platlibdir',
135-
'py_dyndir',
136-
'py_puresitedir',
137-
'py_purelibdir',
138-
'py3_puresitedir',
139-
'py3_purelibdir',
140-
'perl_archlib',
141-
'perl_privlib',
142-
'perl_sitearch',
143-
'perl_sitelib',
144-
'perl_vendorarch',
145-
'perl_vendorlib',
146-
'perl_version',
147-
148-
);
149-
150-
my @macros = (
151-
'make',
152-
'make_build',
153-
'make_install',
154-
'makeinstall_std',
155-
'configure',
156-
'configure2_5x',
157-
158-
);
159-
160-
my @macros_to_unroll = (
161-
'__mkdir_p',
162-
'__mkdir',
163-
'__ln_s',
164-
'__ln',
165-
'__mv',
166-
'__perl',
167-
'__python',
168-
'__python3',
169-
'__rm',
170-
'__rmdir',
171-
'__ruby',
172-
'__cp',
173-
'__grep',
174-
'__cat',
175-
'__chmod',
176-
'__chown',
177-
'__install',
178-
179-
);
180-
181-
# Indicates that we are inside post- or pre- script
182-
$in_script=0;
183-
184-
open(F, $spec);
185-
open(G, "> $newspec");
186-
while(<F>) {
187-
if( /^BuildRoot:/i or /^Packager:/i ) {
188-
next;
189-
}
190-
191-
# Obsolete
192-
if( /^(Build)?Requires(\(.*\))?:\s*info-install\s*$/i ) {
193-
next;
194-
}
195-
196-
$line = $_;
197-
198-
# Captitalize summary and drop dot from its end, if any
199-
if( $line =~ /^(%define\s*)?Summary:\s*(\S+)/i ) {
200-
$word = $2;
201-
$word_old = $word;
202-
$word =~ s/(^[a-z])/\u$1/;
203-
if( $word_old !~ /^$pkgname/ ) {
204-
$line =~ s/Summary:(\s*)$word_old/Summary:$1$word/;
205-
} else {
206-
print STDERR "Won't capitalize summary - it starts with project name\n";
207-
}
208-
209-
chomp $line;
210-
if( $line =~ /\.\s*$/ ) {
211-
$line =~ s/\.\s*$//;
212-
}
213-
print G $line."\n";
214-
next;
215-
}
216-
217-
if( /^%changelog/i ) {
218-
$changelog = 1;
219-
# By default, we drop changelogs from specs
220-
# nowadays changelogs are generated from Git
221-
# and most spec files contains only ancient changelog entries
222-
if( !$SPEC_LEAVE_CHANGELOG ) {
223-
last;
224-
}
225-
}
226-
227-
if( $changelog or /\s*#/) {
228-
print G $line;
229-
next;
230-
}
231-
232-
if( $line =~ /^\%defattr\(-,root,root(,-)?\)\s*$/ ) {
233-
next;
234-
}
235-
236-
$line =~ s/\$\{?RPM_BUILD_ROOT\}?/\%\{buildroot\}/g;
237-
$line =~ s/\$\{?RPM_OPT_FLAGS\}?/\%\{optflags\}/g;
238-
239-
if( $line =~/^\s*(\%\{?__rm\}?|rm) -rf \%\{?buildroot\}?\s*$/ ) {
240-
next;
241-
}
242-
243-
$line =~ s/\%mkrel\s+//;
244-
$line =~ s/\%\{\?dist\}//;
245-
$line =~ s/make \%\{\?_smp_mflags\}/\%make_build/;
246-
$line =~ s/\%make test/\make test/;
247-
248-
# Cleanup old grep usage
249-
$line =~ s/fgrep/grep -F/g;
250-
$line =~ s/egrep/grep -E/g;
251-
252-
# Clean up obsolete macro usage
253-
$line =~ s/({|%)webappconfdir/$1_webappconfdir/g;
254-
$line =~ s/({|%)py_libdir/$1py_purelibdir/g;
255-
$line =~ s/({|%)py_sitedir/$1py_puresitedir/g;
256-
$line =~ s/({|%)python_sitearch/$1py_platsitedir/g;
257-
$line =~ s/({|%)python_sitelib/$1py_puresitedir/g;
258-
$line =~ s/({|%)python3_sitearch/$1py3_platsitedir/g;
259-
$line =~ s/({|%)python3_sitelib/$1py3_puresitedir/g;
260-
$line =~ s/({|%)python_version/$1py_ver/g;
261-
$line =~ s/({|%)pyver/$1py_ver/g;
262-
$line =~ s/\%py_requires -d/BuildRequires: pkgconfig\(python\)/;
263-
264-
foreach $var (@vars) {
265-
$line =~ s/\%$var/\%\{$var\}/g;
266-
}
267-
268-
foreach $macro (@macros) {
269-
$line =~ s/\%\{$macro\}/\%$macro/g;
270-
$line =~ s/\%\{__$macro\}/\%$macro/g;
271-
}
272-
273-
foreach $macro (@macros_to_unroll) {
274-
my $repl = $macro;
275-
$repl =~ s/^__//;
276-
$repl =~ s/_/ -/;
277-
$line =~ s/\%\{?$macro\}?/$repl/g;
278-
}
279-
280-
foreach my $cmd ('mv', 'cp', 'python', 'rm') {
281-
$line =~ s/\%\{_?_?$cmd\}/$cmd/g;
282-
}
283-
284-
# Drop definitions of %name, %version and %release
285-
if( /\%define\s+name\s+(.+)$/ ) {
286-
$name = $1;
287-
next;
288-
}
289-
290-
if( /\%define\s+version\s+(.+)$/ ) {
291-
$version = $1;
292-
next;
293-
}
294-
295-
if( /\%define\s+release\s+(.+)$/ ) {
296-
$release = $1;
297-
next;
298-
}
299-
300-
# If Name, Version or Release are defined using %name, %version and %relese macros
301-
# replace macros with their values
302-
# (manual definition of these macros is obsolete and not needed, they are get defined
303-
# automatically on the basis of Name, Version and Release tags)
304-
if( /^Name:(\s+)\%\{?name\}?$/ ) {
305-
print G "Name:$1$name\n";
306-
next;
307-
}
308-
309-
if( /^Version:(\s+)\%\{?version\}?$/ ) {
310-
print G "Version:$1$version\n";
311-
next;
312-
}
313-
314-
if( /^Release:(\s+)\%\{?release\}?$/ ) {
315-
print G "Release:$1$release\n";
316-
next;
317-
}
318-
319-
print G $line;
1+
#!/usr/bin/env python3
2+
3+
import re
4+
import sys
5+
6+
# Dictionary of macros to replace: key is the macro, value is its replacement
7+
MACROS_TO_REPLACE = {
8+
r'%make\b': '%make_build',
9+
r'%makeinstall_std\b': '%make_install',
10+
r'%configure2_5x\b': '%configure',
11+
r'%apply_patches\b': '%autopatch -p1',
12+
r'\$\{?RPM_BUILD_ROOT\}?': '%{buildroot}',
13+
# Add more macros here as needed
14+
# Example:
15+
# r'%old_macro\b': '%new_macro',
32016
}
32117

322-
# newspec was not specified in command line,
323-
# so we are using temoporary file; now let's move it
324-
# to original one
325-
if (!$ARGV[1]) {
326-
system "cat $newspec > $spec";
327-
system "rm -f $newspec";
328-
}
18+
def replace_macros_and_clean(file_path):
19+
try:
20+
# Read the file content
21+
with open(file_path, 'r') as file:
22+
original_content = file.read()
23+
content = original_content
24+
25+
# Track changes
26+
changes = []
27+
28+
# Replace macros using the dictionary
29+
for old_macro, new_macro in MACROS_TO_REPLACE.items():
30+
# Use regex to replace only whole macros
31+
new_content, count = re.subn(old_macro, new_macro, content)
32+
if count > 0:
33+
changes.append(f"Replaced '{old_macro}' with '{new_macro}' {count} times")
34+
content = new_content
35+
36+
# Remove trailing spaces from each line
37+
lines = content.splitlines()
38+
cleaned_lines = [line.rstrip() for line in lines]
39+
cleaned_content = "\n".join(cleaned_lines) + "\n" # Ensure trailing newline
40+
41+
# Check if trailing spaces were removed
42+
if cleaned_content != content:
43+
changes.append("Removed trailing spaces from all lines")
44+
45+
# Check if any changes were made
46+
if changes:
47+
# Write the modified content back to the file
48+
with open(file_path, 'w') as file:
49+
file.write(cleaned_content)
50+
print(f"Changes in file '{file_path}':")
51+
for change in changes:
52+
print(f" - {change}")
53+
else:
54+
print(f"Nothing to clean in file '{file_path}'.")
55+
except FileNotFoundError:
56+
print(f"Error: File '{file_path}' not found.")
57+
except Exception as e:
58+
print(f"An error occurred: {e}")
59+
60+
if __name__ == "__main__":
61+
if len(sys.argv) != 2:
62+
print("Usage: /usr/bin/spec-cleaner foo.spec")
63+
else:
64+
file_path = sys.argv[1]
65+
replace_macros_and_clean(file_path)

0 commit comments

Comments
 (0)