1 package org
.argeo
.slc
.lib
.linux
.rpmfactory
;
4 import java
.io
.IOException
;
5 import java
.io
.InputStream
;
6 import java
.io
.OutputStream
;
7 import java
.util
.ArrayList
;
10 import org
.apache
.commons
.exec
.Executor
;
11 import org
.apache
.commons
.io
.FileUtils
;
12 import org
.apache
.commons
.io
.IOUtils
;
13 import org
.apache
.commons
.logging
.Log
;
14 import org
.apache
.commons
.logging
.LogFactory
;
15 import org
.argeo
.slc
.SlcException
;
16 import org
.argeo
.slc
.core
.execution
.tasks
.SystemCall
;
17 import org
.springframework
.core
.io
.Resource
;
18 import org
.springframework
.core
.io
.UrlResource
;
20 /** Generates an SRPM from a spec file */
21 public class CreateSrpm
implements Runnable
{
22 private final static Log log
= LogFactory
.getLog(CreateSrpm
.class);
26 /** Directory where to cache downloaded distributions. */
27 private File distributionCache
;
29 private Resource specFile
;
31 private RpmBuildEnvironment rpmBuildEnvironment
;
33 private Boolean overwriteSources
= false;
35 private File srpmFile
;
37 private Executor executor
;
40 File sourcesDir
= new File(topdir
, "SOURCES");
42 File specsDir
= new File(topdir
, "SPECS");
43 File srpmsDir
= new File(topdir
, "SRPMS");
46 // Parse spec file and copy required resources
47 RpmSpecFile spec
= new RpmSpecFile(specFile
);
48 copyToSources(spec
, sourcesDir
);
51 File targetFile
= new File(specsDir
, specFile
.getFilename())
53 copyResourceToFile(specFile
, targetFile
);
55 // Generate rpmbuild config files
56 rpmBuildEnvironment
.writeRpmbuildConfigFiles(topdir
);
60 SystemCall packageSrpm
= new SystemCall();
61 packageSrpm
.arg("rpmbuild");
62 packageSrpm
.arg("-bs").arg("--nodeps");
63 packageSrpm
.arg("--rcfile=rpmrc");
64 packageSrpm
.arg("--macros=" + RpmBuildEnvironment
.defaultMacroFiles
66 // buildSrpm.arg("-D", "_topdir " + topdir.getCanonicalPath() + "");
67 packageSrpm
.arg("SPECS/" + specFile
.getFilename());
68 packageSrpm
.setExecDir(topdir
.getCanonicalPath());
69 packageSrpm
.setLogCommand(true);
72 packageSrpm
.setExecutor(executor
);
73 String answer
= packageSrpm
.function();
75 // Extract generated SRPM path
76 // TODO: make it safer
77 String srpmPath
= answer
.split(":")[1].trim();
78 srpmFile
= new File(srpmPath
);
79 } catch (IOException e
) {
80 throw new SlcException("Cannot generate SRPM from " + specFile
, e
);
85 protected void copyToSources(RpmSpecFile spec
, File sourcesDir
) {
87 List
<Resource
> toCopyToSources
= new ArrayList
<Resource
>();
88 List
<Resource
> toDownload
= new ArrayList
<Resource
>();
89 for (String file
: spec
.getSources().values()) {
93 res
= specFile
.createRelative("../SOURCES/" + file
);
95 res
= new UrlResource(file
);
97 } catch (Exception e
) {
98 res
= new UrlResource(file
);
101 toCopyToSources
.add(res
);
102 } catch (Exception e
) {
103 log
.error("Cannot interpret " + file
, e
);
106 for (String file
: spec
.getPatches().values()) {
110 res
= specFile
.createRelative("../SOURCES/" + file
);
112 res
= new UrlResource(file
);
114 } catch (Exception e
) {
115 res
= new UrlResource(file
);
118 toCopyToSources
.add(res
);
119 } catch (Exception e
) {
120 log
.error("Cannot interpret " + file
, e
);
124 // FIXME: we may have missed some files here
125 for (Resource res
: toCopyToSources
) {
127 if (distributionCache
!= null && toDownload
.contains(res
)) {
128 if (!distributionCache
.exists())
129 distributionCache
.mkdirs();
130 targetDir
= distributionCache
;
131 if (log
.isDebugEnabled())
132 log
.debug("Cache " + res
+ " in " + targetDir
);
134 targetDir
= sourcesDir
;
135 File targetFile
= new File(targetDir
, res
.getFilename())
137 if (!targetFile
.exists() || overwriteSources
)
138 copyResourceToFile(res
, targetFile
);
139 if (!targetDir
.equals(sourcesDir
)) {
140 File fileInSourcesDir
= new File(sourcesDir
,
141 targetFile
.getName());
142 if (!fileInSourcesDir
.exists()
143 || !(fileInSourcesDir
.length() == targetFile
145 FileUtils
.copyFile(targetFile
, fileInSourcesDir
);
148 } catch (Exception e
) {
149 throw new SlcException("Cannot copy to " + sourcesDir
, e
);
153 private static void copyResourceToFile(Resource res
, File targetFile
) {
155 if (targetFile
.equals(res
.getFile())) {
156 if (log
.isDebugEnabled())
157 log
.debug("Target identical to source, skipping... "
158 + targetFile
+ " <=> " + res
);
161 } catch (IOException e1
) {
165 OutputStream out
= null;
166 InputStream in
= null;
168 out
= FileUtils
.openOutputStream(targetFile
);
169 in
= res
.getInputStream();
170 IOUtils
.copy(in
, out
);
171 if (log
.isDebugEnabled())
172 log
.debug("Copied " + targetFile
+ " from " + res
);
173 } catch (Exception e
) {
174 throw new SlcException("Cannot copy " + res
+ " to " + targetFile
,
177 IOUtils
.closeQuietly(in
);
178 IOUtils
.closeQuietly(out
);
183 public void setSpecFile(Resource specFile
) {
184 this.specFile
= specFile
;
187 public void setTopdir(File topdir
) {
188 this.topdir
= topdir
;
191 public void setOverwriteSources(Boolean overwriteSources
) {
192 this.overwriteSources
= overwriteSources
;
195 public File
getSrpmFile() {
199 public void setRpmBuildEnvironment(RpmBuildEnvironment rpmBuildEnvironment
) {
200 this.rpmBuildEnvironment
= rpmBuildEnvironment
;
203 public void setDistributionCache(File distributionCache
) {
204 this.distributionCache
= distributionCache
;
207 public void setExecutor(Executor executor
) {
208 this.executor
= executor
;