11#include " helpers.hpp"
22#include " specfile.hpp"
33#include " installedrpm.hpp"
4+ #include " standalonerpm.hpp"
45#include " dependencyset.hpp"
56
67#include < iostream>
78#include < fstream>
89#include < filesystem>
910#include < optional>
1011
12+ #include < rpm/header.h>
1113#include < rpm/rpmcli.h>
1214#include < rpm/rpmdb.h>
1315#include < rpm/rpmds.h>
@@ -37,11 +39,42 @@ using std::filesystem::path;
3739
3840namespace fs = std::filesystem;
3941
42+ static char * inputdir = NULL ;
43+ static char * outputdir = NULL ;
44+ static char * gitrootdir = NULL ;
45+
4046static struct poptOption optionsTable[] = {
4147 {
4248 NULL , ' \0 ' , POPT_ARG_INCLUDE_TABLE, rpmcliAllPoptTable, 0 ,
4349 " Common options for all rpm modes and executables" ,
4450 NULL },
51+ {
52+ " inputdir" ,
53+ ' i' ,
54+ POPT_ARG_STRING,
55+ &inputdir,
56+ 0 ,
57+ " Input directory where SRPM packages may be found" ,
58+ NULL
59+ },
60+ {
61+ " outputdir" ,
62+ ' o' ,
63+ POPT_ARG_STRING,
64+ &outputdir,
65+ 0 ,
66+ " Output directory where SRPM and RPM files will be placed" ,
67+ NULL
68+ },
69+ {
70+ " gitroot" ,
71+ ' g' ,
72+ POPT_ARG_STRING,
73+ &gitrootdir,
74+ 0 ,
75+ " RSE git repository directory containing releasepackages.lst" ,
76+ NULL
77+ },
4578 POPT_AUTOALIAS
4679 POPT_AUTOHELP
4780 POPT_TABLEEND
@@ -59,6 +92,60 @@ optional<string> calculate_expected_specfile_path( string sgug_rse_git_root,
5992 }
6093}
6194
95+ optional<string> find_srpm_for_package ( bool verbose,
96+ string sgug_rse_srpm_archive_root,
97+ string srpm_name )
98+ {
99+ path candidate_path = std::filesystem::path (sgug_rse_srpm_archive_root);
100+ if ( verbose ) {
101+ cout << " # Looking for " << srpm_name << " under " << candidate_path << endl;
102+ }
103+ if ( fs::exists (candidate_path) && fs::is_directory (candidate_path)) {
104+ vector<path> candidates;
105+ for ( const auto & entry : fs::directory_iterator (candidate_path)) {
106+ path entry_path = entry.path ();
107+ string entry_filename = entry_path.filename ();
108+ // if( verbose ) {
109+ // cout << "# Looking for " << srpm_name << " at " << entry_filename <<
110+ // endl;
111+ // }
112+ if ((!fs::is_directory (entry_path)) &&
113+ sgug_rpm::str_starts_with (entry_filename,srpm_name) &&
114+ sgug_rpm::str_ends_with (entry_filename, " .src.rpm" ) ) {
115+ candidates.push_back (entry_path);
116+ if ( verbose ) {
117+ cout << " # Found candidate: " << entry_filename << endl;
118+ }
119+ }
120+
121+ }
122+ if (candidates.size () > 0 ) {
123+ for ( const path & cp : candidates ) {
124+ sgug_rpm::standalonerpm sarpm;
125+ string canonical_filename = fs::canonical (cp);
126+ if ( sgug_rpm::read_standalonerpm ( verbose, canonical_filename,
127+ sarpm ) ) {
128+ if ( sarpm.get_name () == srpm_name ) {
129+ return {cp.filename ()};
130+ }
131+ else if (verbose) {
132+ cout << " # Examined " << canonical_filename <<
133+ " but failed match of package name" << endl;
134+ }
135+ }
136+ else if (verbose) {
137+ cerr << " # Couldn't open " << canonical_filename << endl;
138+ }
139+ }
140+ }
141+
142+ return {};
143+ }
144+ else {
145+ return {};
146+ }
147+ }
148+
62149int main (int argc, char **argv)
63150{
64151 vector<sgug_rpm::specfile> valid_specfiles;
@@ -71,17 +158,40 @@ int main(int argc, char**argv)
71158 exit (EXIT_FAILURE);
72159 }
73160
161+ // Check we have outputdir and gitrootdir
162+ if ( inputdir == NULL || outputdir == NULL || gitrootdir == NULL ) {
163+ cerr << " inputdir, outputdir and gitrootdir must be passed" << endl;
164+ exit (EXIT_FAILURE);
165+ }
166+ path inputdir_p = {inputdir};
167+ path outputdir_p = {outputdir};
168+ path gitrootdir_p = {gitrootdir};
169+
74170 bool verbose = popt_context.verbose ;
75171
76172 sgug_rpm::progress_printer pprinter;
77173
174+ path inputsrpm_p = inputdir_p;
175+ path buildprogress_p = outputdir_p / " PROGRESS" ;
176+ path outputsrpm_p = outputdir_p / " SRPMS" ;
177+ path outputrpm_p = outputdir_p / " RPMS" ;
178+
179+ /*
78180 string sgug_rse_git_root = "/usr/people/dan/Sources/GitClones/sgug-rse.git";
79- string sgug_rse_srpm_archive_root = " /usr/people/dan/Temp/srpmfetches0.0.6" ;
181+ string build_progress_dir = "/usr/people/dan/Temp/build0.0.6round2/PROGRESS";
182+ string sgug_rse_srpm_archive_root = "/usr/people/dan/Temp/build0.0.6round1/SRPMS";
183+ string sgug_rse_srpm_output_root = "/usr/people/dan/Temp/build0.0.6round2/SRPMS";
184+ string sgug_rse_rpm_output_root = "/usr/people/dan/Temp/build0.0.6round2/RPMS";
185+ */
80186
81187 cout << " # Reading spec files..." << endl;
82188
189+ std::ifstream input ( fs::canonical (gitrootdir_p / " releasepackages.lst" ) );
190+
191+
192+ vector<string> names_in;
83193 string curline;
84- for ( string line; std::getline (cin , line); ) {
194+ for ( string line; std::getline (input , line); ) {
85195 // Skip comments + empty lines
86196 if ( line.length () == 0 || line[0 ] == ' #' ) {
87197 continue ;
@@ -90,12 +200,16 @@ int main(int argc, char**argv)
90200 // a) a specfile
91201 // b) an SRPM we can install that matches
92202 string package_name = line;
203+ names_in.push_back (package_name);
204+ }
205+
206+ for ( string & package_name : names_in ) {
93207 optional<string> expected_specfile_path_opt =
94- calculate_expected_specfile_path ( sgug_rse_git_root ,
208+ calculate_expected_specfile_path ( gitrootdir_p ,
95209 package_name );
96210 if ( !expected_specfile_path_opt ) {
97211 cerr << " Missing spec for " << package_name << endl;
98- cerr << " Looked under " << sgug_rse_git_root << " /packages/" <<
212+ cerr << " Looked under " << gitrootdir_p << " /packages/" <<
99213 package_name << " /SPECS/" << package_name << " .spec" << endl;
100214 exit (EXIT_FAILURE);
101215 }
@@ -114,6 +228,8 @@ int main(int argc, char**argv)
114228 else {
115229 failed_specfiles.push_back ( package_name );
116230 }
231+ // Quick hack while testing, only do the first one
232+ // break;
117233 }
118234
119235 size_t num_specs = valid_specfiles.size ();
@@ -136,35 +252,25 @@ int main(int argc, char**argv)
136252 for ( const string & failed_fn : failed_specfiles ) {
137253 cout<< " # " << failed_fn << endl;
138254 }
255+ exit (EXIT_FAILURE);
139256 }
140257
141- exit (1 );
142- // GOT HERE
143-
144- // Now we work out for each of the rpms
145- // (a) If such an RPM is installed
258+ vector<sgug_rpm::specfile> specs_to_rebuild = valid_specfiles;
146259
147- vector<sgug_rpm::specfile> specs_to_rebuild;
260+ cout << " # Checking availability of SRPMs for packages..." << endl;
261+ unordered_map<string,string> package_to_srpm_map;
148262
149- cout << " # Checking for installed packages and dependencies..." << endl;
150-
151- for ( const sgug_rpm::specfile & specfile: valid_specfiles ) {
152- // cout << "# Walking spec " << specfile.get_name() << endl;
153- size_t num_valid_rpms = 0 ;
154- bool found_installed_package = false ;
155- for ( const string & pkg : specfile.get_packages () ) {
156- sgug_rpm::installedrpm foundrpm;
157- bool valid_rpm = sgug_rpm::read_installedrpm ( verbose, pkg, foundrpm );
158- if ( valid_rpm ) {
159- found_installed_package = true ;
160- }
161- }
162- pprinter.accept_progress ();
163- if ( found_installed_package ) {
164- specs_to_rebuild.emplace_back (specfile);
263+ for ( const sgug_rpm::specfile & specfile : valid_specfiles ) {
264+ const string & srpm_name = specfile.get_name ();
265+ cout << " # Looking for srpm " << srpm_name << endl;
266+ optional<string> found_srpm_opt =
267+ find_srpm_for_package ( verbose, inputsrpm_p, srpm_name );
268+ if ( !found_srpm_opt ) {
269+ cerr << " Unable to find SRPM for " << srpm_name << endl;
270+ exit (EXIT_FAILURE);
165271 }
272+ package_to_srpm_map[srpm_name] = *found_srpm_opt;
166273 }
167- pprinter.reset ();
168274
169275 cout << " # Writing worldrebuilder.sh..." << endl;
170276
@@ -178,21 +284,96 @@ int main(int argc, char**argv)
178284 worldrebuilderfile.open (" worldrebuilder.sh" );
179285 worldrebuilderfile << " #!/usr/sgug/bin/bash" << endl;
180286 worldrebuilderfile << " # This script should be run as your user!" << endl;
181- worldrebuilderfile << " mkdir -p ~/rpmbuild/PROGRESS" << endl;
287+ worldrebuilderfile << " echo 'This script is SUPER DESTRUCTIVE.'" << endl;
288+ worldrebuilderfile << " echo 'So you must edit it which confirms you'" << endl;
289+ worldrebuilderfile << " echo 'agree with what it will do.'" << endl;
290+ worldrebuilderfile << " exit 1" << endl;
291+ worldrebuilderfile << " # Some useful variables" << endl;
292+ worldrebuilderfile << " build_progress_dir=" << buildprogress_p << endl;
293+ worldrebuilderfile << " sgug_rse_srpm_archive_root=" << inputsrpm_p << endl;
294+ worldrebuilderfile << " sgug_rse_git_root=" << gitrootdir_p << endl;
295+ worldrebuilderfile << " sgug_rse_srpm_output_root=" << outputsrpm_p << endl;
296+ worldrebuilderfile << " sgug_rse_rpm_output_root=" << outputrpm_p << endl;
297+
298+ worldrebuilderfile << " ORIG_WD=`pwd`" << endl;
299+ worldrebuilderfile << " cleanUpDirs () {" << endl;
300+ worldrebuilderfile << " rm -rf ~/rpmbuild" << endl;
301+ worldrebuilderfile << " mkdir -p ~/rpmbuild/BUILD" << endl;
302+ worldrebuilderfile << " mkdir -p ~/rpmbuild/BUILDROOT" << endl;
303+ worldrebuilderfile << " mkdir -p ~/rpmbuild/RPMS" << endl;
304+ worldrebuilderfile << " mkdir -p ~/rpmbuild/SOURCES" << endl;
305+ worldrebuilderfile << " mkdir -p ~/rpmbuild/SPECS" << endl;
306+ worldrebuilderfile << " mkdir -p ~/rpmbuild/SRPMS" << endl;
307+ worldrebuilderfile << " mkdir -p $build_progress_dir" << endl;
308+ worldrebuilderfile << " mkdir -p $sgug_rse_srpm_output_root" << endl;
309+ worldrebuilderfile << " mkdir -p $sgug_rse_rpm_output_root/noarch" << endl;
310+ worldrebuilderfile << " mkdir -p $sgug_rse_rpm_output_root/mips" << endl;
311+ worldrebuilderfile << " }" << endl;
312+ worldrebuilderfile << " installSrpm () {" << endl;
313+ worldrebuilderfile << " packageSrpmfile=$1" << endl;
314+ worldrebuilderfile << " rpm -ivh $packageSrpmfile" << endl;
315+ worldrebuilderfile << " }" << endl;
316+ worldrebuilderfile << " copySgugGitPackage () {" << endl;
317+ worldrebuilderfile << " sgugGitPackageRoot=$1" << endl;
318+ worldrebuilderfile << " cp -r $sgugGitPackageRoot/* ~/rpmbuild/" << endl;
319+ worldrebuilderfile << " }" << endl;
320+ worldrebuilderfile << " rpmbuildPackage () {" << endl;
321+ worldrebuilderfile << " packageName=$1" << endl;
322+ worldrebuilderfile << " cd ~/rpmbuild/SPECS" << endl;
323+ worldrebuilderfile << " rpmbuild -ba \" $packageName.spec\" --nocheck" << endl;
324+ worldrebuilderfile << " rpmrc=$?" << endl;
325+ worldrebuilderfile << " cd $ORIG_WD" << endl;
326+ worldrebuilderfile << " return $rpmrc" << endl;
327+ worldrebuilderfile << " }" << endl;
328+ worldrebuilderfile << " archiveBuiltArtefacts () {" << endl;
329+ worldrebuilderfile << " mv ~/rpmbuild/SRPMS/* $sgug_rse_srpm_output_root/" << endl;
330+ worldrebuilderfile << " if [[ -e ~/rpmbuild/RPMS/noarch ]]; then" << endl;
331+ worldrebuilderfile << " mv ~/rpmbuild/RPMS/noarch/* $sgug_rse_rpm_output_root/noarch/" << endl;
332+ worldrebuilderfile << " fi" << endl;
333+ worldrebuilderfile << " if [[ -e ~/rpmbuild/RPMS/mips ]]; then" << endl;
334+ worldrebuilderfile << " mv ~/rpmbuild/RPMS/mips/* $sgug_rse_rpm_output_root/mips/" << endl;
335+ worldrebuilderfile << " fi" << endl;
336+ worldrebuilderfile << " }" << endl;
337+ worldrebuilderfile << " doPackageBuild () {" << endl;
338+ worldrebuilderfile << " packageName=$1" << endl;
339+ worldrebuilderfile << " packageSrpm=$2" << endl;
340+ worldrebuilderfile << " startedFilename=\" $build_progress_dir/$packageName.started\" " << endl;
341+ worldrebuilderfile << " failedFilename=\" $build_progress_dir/$packageName.failed\" " << endl;
342+ worldrebuilderfile << " successFilename=\" $build_progress_dir/$packageName.success\" " << endl;
343+ worldrebuilderfile << " if [[ -e $startedFilename ]]; then" << endl;
344+ worldrebuilderfile << " echo \" $packageName was previously started. Skipping.\" " << endl;
345+ worldrebuilderfile << " else" << endl;
346+ worldrebuilderfile << " cleanUpDirs" << endl;
347+ worldrebuilderfile << " touch $startedFilename" << endl;
348+ worldrebuilderfile << " installSrpm \" $sgug_rse_srpm_archive_root/$packageSrpm\" " << endl;
349+ worldrebuilderfile << " copySgugGitPackage \" $sgug_rse_git_root/packages/$packageName\" " << endl;
350+ worldrebuilderfile << " rpmbuildPackage \" $packageName\" " << endl;
351+ worldrebuilderfile << " packageBuildStatus=$?" << endl;
352+ worldrebuilderfile << " if [[ $packageBuildStatus -ne 0 ]]; then" << endl;
353+ worldrebuilderfile << " touch $failedFilename" << endl;
354+ worldrebuilderfile << " else" << endl;
355+ worldrebuilderfile << " archiveBuiltArtefacts" << endl;
356+ worldrebuilderfile << " touch $successFilename" << endl;
357+ worldrebuilderfile << " fi" << endl;
358+ worldrebuilderfile << " fi" << endl;
359+ worldrebuilderfile << " }" << endl;
360+ worldrebuilderfile << " # The package list..." << endl;
182361
183362 for ( const sgug_rpm::specfile & spec : specs_to_rebuild ) {
184363 const string & name = spec.get_name ();
185- worldrebuilderfile << " # Must rebuild: " << name << endl;
186- worldrebuilderfile << " touch ~/rpmbuild/PROGRESS/" << name << " .start" <<
187- endl;
188- worldrebuilderfile << " rpmbuild -ba " << name << " .spec --nocheck" <<
189- endl;
190- worldrebuilderfile << " if [[ $? -ne 0 ]]; then" << endl;
191- worldrebuilderfile << " touch ~/rpmbuild/PROGRESS/" << name <<
192- " .failed" << endl;
193- worldrebuilderfile << " fi" << endl;
194- worldrebuilderfile << " touch ~/rpmbuild/PROGRESS/" << name << " .done" <<
195- endl;
364+ const string & srpm = package_to_srpm_map[name];
365+ worldrebuilderfile << " doPackageBuild '" << name << " ' '" <<
366+ srpm << " '" << endl;
367+ // worldrebuilderfile << "touch ~/rpmbuild/PROGRESS/" << name << ".start" <<
368+ // endl;
369+ // worldrebuilderfile << "rpmbuild -ba " << name << ".spec --nocheck" <<
370+ // endl;
371+ // worldrebuilderfile << "if [[ $? -ne 0 ]]; then" << endl;
372+ // worldrebuilderfile << " touch ~/rpmbuild/PROGRESS/" << name <<
373+ // ".failed" << endl;
374+ // worldrebuilderfile << "fi" << endl;
375+ // worldrebuilderfile << "touch ~/rpmbuild/PROGRESS/" << name << ".done" <<
376+ // endl;
196377 }
197378
198379 worldrebuilderfile.close ();
0 commit comments