/**
   * Tests run of zipalign with correct parameters as well adding aligned file to artifacts
   *
   * @throws Exception
   */
  public void testDefaultRun() throws Exception {
    ZipalignMojo mojo = createMojo("zipalign-config-project3");

    MavenProject project = Whitebox.getInternalState(mojo, "project");
    project.setPackaging(AndroidExtension.APK);

    MavenProjectHelper projectHelper = EasyMock.createNiceMock(MavenProjectHelper.class);
    Capture<File> capturedParameter = new Capture<File>();
    projectHelper.attachArtifact(
        EasyMock.eq(project),
        EasyMock.eq(AndroidExtension.APK),
        EasyMock.eq("aligned"),
        EasyMock.capture(capturedParameter));
    Whitebox.setInternalState(mojo, "projectHelper", projectHelper);

    final CommandExecutor mockExecutor = PowerMock.createMock(CommandExecutor.class);
    PowerMock.replace(
            CommandExecutor.Factory.class.getDeclaredMethod("createDefaultCommmandExecutor"))
        .with(
            new InvocationHandler() {
              @Override
              public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                return mockExecutor;
              }
            });

    Capture<List<String>> capturedFile = new Capture<List<String>>();
    mockExecutor.setLogger(EasyMock.anyObject(Log.class));
    mockExecutor.executeCommand(EasyMock.anyObject(String.class), EasyMock.capture(capturedFile));

    PowerMock.mockStatic(FileUtils.class);
    EasyMock.expect(FileUtils.fileExists("app-updated.apk")).andReturn(true);

    EasyMock.replay(projectHelper);
    PowerMock.replay(mockExecutor);
    PowerMock.replay(FileUtils.class);

    mojo.execute();

    PowerMock.verify(mockExecutor);
    List<String> parameters = capturedFile.getValue();
    List<String> parametersExpected = new ArrayList<String>();
    parametersExpected.add("-v");
    parametersExpected.add("-f");
    parametersExpected.add("4");
    parametersExpected.add("app.apk");
    parametersExpected.add("app-updated.apk");
    assertEquals("Zipalign arguments aren't as expected", parametersExpected, parameters);

    PowerMock.verify(projectHelper);
    assertEquals(
        "File should be same as expected",
        new File("app-updated.apk"),
        capturedParameter.getValue());

    // verify that all method were invoked
    PowerMock.verify(FileUtils.class);
  }
 protected final void attachNar(
     ArchiverManager archiverManager,
     MavenProjectHelper projectHelper,
     MavenProject project,
     String classifier,
     File dir,
     String include)
     throws MojoExecutionException {
   File narFile =
       new File(
           project.getBuild().getDirectory(),
           project.getBuild().getFinalName()
               + "-"
               + classifier
               + "."
               + NarConstants.NAR_EXTENSION);
   if (narFile.exists()) {
     narFile.delete();
   }
   try {
     Archiver archiver = archiverManager.getArchiver(NarConstants.NAR_ROLE_HINT);
     archiver.addDirectory(dir, new String[] {include}, null);
     archiver.setDestFile(narFile);
     archiver.createArchive();
   } catch (NoSuchArchiverException e) {
     throw new MojoExecutionException("NAR: cannot find archiver", e);
   } catch (ArchiverException e) {
     throw new MojoExecutionException("NAR: cannot create NAR archive '" + narFile + "'", e);
   } catch (IOException e) {
     throw new MojoExecutionException("NAR: cannot create NAR archive '" + narFile + "'", e);
   }
   projectHelper.attachArtifact(project, NarConstants.NAR_TYPE, classifier, narFile);
 }
  @Override
  public void execute() throws MojoExecutionException, MojoFailureException {
    try {
      if (!project.isExecutionRoot()) {
        getLog().info("Not the execution root so ignoring this project");
        return;
      }
      buildDir.mkdirs();

      for (MavenProject reactorProject : reactorProjects) {
        // ignore the execution root which just aggregates stuff
        if (!reactorProject.isExecutionRoot()) {
          combineProfilesTo(reactorProject, buildDir);
        }
      }
      Zips.createZipFile(getLog(), buildDir, outputFile);

      projectHelper.attachArtifact(project, artifactType, artifactClassifier, outputFile);

      String relativePath = Files.getRelativePath(project.getBasedir(), outputFile);
      while (relativePath.startsWith("/")) {
        relativePath = relativePath.substring(1);
      }
      getLog().info("Created profile zip file: " + relativePath);
    } catch (MojoExecutionException e) {
      throw e;
    } catch (Exception e) {
      throw new MojoExecutionException("Error executing", e);
    }
  }
Esempio n. 4
0
  public void execute() throws MojoExecutionException {
    try {

      Library library = new Library(name);
      if (platform == null || platform.trim().length() == 0) {
        platform = library.getPlatform();
      }

      String packageName = project.getArtifactId() + "-" + project.getVersion() + "-" + platform;
      JarArchiver archiver = (JarArchiver) archiverManager.getArchiver("jar");

      File packageFile =
          new File(new File(project.getBuild().getDirectory()), packageName + ".jar");
      archiver.setDestFile(packageFile);
      archiver.setIncludeEmptyDirs(true);
      archiver.addDirectory(libDirectory);

      Manifest manifest = new Manifest();
      manifest.addConfiguredAttribute(
          new Attribute("Bundle-SymbolicName", project.getArtifactId() + "-" + platform));
      manifest.addConfiguredAttribute(new Attribute("Bundle-Name", name + " for " + platform));
      manifest.addConfiguredAttribute(
          new Attribute("Bundle-NativeCode", getNativeCodeValue(library)));
      manifest.addConfiguredAttribute(new Attribute("Bundle-Version", project.getVersion()));
      manifest.addConfiguredAttribute(new Attribute("Bundle-ManifestVersion", "2"));
      manifest.addConfiguredAttribute(
          new Attribute("Bundle-Description", project.getDescription()));
      archiver.addConfiguredManifest(manifest);

      archiver.createArchive();

      projectHelper.attachArtifact(project, "jar", platform, packageFile);

    } catch (Exception e) {
      throw new MojoExecutionException("packageing failed: " + e, e);
    }
  }
 /**
  * Attaches the features.xml file to the build.
  *
  * @param file the generated features.xml file
  */
 private void attachToBuild(File file) {
   projectHelper.attachArtifact(
       this.project, "xml", "features", file); // $NON-NLS-1$ //$NON-NLS-2$
 }
Esempio n. 6
0
  public static void prepareLanguage(
      Log log,
      MavenProject project,
      MavenProjectHelper projectHelper,
      File languageOutDir,
      File schemaOutDir,
      BuildContext buildContext)
      throws MojoExecutionException {

    File camelMetaDir = new File(languageOutDir, "META-INF/services/org/apache/camel/");

    // first we need to setup the output directory because the next check
    // can stop the build before the end and eclipse always needs to know about that directory
    if (projectHelper != null) {
      projectHelper.addResource(
          project,
          languageOutDir.getPath(),
          Collections.singletonList("**/dataformat.properties"),
          Collections.emptyList());
    }

    if (!PackageHelper.haveResourcesChanged(
        log, project, buildContext, "META-INF/services/org/apache/camel/language")) {
      return;
    }

    Map<String, String> javaTypes = new HashMap<String, String>();

    StringBuilder buffer = new StringBuilder();
    int count = 0;
    for (Resource r : project.getBuild().getResources()) {
      File f = new File(r.getDirectory());
      if (!f.exists()) {
        f = new File(project.getBasedir(), r.getDirectory());
      }
      f = new File(f, "META-INF/services/org/apache/camel/language");

      if (f.exists() && f.isDirectory()) {
        File[] files = f.listFiles();
        if (files != null) {
          for (File file : files) {
            String javaType = readClassFromCamelResource(file, buffer, buildContext);
            if (!file.isDirectory() && file.getName().charAt(0) != '.') {
              count++;
            }
            if (javaType != null) {
              javaTypes.put(file.getName(), javaType);
            }
          }
        }
      }
    }

    // find camel-core and grab the data format model from there, and enrich this model with
    // information from this artifact
    // and create json schema model file for this data format
    try {
      if (count > 0) {
        Artifact camelCore = findCamelCoreArtifact(project);
        if (camelCore != null) {
          File core = camelCore.getFile();
          if (core != null) {
            URL url = new URL("file", null, core.getAbsolutePath());
            URLClassLoader loader = new URLClassLoader(new URL[] {url});
            for (Map.Entry<String, String> entry : javaTypes.entrySet()) {
              String name = entry.getKey();
              String javaType = entry.getValue();
              String modelName = asModelName(name);

              InputStream is =
                  loader.getResourceAsStream(
                      "org/apache/camel/model/language/" + modelName + ".json");
              if (is == null) {
                // use file input stream if we build camel-core itself, and thus do not have a JAR
                // which can be loaded by URLClassLoader
                is =
                    new FileInputStream(
                        new File(core, "org/apache/camel/model/language/" + modelName + ".json"));
              }
              String json = loadText(is);
              if (json != null) {
                LanguageModel languageModel = new LanguageModel();
                languageModel.setName(name);
                languageModel.setTitle("");
                languageModel.setModelName(modelName);
                languageModel.setLabel("");
                languageModel.setDescription("");
                languageModel.setJavaType(javaType);
                languageModel.setGroupId(project.getGroupId());
                languageModel.setArtifactId(project.getArtifactId());
                languageModel.setVersion(project.getVersion());

                List<Map<String, String>> rows =
                    JSonSchemaHelper.parseJsonSchema("model", json, false);
                for (Map<String, String> row : rows) {
                  if (row.containsKey("title")) {
                    languageModel.setTitle(row.get("title"));
                  }
                  if (row.containsKey("description")) {
                    languageModel.setDescription(row.get("description"));
                  }
                  if (row.containsKey("label")) {
                    languageModel.setLabel(row.get("label"));
                  }
                  if (row.containsKey("javaType")) {
                    languageModel.setModelJavaType(row.get("javaType"));
                  }
                }
                log.debug("Model " + languageModel);

                // build json schema for the data format
                String properties = after(json, "  \"properties\": {");
                String schema = createParameterJsonSchema(languageModel, properties);
                log.debug("JSon schema\n" + schema);

                // write this to the directory
                File dir = new File(schemaOutDir, schemaSubDirectory(languageModel.getJavaType()));
                dir.mkdirs();

                File out = new File(dir, name + ".json");
                OutputStream fos = buildContext.newFileOutputStream(out);
                fos.write(schema.getBytes());
                fos.close();

                buildContext.refresh(out);

                log.debug("Generated " + out + " containing JSon schema for " + name + " language");
              }
            }
          }
        }
      }
    } catch (Exception e) {
      throw new MojoExecutionException(
          "Error loading language model from camel-core. Reason: " + e, e);
    }

    if (count > 0) {
      Properties properties = new Properties();
      String names = buffer.toString();
      properties.put("languages", names);
      properties.put("groupId", project.getGroupId());
      properties.put("artifactId", project.getArtifactId());
      properties.put("version", project.getVersion());
      properties.put("projectName", project.getName());
      if (project.getDescription() != null) {
        properties.put("projectDescription", project.getDescription());
      }

      camelMetaDir.mkdirs();
      File outFile = new File(camelMetaDir, "language.properties");

      // check if the existing file has the same content, and if so then leave it as is so we do not
      // write any changes
      // which can cause a re-compile of all the source code
      if (outFile.exists()) {
        try {
          Properties existing = new Properties();

          InputStream is = new FileInputStream(outFile);
          existing.load(is);
          is.close();

          // are the content the same?
          if (existing.equals(properties)) {
            log.debug("No language changes detected");
            return;
          }
        } catch (IOException e) {
          // ignore
        }
      }

      try {
        OutputStream os = buildContext.newFileOutputStream(outFile);
        properties.store(os, "Generated by camel-package-maven-plugin");
        os.close();

        log.info(
            "Generated "
                + outFile
                + " containing "
                + count
                + " Camel "
                + (count > 1 ? "languages: " : "language: ")
                + names);

        if (projectHelper != null) {
          projectHelper.attachArtifact(project, "properties", "camelLanguage", outFile);
        }
      } catch (IOException e) {
        throw new MojoExecutionException(
            "Failed to write properties to " + outFile + ". Reason: " + e, e);
      }
    } else {
      log.debug(
          "No META-INF/services/org/apache/camel/language directory found. Are you sure you have created a Camel language?");
    }
  }
  /**
   * Create the binary distribution.
   *
   * @throws org.apache.maven.plugin.MojoExecutionException
   */
  public void execute() throws MojoExecutionException, MojoFailureException {
    if (skipAssembly) {
      getLog()
          .info("Assemblies have been skipped per configuration of the skipAssembly parameter.");
      return;
    }

    // run only at the execution root.
    if (runOnlyAtExecutionRoot && !isThisTheExecutionRoot()) {
      getLog().info("Skipping the assembly in this project because it's not the Execution Root");
      return;
    }

    List<Assembly> assemblies;
    try {
      assemblies = assemblyReader.readAssemblies(this);
    } catch (final AssemblyReadException e) {
      throw new MojoExecutionException("Error reading assemblies: " + e.getMessage(), e);
    } catch (final InvalidAssemblerConfigurationException e) {
      throw new MojoFailureException(
          assemblyReader, e.getMessage(), "Mojo configuration is invalid: " + e.getMessage());
    }

    // TODO: include dependencies marked for distribution under certain formats
    // TODO: how, might we plug this into an installer, such as NSIS?

    boolean warnedAboutMainProjectArtifact = false;
    for (final Assembly assembly : assemblies) {
      try {
        final String fullName = AssemblyFormatUtils.getDistributionName(assembly, this);

        List<String> effectiveFormats = formats;
        if (effectiveFormats == null || effectiveFormats.size() == 0) {
          effectiveFormats = assembly.getFormats();
        }
        if (effectiveFormats == null || effectiveFormats.size() == 0) {
          throw new MojoFailureException(
              "No formats specified in the execution parameters or the assembly descriptor.");
        }

        for (final String format : effectiveFormats) {
          final File destFile =
              assemblyArchiver.createArchive(
                  assembly, fullName, format, this, isRecompressZippedFiles());

          final MavenProject project = getProject();
          final String classifier = getClassifier();
          final String type = project.getArtifact().getType();

          if (attach && destFile.isFile()) {
            if (isAssemblyIdAppended()) {
              projectHelper.attachArtifact(project, format, assembly.getId(), destFile);
            } else if (classifier != null) {
              projectHelper.attachArtifact(project, format, classifier, destFile);
            } else if (!"pom".equals(type) && format.equals(type)) {
              if (!warnedAboutMainProjectArtifact) {
                final StringBuilder message = new StringBuilder();

                message.append(
                    "Configuration options: 'appendAssemblyId' is set to false, and 'classifier' is missing.");
                message
                    .append("\nInstead of attaching the assembly file: ")
                    .append(destFile)
                    .append(", it will become the file for main project artifact.");
                message.append(
                    "\nNOTE: If multiple descriptors or descriptor-formats are provided for this project, the value of this file will be non-deterministic!");

                getLog().warn(message);
                warnedAboutMainProjectArtifact = true;
              }

              final File existingFile = project.getArtifact().getFile();
              if ((existingFile != null) && existingFile.exists()) {
                getLog()
                    .warn(
                        "Replacing pre-existing project main-artifact file: "
                            + existingFile
                            + "\nwith assembly file: "
                            + destFile);
              }

              project.getArtifact().setFile(destFile);
            } else {
              projectHelper.attachArtifact(project, format, null, destFile);
            }
          } else if (attach) {
            getLog()
                .warn(
                    "Assembly file: "
                        + destFile
                        + " is not a regular file (it may be a directory). It cannot be attached to the project build for installation or deployment.");
          }
        }
      } catch (final ArchiveCreationException e) {
        throw new MojoExecutionException("Failed to create assembly: " + e.getMessage(), e);
      } catch (final AssemblyFormattingException e) {
        throw new MojoExecutionException("Failed to create assembly: " + e.getMessage(), e);
      } catch (final InvalidAssemblerConfigurationException e) {
        throw new MojoFailureException(
            assembly,
            "Assembly is incorrectly configured: " + assembly.getId(),
            "Assembly: " + assembly.getId() + " is not configured correctly: " + e.getMessage());
      }
    }
  }
  public void execute() throws MojoExecutionException, MojoFailureException {
    if (skipNbm) {
      getLog().info("Skipping generation of NBM file.");
      return;
    }

    if ("pom".equals(project.getPackaging())) {
      getLog().info("Skipping " + project.getId() + ", no nbm:nbm execution for 'pom' packaging");
      return;
    }
    super.execute();

    // 3. generate nbm
    File nbmFile = new File(nbmBuildDir, finalName + ".nbm");
    MakeNBM nbmTask = (MakeNBM) antProject.createTask("makenbm");
    nbmTask.setFile(nbmFile);
    nbmTask.setProductDir(clusterDir);

    nbmTask.setModule("modules" + File.separator + moduleJarName + ".jar");
    boolean reqRestart = requiresRestart;
    if (!reqRestart && module.isRequiresRestart()) {
      reqRestart = module.isRequiresRestart();
      getLog()
          .warn(
              "Module descriptor's requiresRestart field is deprecated, use plugin's configuration in pom.xml");
    }
    nbmTask.setNeedsrestart(Boolean.toString(reqRestart));
    String moduleAuthor = author;
    if (module.getAuthor() != null) {
      moduleAuthor = module.getAuthor();
      getLog()
          .warn(
              "Module descriptor's requiresRestart field is deprecated, use plugin's configuration in pom.xml");
    }
    nbmTask.setModuleauthor(moduleAuthor);
    if (keystore != null && keystorealias != null && keystorepassword != null) {
      File ks = new File(keystore);
      if (!ks.exists()) {
        getLog().warn("Cannot find keystore file at " + ks.getAbsolutePath());
      } else {
        Signature sig = nbmTask.createSignature();
        sig.setKeystore(ks);
        sig.setAlias(keystorealias);
        sig.setStorepass(keystorepassword);
        getLog().debug("Setup the Ant task to sign the NBM file.");
      }
    } else if (keystore != null || keystorepassword != null || keystorealias != null) {
      getLog()
          .warn(
              "If you want to sign the nbm file, you need to define all three keystore related parameters.");
    }
    String licName = licenseName;
    File licFile = licenseFile;
    if (module.getLicenseName() != null) {
      licName = module.getLicenseName();
      getLog()
          .warn(
              "Module descriptor's licenseName field is deprecated, use plugin's configuration in pom.xml");
    }
    if (module.getLicenseFile() != null) {
      File lf = new File(project.getBasedir(), module.getLicenseFile());
      licFile = lf;
      getLog()
          .warn(
              "Module descriptor's licenseFile field is deprecated, use plugin's configuration in pom.xml");
    }
    if (licName != null && licFile != null) {
      if (!licFile.exists() || !licFile.isFile()) {
        getLog().warn("Cannot find license file at " + licFile.getAbsolutePath());
      } else {
        Blurb lb = nbmTask.createLicense();
        lb.setFile(licFile);
        lb.addText(licName);
      }
    } else if (licName != null || licFile != null) {
      getLog()
          .warn(
              "To set license for the nbm, you need to specify both licenseName and licenseFile parameters.");
    } else {
      Blurb lb = nbmTask.createLicense();
      lb.addText(createDefaultLicenseHeader());
      lb.addText(createDefaultLicenseText());
    }
    String hpUrl = homePageUrl;
    if (module.getHomepageUrl() != null) {
      getLog()
          .warn(
              "Module descriptor's homePageUrl field is deprecated, use plugin's configuration in pom.xml");
      hpUrl = module.getHomepageUrl();
    }
    if (hpUrl != null) {
      nbmTask.setHomepage(hpUrl);
    }
    String distribUrl = distributionUrl;
    if (module.getDistributionUrl() != null) {
      distribUrl = module.getDistributionUrl();
      getLog()
          .warn(
              "Module descriptor's distributionUrl field is deprecated, use plugin's configuration in pom.xml");
    }
    if (distribUrl != null) {
      ArtifactRepository distRepository =
          CreateUpdateSiteMojo.getDeploymentRepository(distribUrl, container, getLog());
      String dist = null;
      if (distRepository == null) {
        if (!distribUrl.contains("::")) {
          dist = distribUrl + (distribUrl.endsWith("/") ? "" : "/") + nbmFile.getName();
        }
      } else {
        Artifact art =
            artifactFactory.createArtifact(
                project.getGroupId(),
                project.getArtifactId(),
                project.getVersion(),
                null,
                "nbm-file");

        dist =
            distRepository.getUrl()
                + (distRepository.getUrl().endsWith("/") ? "" : "/")
                + distRepository.pathOf(art);
      }
      nbmTask.setDistribution(dist);
    } else {
      nbmTask.setDistribution(nbmFile.getName());
    }
    if (!"extra".equals(cluster)) {
      nbmTask.setTargetcluster(cluster);
    }
    // MNBMODULE-217 avoid using the static DATE_FORMAT variable in MavenNBM.java (in ant harness)
    nbmTask.setReleasedate(DATE_FORMAT.format(new Date(System.currentTimeMillis())));
    try {
      nbmTask.execute();
    } catch (BuildException e) {
      throw new MojoExecutionException("Cannot Generate nbm file:" + e.getMessage(), e);
    }
    try {
      File nbmfile = new File(buildDir, nbmFile.getName());
      FileUtils.getFileUtils().copyFile(nbmFile, nbmfile);
      projectHelper.attachArtifact(project, "nbm-file", null, nbmfile);
    } catch (IOException ex) {
      throw new MojoExecutionException("Cannot copy nbm to build directory", ex);
    }
  }
Esempio n. 9
0
  protected void attachFile(String cpString) throws MojoExecutionException {
    File attachedFile = new File(project.getBuild().getDirectory(), "classpath");
    storeClasspathFile(cpString, attachedFile);

    projectHelper.attachArtifact(project, attachedFile, "classpath");
  }
Esempio n. 10
0
  protected void attachP2Metadata() throws MojoExecutionException {
    if (!attachP2Metadata || !supportedProjectTypes.contains(project.getPackaging())) {
      return;
    }

    File file = project.getArtifact().getFile();

    if (file == null || !file.canRead()) {
      throw new IllegalStateException();
    }

    File targetDir = new File(project.getBuild().getDirectory());

    Map<String, IArtifactFacade> artifactsToBeAttached = new HashMap<String, IArtifactFacade>();

    ArtifactFacade projectDefaultArtifact = new ArtifactFacade(project.getArtifact());

    Artifact p2contentArtifact =
        createP2Artifact(
            projectDefaultArtifact,
            EXTENSION_P2_METADATA,
            CLASSIFIER_P2_METADATA,
            FILE_NAME_P2_METADATA,
            targetDir);
    artifactsToBeAttached.put(CLASSIFIER_P2_METADATA, new ArtifactFacade(p2contentArtifact));

    Artifact p2artifactsArtifact =
        createP2Artifact(
            projectDefaultArtifact,
            EXTENSION_P2_ARTIFACTS,
            CLASSIFIER_P2_ARTIFACTS,
            FILE_NAME_P2_ARTIFACTS,
            targetDir);
    artifactsToBeAttached.put(CLASSIFIER_P2_ARTIFACTS, new ArtifactFacade(p2artifactsArtifact));

    try {
      List<IArtifactFacade> artifacts = new ArrayList<IArtifactFacade>();

      artifacts.add(projectDefaultArtifact);

      for (Artifact attachedArtifact : project.getAttachedArtifacts()) {
        if (attachedArtifact.getFile() != null
            && attachedArtifact.getFile().getName().endsWith(".jar")) {
          artifacts.add(new ArtifactFacade(attachedArtifact));
        }
      }

      Map<String, Set<Object>> generateMetadata =
          getP2Generator().generateMetadata(artifacts, artifactsToBeAttached, targetDir);

      ReactorProject reactorProject = DefaultReactorProject.adapt(project);

      for (Map.Entry<String, Set<Object>> entry : generateMetadata.entrySet()) {
        reactorProject.setDependencyMetadata(entry.getKey(), true, entry.getValue());
        reactorProject.setDependencyMetadata(entry.getKey(), false, Collections.emptySet());
      }
    } catch (IOException e) {
      throw new MojoExecutionException("Could not generate P2 metadata", e);
    }

    for (Entry<String, IArtifactFacade> entry : artifactsToBeAttached.entrySet()) {
      IArtifactFacade artifactFacade = entry.getValue();

      projectHelper.attachArtifact(
          project,
          artifactFacade.getPackagingType(),
          artifactFacade.getClassifier(),
          artifactFacade.getLocation());
    }

    File localArtifactsFile =
        new File(project.getBuild().getDirectory(), FILE_NAME_LOCAL_ARTIFACTS);
    writeArtifactLocations(localArtifactsFile, getAllProjectArtifacts(project));
  }
Esempio n. 11
0
  @Override
  public void execute() throws MojoExecutionException {
    String gitConfigDirectory = Utils.getGitConfigFolder(getProjectBaseDirectory());
    String commitId = Utils.getLastCommitUuid(gitConfigDirectory);

    if (failIfCommitNecessary && Utils.isCommitNecessary(gitConfigDirectory)) {
      String failMsg =
          "There are modified sources, commit changes before calling the plugin or set "
              + "failIfCommitNecessary parameter as false in your plugin configuration field inside the pom.xml";

      throw new MojoExecutionException(failMsg);
    }

    try {
      String timeStamp = Utils.getTimestamp(new Date());

      // Extract the original chop-runner.jar file which should be in the local repository
      String runnerJarPath = getRunnerInLocalRepo();
      String extractedRunnerPath = getExtractedRunnerPath();
      if (FileUtils.fileExists(extractedRunnerPath)) {
        FileUtils.cleanDirectory(extractedRunnerPath);
      } else {
        FileUtils.mkdir(extractedRunnerPath);
      }
      Utils.extractJar(new File(runnerJarPath), extractedRunnerPath);

      // Copy caller project jar and its dependency jars to topmost runner folder
      File libPathFile = new File(extractedRunnerPath);
      String projectTestOutputJar = getProjectTestOutputJarPath();
      if (!FileUtils.fileExists(projectTestOutputJar)) {
        throw new MojoExecutionException(
            "Project Test Jar could not be found. Make sure you use 'test-jar'"
                + " goal of the 'maven-jar-plugin' in your project's pom");
      }
      FileUtils.copyFileToDirectory(new File(getProjectOutputJarPath()), libPathFile);
      FileUtils.copyFileToDirectory(new File(projectTestOutputJar), libPathFile);

      Utils.copyArtifactsTo(this.project, extractedRunnerPath);
      Utils.copyResourcesTo(this.project, extractedRunnerPath);

      // Create project.properties file
      InputStream inputStream;
      Properties prop = new Properties();
      String configPropertiesFilePath = extractedRunnerPath + "project.properties";
      if (FileUtils.fileExists(configPropertiesFilePath)) {
        // Existing project.properties of chop-runner
        inputStream = new FileInputStream(configPropertiesFilePath);
        prop.load(inputStream);
        inputStream.close();
      }

      // If exists, properties in this file can overwrite the ones from chop-runner
      if (getClass().getResource("project.properties") != null) {
        inputStream = getClass().getResourceAsStream("project.properties");
        Properties propCurrent = new Properties();
        propCurrent.load(inputStream);
        inputStream.close();

        String key;
        while (propCurrent.propertyNames().hasMoreElements()) {
          key = propCurrent.propertyNames().nextElement().toString();
          prop.setProperty(key, propCurrent.getProperty(key));
        }
      }

      // Insert all properties acquired in runtime and overwrite existing ones
      String gitUrl = Utils.getGitRemoteUrl(gitConfigDirectory);
      String md5 = Utils.getMD5(timeStamp, commitId);
      prop.setProperty(Project.GIT_UUID_KEY, commitId);
      prop.setProperty(Project.GIT_URL_KEY, gitUrl);
      prop.setProperty(Project.CREATE_TIMESTAMP_KEY, timeStamp);
      prop.setProperty(Project.GROUP_ID_KEY, this.project.getGroupId());
      prop.setProperty(Project.ARTIFACT_ID_KEY, this.project.getArtifactId());
      prop.setProperty(Project.PROJECT_VERSION_KEY, this.project.getVersion());
      prop.setProperty(Project.TEST_PACKAGE_BASE, testPackageBase);
      prop.setProperty(Project.MD5_KEY, md5);
      prop.setProperty(CoordinatorFig.USERNAME, username);
      prop.setProperty(CoordinatorFig.PASSWORD, password);
      prop.setProperty(CoordinatorFig.ENDPOINT, endpoint);

      String uuid =
          commitId.substring(0, CHARS_OF_UUID / 2)
              + commitId.substring(commitId.length() - CHARS_OF_UUID / 2);

      prop.setProperty(Project.LOAD_KEY, TESTS_PATH + '/' + uuid + '/' + RUNNER_JAR);
      prop.setProperty(Project.LOAD_TIME_KEY, String.valueOf(System.currentTimeMillis()));
      prop.setProperty(Project.CHOP_VERSION_KEY, plugin.getVersion());

      // Save the newly formed properties file under project.properties
      FileUtils.mkdir(
          configPropertiesFilePath.substring(0, configPropertiesFilePath.lastIndexOf('/')));
      FileWriter writer = new FileWriter(configPropertiesFilePath);
      prop.store(writer, "Generated with chop:runner");

      // Create the final runner file
      String finalPath = getRunnerFile().getAbsolutePath();
      File finalFile = new File(finalPath);
      Utils.archiveWar(finalFile, extractedRunnerPath);

      // Attempt to attach the runner file with the chop classifier
      projectHelper.attachArtifact(project, finalFile, "chop");
    } catch (MojoExecutionException e) {
      throw e;
    } catch (Exception e) {
      e.printStackTrace();
      throw new MojoExecutionException("Error while executing plugin", e);
    }
  }
Esempio n. 12
0
 private void deployArtifact() {
   if (FILE_FEATURE_PROFILE != null && FILE_FEATURE_PROFILE.exists()) {
     project.getArtifact().setFile(FILE_FEATURE_PROFILE);
     projectHelper.attachArtifact(project, "zip", null, FILE_FEATURE_PROFILE);
   }
 }
Esempio n. 13
0
  protected void generateAggregatedZip(
      MavenProject rootProject,
      List<MavenProject> reactorProjects,
      Set<MavenProject> pomZipProjects)
      throws IOException, MojoExecutionException {
    File projectBaseDir = rootProject.getBasedir();
    String rootProjectGroupId = rootProject.getGroupId();
    String rootProjectArtifactId = rootProject.getArtifactId();
    String rootProjectVersion = rootProject.getVersion();

    String aggregatedZipFileName =
        "target/" + rootProjectArtifactId + "-" + rootProjectVersion + "-app.zip";
    File projectOutputFile = new File(projectBaseDir, aggregatedZipFileName);
    getLog()
        .info(
            "Generating "
                + projectOutputFile.getAbsolutePath()
                + " from root project "
                + rootProjectArtifactId);
    File projectBuildDir = new File(projectBaseDir, reactorProjectOutputPath);

    if (projectOutputFile.exists()) {
      projectOutputFile.delete();
    }
    createAggregatedZip(
        projectBaseDir,
        projectBuildDir,
        reactorProjectOutputPath,
        projectOutputFile,
        includeReadMe,
        pomZipProjects);
    if (rootProject.getAttachedArtifacts() != null) {
      // need to remove existing as otherwise we get a WARN
      Artifact found = null;
      for (Artifact artifact : rootProject.getAttachedArtifacts()) {
        if (artifactClassifier != null
            && artifact.hasClassifier()
            && artifact.getClassifier().equals(artifactClassifier)) {
          found = artifact;
          break;
        }
      }
      if (found != null) {
        rootProject.getAttachedArtifacts().remove(found);
      }
    }

    getLog()
        .info(
            "Attaching aggregated zip "
                + projectOutputFile
                + " to root project "
                + rootProject.getArtifactId());
    projectHelper.attachArtifact(rootProject, artifactType, artifactClassifier, projectOutputFile);

    // if we are doing an install goal, then also install the aggregated zip manually
    // as maven will install the root project first, and then build the reactor projects, and at
    // this point
    // it does not help to attach artifact to root project, as those artifacts will not be installed
    // so we need to install manually
    List<String> activeProfileIds = new ArrayList<>();
    List<Profile> activeProfiles = rootProject.getActiveProfiles();
    if (activeProfiles != null) {
      for (Profile profile : activeProfiles) {
        String id = profile.getId();
        if (Strings.isNotBlank(id)) {
          activeProfileIds.add(id);
        }
      }
    }
    if (rootProject.hasLifecyclePhase("install")) {
      getLog().info("Installing aggregated zip " + projectOutputFile);
      InvocationRequest request = new DefaultInvocationRequest();
      request.setBaseDirectory(rootProject.getBasedir());
      request.setPomFile(new File("./pom.xml"));
      request.setGoals(Collections.singletonList("install:install-file"));
      request.setRecursive(false);
      request.setInteractive(false);
      request.setProfiles(activeProfileIds);

      Properties props = new Properties();
      props.setProperty("file", aggregatedZipFileName);
      props.setProperty("groupId", rootProjectGroupId);
      props.setProperty("artifactId", rootProjectArtifactId);
      props.setProperty("version", rootProjectVersion);
      props.setProperty("classifier", "app");
      props.setProperty("packaging", "zip");
      props.setProperty("generatePom", "false");
      request.setProperties(props);

      getLog()
          .info(
              "Installing aggregated zip using: mvn install:install-file"
                  + serializeMvnProperties(props));
      Invoker invoker = new DefaultInvoker();
      try {
        InvocationResult result = invoker.execute(request);
        if (result.getExitCode() != 0) {
          throw new IllegalStateException("Error invoking Maven goal install:install-file");
        }
      } catch (MavenInvocationException e) {
        throw new MojoExecutionException("Error invoking Maven goal install:install-file", e);
      }
    }

    if (rootProject.hasLifecyclePhase("deploy")) {

      if (deploymentRepository == null && Strings.isNullOrBlank(altDeploymentRepository)) {
        String msg =
            "Cannot run deploy phase as Maven project has no <distributionManagement> with the maven url to use for deploying the aggregated zip file, neither an altDeploymentRepository property.";
        getLog().warn(msg);
        throw new MojoExecutionException(msg);
      }

      getLog()
          .info(
              "Deploying aggregated zip "
                  + projectOutputFile
                  + " to root project "
                  + rootProject.getArtifactId());
      getLog()
          .info(
              "Using deploy goal: "
                  + deployFileGoal
                  + " with active profiles: "
                  + activeProfileIds);

      InvocationRequest request = new DefaultInvocationRequest();
      request.setBaseDirectory(rootProject.getBasedir());
      request.setPomFile(new File("./pom.xml"));
      request.setGoals(Collections.singletonList(deployFileGoal));
      request.setRecursive(false);
      request.setInteractive(false);
      request.setProfiles(activeProfileIds);
      request.setProperties(getProject().getProperties());

      Properties props = new Properties();
      props.setProperty("file", aggregatedZipFileName);
      props.setProperty("groupId", rootProjectGroupId);
      props.setProperty("artifactId", rootProjectArtifactId);
      props.setProperty("version", rootProjectVersion);
      props.setProperty("classifier", "app");
      props.setProperty("packaging", "zip");
      String deployUrl = null;

      if (!Strings.isNullOrBlank(deployFileUrl)) {
        deployUrl = deployFileUrl;
      } else if (altDeploymentRepository != null && altDeploymentRepository.contains("::")) {
        deployUrl =
            altDeploymentRepository.substring(altDeploymentRepository.lastIndexOf("::") + 2);
      } else {
        deployUrl = deploymentRepository.getUrl();
      }

      props.setProperty("url", deployUrl);
      props.setProperty("repositoryId", deploymentRepository.getId());
      props.setProperty("generatePom", "false");
      request.setProperties(props);

      getLog()
          .info(
              "Deploying aggregated zip using: mvn deploy:deploy-file"
                  + serializeMvnProperties(props));
      Invoker invoker = new DefaultInvoker();
      try {
        InvocationResult result = invoker.execute(request);
        if (result.getExitCode() != 0) {
          throw new IllegalStateException("Error invoking Maven goal deploy:deploy-file");
        }
      } catch (MavenInvocationException e) {
        throw new MojoExecutionException("Error invoking Maven goal deploy:deploy-file", e);
      }
    }
  }
Esempio n. 14
0
  protected void generateZip()
      throws DependencyTreeBuilderException, MojoExecutionException, IOException,
          MojoFailureException {

    File appBuildDir = buildDir;
    if (Strings.isNotBlank(pathInZip)) {
      appBuildDir = new File(buildDir, pathInZip);
    }
    appBuildDir.mkdirs();

    if (hasConfigDir()) {
      copyAppConfigFiles(appBuildDir, appConfigDir);

    } else {
      getLog()
          .info(
              "The app configuration files directory "
                  + appConfigDir
                  + " doesn't exist, so not copying any additional project documentation or configuration files");
    }
    MavenProject project = getProject();

    if (!ignoreProject) {
      File kubernetesJson = getKubernetesJson();
      if (kubernetesJson != null && kubernetesJson.isFile() && kubernetesJson.exists()) {
        File jsonFile = new File(appBuildDir, "kubernetes.json");
        jsonFile.getParentFile().mkdirs();
        Files.copy(kubernetesJson, jsonFile);
      }

      // TODO if no iconRef is specified we could try guess based on the project?

      // lets check if we can use an icon reference
      copyIconToFolder(appBuildDir);
    }

    // lets only generate a app zip if we have a requirement (e.g. we're not a parent pom packaging
    // project) and
    // we have defined some configuration files or dependencies
    // to avoid generating dummy apps for parent poms
    if (hasConfigDir() || !ignoreProject) {

      if (includeReadMe) {
        copyReadMe(appBuildDir);
      }

      if (generateSummaryFile) {
        copySummaryText(appBuildDir);
      }

      if (generateAppPropertiesFile) {
        String name = project.getName();
        if (Strings.isNullOrBlank(name)) {
          name = project.getArtifactId();
        }
        String description = project.getDescription();
        Properties appProperties = new Properties();
        appProperties.put("name", name);
        if (Strings.isNotBlank(description)) {
          appProperties.put("description", description);
        }
        appProperties.put("groupId", project.getGroupId());
        appProperties.put("artifactId", project.getArtifactId());
        appProperties.put("version", project.getVersion());
        File appPropertiesFile = new File(appBuildDir, "fabric8.properties");
        appPropertiesFile.getParentFile().mkdirs();
        if (!appPropertiesFile.exists()) {
          appProperties.store(new FileWriter(appPropertiesFile), "Fabric8 Properties");
        }
      }

      File outputZipFile = getZipFile();
      File legalDir = null;
      if (includeLegal) {
        legalDir = new File(project.getBuild().getOutputDirectory(), "META-INF");
      }
      Zips.createZipFile(getLog(), buildDir, outputZipFile, legalDir);

      projectHelper.attachArtifact(project, artifactType, artifactClassifier, outputZipFile);
      getLog().info("Created app zip file: " + outputZipFile);
    }
  }
  public void execute() throws MojoExecutionException, MojoFailureException {
    if (this.skip) {
      getLog().info("skip execution");
      return;
    }
    // project.addAttachedArtifact(  );
    File warExecFile = new File(buildDirectory, finalName);
    if (warExecFile.exists()) {
      warExecFile.delete();
    }

    File execWarJar = new File(buildDirectory, finalName);

    FileOutputStream execWarJarOutputStream = null;
    ArchiveOutputStream os = null;
    File tmpPropertiesFile = null;
    File tmpManifestFile = null;
    FileOutputStream tmpPropertiesFileOutputStream = null;
    PrintWriter tmpManifestWriter = null;

    try {

      tmpPropertiesFile = new File(buildDirectory, "war-exec.properties");
      if (tmpPropertiesFile.exists()) {
        tmpPropertiesFile.delete();
      }
      tmpPropertiesFile.getParentFile().mkdirs();

      tmpManifestFile = new File(buildDirectory, "war-exec.manifest");
      if (tmpManifestFile.exists()) {
        tmpManifestFile.delete();
      }
      tmpPropertiesFileOutputStream = new FileOutputStream(tmpPropertiesFile);
      execWarJar.getParentFile().mkdirs();
      execWarJar.createNewFile();
      execWarJarOutputStream = new FileOutputStream(execWarJar);

      tmpManifestWriter = new PrintWriter(tmpManifestFile);

      // store :
      // * wars in the root: foo.war
      // * tomcat jars
      // * file tomcat.standalone.properties with possible values :
      //   * useServerXml=true/false to use directly the one provided
      //   * enableNaming=true/false
      //   * wars=foo.war|contextpath;bar.war  ( |contextpath is optionnal if empty use the war name
      // )
      //   * accessLogValveFormat=
      //   * connectorhttpProtocol: HTTP/1.1 or org.apache.coyote.http11.Http11NioProtocol
      // * optionnal: conf/ with usual tomcat configuration files
      // * MANIFEST with Main-Class

      Properties properties = new Properties();

      properties.put(
          Tomcat7Runner.ARCHIVE_GENERATION_TIMESTAMP_KEY,
          Long.toString(System.currentTimeMillis()));
      properties.put(Tomcat7Runner.ENABLE_NAMING_KEY, Boolean.toString(enableNaming));
      properties.put(Tomcat7Runner.ACCESS_LOG_VALVE_FORMAT_KEY, accessLogValveFormat);
      properties.put(Tomcat7Runner.HTTP_PROTOCOL_KEY, connectorHttpProtocol);

      os =
          new ArchiveStreamFactory()
              .createArchiveOutputStream(ArchiveStreamFactory.JAR, execWarJarOutputStream);

      if ("war".equals(project.getPackaging())) {

        os.putArchiveEntry(new JarArchiveEntry(StringUtils.removeStart(path, "/") + ".war"));
        IOUtils.copy(new FileInputStream(projectArtifact.getFile()), os);
        os.closeArchiveEntry();

        properties.put(Tomcat7Runner.WARS_KEY, StringUtils.removeStart(path, "/") + ".war|" + path);
      } else if (warRunDependencies != null && !warRunDependencies.isEmpty()) {
        for (WarRunDependency warRunDependency : warRunDependencies) {
          if (warRunDependency.dependency != null) {
            Dependency dependency = warRunDependency.dependency;
            Artifact artifact =
                artifactFactory.createArtifactWithClassifier(
                    dependency.getGroupId(),
                    dependency.getArtifactId(),
                    dependency.getVersion(),
                    dependency.getType(),
                    dependency.getClassifier());

            artifactResolver.resolve(artifact, this.remoteRepos, this.local);

            File warFileToBundle = new File(resolvePluginWorkDir(), artifact.getFile().getName());
            FileUtils.copyFile(artifact.getFile(), warFileToBundle);

            if (warRunDependency.contextXml != null) {
              warFileToBundle = addContextXmlToWar(warRunDependency.contextXml, warFileToBundle);
            }
            final String warFileName = artifact.getFile().getName();
            os.putArchiveEntry(new JarArchiveEntry(warFileName));
            IOUtils.copy(new FileInputStream(warFileToBundle), os);
            os.closeArchiveEntry();
            String propertyWarValue = properties.getProperty(Tomcat7Runner.WARS_KEY);
            String contextPath =
                StringUtils.isEmpty(warRunDependency.contextPath)
                    ? "/"
                    : warRunDependency.contextPath;
            if (propertyWarValue != null) {
              properties.put(
                  Tomcat7Runner.WARS_KEY, propertyWarValue + ";" + warFileName + "|" + contextPath);
            } else {
              properties.put(Tomcat7Runner.WARS_KEY, warFileName + "|" + contextPath);
            }
          }
        }
      }

      if (serverXml != null && serverXml.exists()) {
        os.putArchiveEntry(new JarArchiveEntry("conf/server.xml"));
        IOUtils.copy(new FileInputStream(serverXml), os);
        os.closeArchiveEntry();
        properties.put(Tomcat7Runner.USE_SERVER_XML_KEY, Boolean.TRUE.toString());
      } else {
        properties.put(Tomcat7Runner.USE_SERVER_XML_KEY, Boolean.FALSE.toString());
      }

      os.putArchiveEntry(new JarArchiveEntry("conf/web.xml"));
      IOUtils.copy(getClass().getResourceAsStream("/conf/web.xml"), os);
      os.closeArchiveEntry();

      properties.store(tmpPropertiesFileOutputStream, "created by Apache Tomcat Maven plugin");

      tmpPropertiesFileOutputStream.flush();
      tmpPropertiesFileOutputStream.close();

      os.putArchiveEntry(new JarArchiveEntry(Tomcat7RunnerCli.STAND_ALONE_PROPERTIES_FILENAME));
      IOUtils.copy(new FileInputStream(tmpPropertiesFile), os);
      os.closeArchiveEntry();

      // add tomcat classes
      for (Artifact pluginArtifact : pluginArtifacts) {
        if (StringUtils.equals("org.apache.tomcat", pluginArtifact.getGroupId())
            || StringUtils.equals("org.apache.tomcat.embed", pluginArtifact.getGroupId())
            || StringUtils.equals("org.eclipse.jdt.core.compiler", pluginArtifact.getGroupId())
            || StringUtils.equals("commons-cli", pluginArtifact.getArtifactId())
            || StringUtils.equals("tomcat7-war-runner", pluginArtifact.getArtifactId())) {
          JarFile jarFile = new JarFile(pluginArtifact.getFile());
          extractJarToArchive(jarFile, os);
        }
      }

      // add extra dependencies
      if (extraDependencies != null && !extraDependencies.isEmpty()) {
        for (Dependency dependency : extraDependencies) {
          // String groupId, String artifactId, String version, String scope, String type
          Artifact artifact =
              artifactFactory.createArtifact(
                  dependency.getGroupId(),
                  dependency.getArtifactId(),
                  dependency.getVersion(),
                  dependency.getScope(),
                  dependency.getType());

          artifactResolver.resolve(artifact, this.remoteRepos, this.local);
          JarFile jarFile = new JarFile(artifact.getFile());
          extractJarToArchive(jarFile, os);
        }
      }

      Manifest manifest = new Manifest();

      Manifest.Attribute mainClassAtt = new Manifest.Attribute();
      mainClassAtt.setName("Main-Class");
      mainClassAtt.setValue(mainClass);
      manifest.addConfiguredAttribute(mainClassAtt);

      manifest.write(tmpManifestWriter);
      tmpManifestWriter.flush();
      tmpManifestWriter.close();

      os.putArchiveEntry(new JarArchiveEntry("META-INF/MANIFEST.MF"));
      IOUtils.copy(new FileInputStream(tmpManifestFile), os);
      os.closeArchiveEntry();

      if (attachArtifact) {
        // MavenProject project, String artifactType, String artifactClassifier, File artifactFile
        projectHelper.attachArtifact(
            project, attachArtifactClassifierType, attachArtifactClassifier, execWarJar);
      }

      if (extraResources != null) {
        for (ExtraResource extraResource : extraResources) {

          DirectoryScanner directoryScanner = new DirectoryScanner();
          directoryScanner.setBasedir(extraResource.getDirectory());
          directoryScanner.addDefaultExcludes();
          directoryScanner.setExcludes(toStringArray(extraResource.getExcludes()));
          directoryScanner.setIncludes(toStringArray(extraResource.getIncludes()));
          directoryScanner.scan();
          for (String includeFile : directoryScanner.getIncludedFiles()) {
            getLog().debug("include file:" + includeFile);
            os.putArchiveEntry(new JarArchiveEntry(includeFile));
            IOUtils.copy(
                new FileInputStream(new File(extraResource.getDirectory(), includeFile)), os);
            os.closeArchiveEntry();
          }
        }
      }

      if (tomcatConfigurationFilesDirectory != null && tomcatConfigurationFilesDirectory.exists()) {
        // Because its the tomcat default dir for configs
        String aConfigOutputDir = "conf/";
        copyDirectoryContentIntoArchive(tomcatConfigurationFilesDirectory, aConfigOutputDir, os);
      }

    } catch (ManifestException e) {
      throw new MojoExecutionException(e.getMessage(), e);
    } catch (IOException e) {
      throw new MojoExecutionException(e.getMessage(), e);
    } catch (ArchiveException e) {
      throw new MojoExecutionException(e.getMessage(), e);
    } catch (ArtifactNotFoundException e) {
      throw new MojoExecutionException(e.getMessage(), e);
    } catch (ArtifactResolutionException e) {
      throw new MojoExecutionException(e.getMessage(), e);
    } finally {
      IOUtils.closeQuietly(os);
      IOUtils.closeQuietly(tmpManifestWriter);
      IOUtils.closeQuietly(execWarJarOutputStream);
      IOUtils.closeQuietly(tmpPropertiesFileOutputStream);
    }
  }
  @Override
  public void execute() throws MojoExecutionException, MojoFailureException {

    String xprojZipFileName =
        project.getArtifactId() + "-" + XCODEPROJ_WITH_DEPS_CLASSIFIER + ".zip";

    final String projectBuildDirectory = project.getBuild().getDirectory();

    try {
      final File targetFolder = new File(projectBuildDirectory);

      FileUtils.mkdirs(targetFolder);

      String relativeTargetDirName =
          FileUtils.getRelativePath(
              projectBuildDirectory, project.getBasedir().getAbsolutePath(), "/");
      String relativeSrcDirName =
          FileUtils.getRelativePath(
              FolderLayout.getSourceFolder(project).getAbsolutePath(),
              project.getBasedir().getAbsolutePath(),
              "/");

      Set<String> includes = new HashSet<String>();

      includes.add(relativeSrcDirName); // src/xcode folder
      includes.add(relativeTargetDirName + "/xcode-deps/frameworks");

      zip(
          Arrays.asList("zip", "-r", "-y", "-q", relativeTargetDirName + "/" + xprojZipFileName),
          includes,
          excludes);

      includes.clear();

      includes.add("pom.xml");
      includes.add("sync.info");
      includes.add(relativeTargetDirName + "/bundles");
      includes.add(relativeTargetDirName + "/headers");
      includes.add(relativeTargetDirName + "/libs");
      includes.add(relativeTargetDirName + "/xcode-deps");

      Collection<String> myExcludes =
          excludes == null ? new ArrayList<String>() : new ArrayList<String>(excludes);
      myExcludes.add(relativeTargetDirName + "/xcode-deps/frameworks/*");

      if (additionalArchivePaths != null) {
        includes.addAll(additionalArchivePaths);
      }

      zip(
          Arrays.asList("zip", "-r", "-g", "-q", relativeTargetDirName + "/" + xprojZipFileName),
          includes,
          myExcludes);

      getLog()
          .info(
              "Packaged the Xcode project with all its dependencies into the zip file "
                  + xprojZipFileName);
    } catch (IOException e) {
      throw new MojoExecutionException(
          "Could not package the Xcode project with all its dependencies into a zip file.", e);
    }

    projectHelper.attachArtifact(
        project,
        "zip",
        XCODEPROJ_WITH_DEPS_CLASSIFIER,
        new File(projectBuildDirectory, xprojZipFileName));
  }