Merge tag 'v2.3.20' into testing
[gpl/argeo-jcr.git] / org.argeo.slc.rpmfactory / src / org / argeo / slc / rpmfactory / core / BuildInMock.java
diff --git a/org.argeo.slc.rpmfactory/src/org/argeo/slc/rpmfactory/core/BuildInMock.java b/org.argeo.slc.rpmfactory/src/org/argeo/slc/rpmfactory/core/BuildInMock.java
new file mode 100644 (file)
index 0000000..eab9ffa
--- /dev/null
@@ -0,0 +1,190 @@
+package org.argeo.slc.rpmfactory.core;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.commons.exec.Executor;
+import org.apache.commons.io.FileUtils;
+import org.argeo.api.cms.CmsLog;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.rpmfactory.RpmFactory;
+import org.argeo.slc.runtime.tasks.SystemCall;
+
+/** Build an RPM in mock. */
+public class BuildInMock implements Runnable {
+       private final static CmsLog log = CmsLog.getLog(BuildInMock.class);
+       private final static String NOARCH = "noarch";
+
+       private String rpmPackage = null;
+       private String branch = null;
+       private String arch = NOARCH;
+
+       private RpmFactory rpmFactory;
+       private Executor executor;
+
+       private String debuginfoDirName = "debuginfo";
+       private String mockExecutable = "/usr/bin/mock";
+
+       private List<String> preBuildCommands = new ArrayList<String>();
+
+       public void run() {
+               if (!rpmFactory.isDeveloperInstance()) {
+                       // clean/init
+                       SystemCall mockClean = createBaseMockCall();
+                       mockClean.arg("--init");
+                       mockClean.run();
+               }
+
+               // pre build commands
+               for (String preBuildCmd : preBuildCommands) {
+                       SystemCall mockClean = createBaseMockCall();
+                       mockClean.arg("--chroot").arg(preBuildCmd);
+                       mockClean.run();
+               }
+
+               // actual build
+               SystemCall mockBuild = createBaseMockCall();
+               mockBuild.arg("--scm-enable");
+               mockBuild.arg("--scm-option").arg("package=" + rpmPackage);
+               mockBuild.arg("--no-clean");
+               //
+               //
+               mockBuild.run();
+               //
+
+               // copy RPMs to target directories
+               File stagingDir = rpmFactory.getWorkspaceDir(rpmFactory
+                               .getStagingWorkspace());
+               File srpmDir = new File(stagingDir, "SRPMS");
+               srpmDir.mkdirs();
+               File archDir = null;
+               File debuginfoDir = null;
+               if (!arch.equals(NOARCH)) {
+                       archDir = new File(stagingDir, arch);
+                       debuginfoDir = new File(archDir, debuginfoDirName);
+                       debuginfoDir.mkdirs();
+               }
+
+               Set<File> reposToRecreate = new HashSet<File>();
+               File resultDir = rpmFactory.getResultDir(arch);
+               if (resultDir.exists())
+                       rpms: for (File file : resultDir.listFiles()) {
+                               if (file.isDirectory())
+                                       continue rpms;
+
+                               File[] targetDirs;
+                               if (file.getName().contains(".src.rpm"))
+                                       targetDirs = new File[] { srpmDir };
+                               else if (file.getName().contains("-debuginfo-"))
+                                       targetDirs = new File[] { debuginfoDir };
+                               else if (!arch.equals(NOARCH)
+                                               && file.getName().contains("." + arch + ".rpm"))
+                                       targetDirs = new File[] { archDir };
+                               else if (file.getName().contains(".noarch.rpm")) {
+                                       List<File> dirs = new ArrayList<File>();
+                                       for (String arch : rpmFactory.getArchs())
+                                               dirs.add(new File(stagingDir, arch));
+                                       targetDirs = dirs.toArray(new File[dirs.size()]);
+                               } else if (file.getName().contains(".rpm"))
+                                       throw new SlcException("Don't know where to copy " + file);
+                               else {
+                                       if (log.isTraceEnabled())
+                                               log.trace("Skip " + file);
+                                       continue rpms;
+                               }
+
+                               reposToRecreate.addAll(Arrays.asList(targetDirs));
+                               copyToDirs(file, targetDirs);
+                       }
+
+               // recreate changed repos
+               for (File repoToRecreate : reposToRecreate) {
+                       SystemCall createrepo = new SystemCall();
+                       createrepo.arg("createrepo");
+                       // sqllite db
+                       createrepo.arg("-d");
+                       // debuginfo
+                       if (!repoToRecreate.getName().equals(debuginfoDirName))
+                               createrepo.arg("-x").arg(debuginfoDirName + "/*");
+                       // quiet
+                       createrepo.arg("-q");
+                       createrepo.arg(repoToRecreate.getAbsolutePath());
+
+                       createrepo.setExecutor(executor);
+                       createrepo.run();
+                       log.info("Updated repo " + repoToRecreate);
+               }
+
+               // index staging workspace
+               rpmFactory.indexWorkspace(rpmFactory.getStagingWorkspace());
+       }
+
+       /** Creates a mock call with all the common options such as config file etc. */
+       protected SystemCall createBaseMockCall() {
+               String mockCfg = rpmFactory.getMockConfig(arch);
+               File mockConfigFile = rpmFactory.getMockConfigFile(arch, branch);
+
+               // prepare mock call
+               SystemCall mock = new SystemCall();
+
+               if (arch != null)
+                       mock.arg("setarch").arg(arch);
+               mock.arg(mockExecutable);
+               mock.arg("-v");
+               mock.arg("--configdir=" + mockConfigFile.getAbsoluteFile().getParent());
+               if (arch != null)
+                       mock.arg("--arch=" + arch);
+               mock.arg("-r").arg(mockCfg);
+
+               mock.setLogCommand(true);
+               mock.setExecutor(executor);
+
+               return mock;
+       }
+
+       protected void copyToDirs(File file, File[] dirs) {
+               for (File dir : dirs) {
+                       try {
+                               FileUtils.copyFileToDirectory(file, dir);
+                               if (log.isDebugEnabled())
+                                       log.debug(file + " => " + dir);
+                       } catch (IOException e) {
+                               throw new SlcException("Cannot copy " + file + " to " + dir, e);
+                       }
+               }
+       }
+
+       public void setArch(String arch) {
+               this.arch = arch;
+       }
+
+       public void setRpmPackage(String rpmPackage) {
+               this.rpmPackage = rpmPackage;
+       }
+
+       public void setBranch(String branch) {
+               this.branch = branch;
+       }
+
+       public void setRpmFactory(RpmFactory env) {
+               this.rpmFactory = env;
+       }
+
+       public void setExecutor(Executor executor) {
+               this.executor = executor;
+       }
+
+       public void setMockExecutable(String mockExecutable) {
+               this.mockExecutable = mockExecutable;
+       }
+
+       public void setPreBuildCommands(List<String> preBuildCommands) {
+               this.preBuildCommands = preBuildCommands;
+       }
+
+}
\ No newline at end of file