/**
   * Lists remote packages available for install using {@link UpdaterData#updateOrInstallAll_NoGUI}.
   *
   * @param includeAll True to list and install all packages, including obsolete ones.
   * @param extendedOutput True to display more details on each package.
   */
  public void listRemotePackages_NoGUI(boolean includeAll, boolean extendedOutput) {

    List<ArchiveInfo> archives = getRemoteArchives_NoGUI(includeAll);

    mSdkLog.info("Packages available for installation or update: %1$d\n", archives.size());

    int index = 1;
    for (ArchiveInfo ai : archives) {
      Archive a = ai.getNewArchive();
      if (a != null) {
        Package p = a.getParentPackage();
        if (p != null) {
          if (extendedOutput) {
            mSdkLog.info("----------\n");
            mSdkLog.info("id: %1$d or \"%2$s\"\n", index, p.installId());
            mSdkLog.info(
                "     Type: %1$s\n",
                p.getClass()
                    .getSimpleName()
                    .replaceAll("Package", "")); // $NON-NLS-1$ //$NON-NLS-2$
            String desc = LineUtil.reformatLine("     Desc: %s\n", p.getLongDescription());
            mSdkLog.info("%s", desc); // $NON-NLS-1$
          } else {
            mSdkLog.info("%1$ 4d- %2$s\n", index, p.getShortDescription());
          }
          index++;
        }
      }
    }
  }
    private int getDependencyOrder(ArchiveInfo ai) {
      if (ai == null) {
        return 0;
      }

      // reuse cached value, if any
      Integer cached = mOrders.get(ai);
      if (cached != null) {
        return cached.intValue();
      }

      ArchiveInfo[] deps = ai.getDependsOn();
      if (deps == null) {
        return 0;
      }

      // compute dependencies, recursively
      int n = deps.length;

      for (ArchiveInfo dep : deps) {
        n += getDependencyOrder(dep);
      }

      // cache it
      mOrders.put(ai, Integer.valueOf(n));

      return n;
    }
Example #3
0
  private License getArchiveInfoLicense(ArchiveInfo ai) {
    Archive a = ai.getNewArchive();
    if (a != null) {
      Package p = a.getParentPackage();
      if (p != null) {
        License lic = p.getLicense();
        if (lic != null
            && lic.getLicenseRef() != null
            && !lic.getLicense().isEmpty()
            && lic.getLicense() != null
            && !lic.getLicense().isEmpty()) {
          return lic;
        }
      }
    }

    return null;
  }
Example #4
0
  private static void addDependencies(
      @NonNull List<ArchiveInfo> dependencies,
      @NonNull ArchiveInfo archive,
      @NonNull Set<ArchiveInfo> visited) {
    if (visited.contains(archive)) {
      return;
    }
    visited.add(archive);

    ArchiveInfo[] dependsOn = archive.getDependsOn();
    if (dependsOn != null) {
      for (ArchiveInfo dependency : dependsOn) {
        if (!dependencies.contains(dependency)) {
          dependencies.add(dependency);
          addDependencies(dependencies, dependency, visited);
        }
      }
    }
  }
Example #5
0
  /**
   * Get list of each asset to be replaced, and the shots it's in.
   *
   * @return
   * @throws PipelineException
   */
  private boolean getShotsUsingAssets() throws PipelineException {
    ArrayList<ArchiveInfo> archive = mclient.archiveQuery(shotPattern, null);

    logLine("Looking for shots using lo-res assets.");
    for (ArchiveInfo curArc : archive) {
      String name = curArc.getName();
      VersionID vid = curArc.getVersionID();
      TreeSet<VersionID> allVers = mclient.getCheckedInVersionIDs(name);
      if (!vid.equals(allVers.last())) continue;

      NodeVersion ver = mclient.getCheckedInVersion(name, vid);
      Set<String> srcs = ver.getSourceNames();

      for (String loResAsset : pAssetManager.keySet()) {
        if (srcs.contains(loResAsset)) {
          // TODO chec if latest.

          logLine("\t" + getShortName(loResAsset) + ": " + getShortName(name));

          AssetInfo tempInfo = pAssetManager.get(loResAsset);

          if (!tempInfo.getLoHiResShots().containsKey(name))
            tempInfo.getLoHiResShots().put(name, null);
        } // end if
      } // end for
    } // end for

    logLine("Looking for shots using hi-res assets");
    /* - Populate lo-res */
    for (ArchiveInfo curArc : archive) {
      String name = curArc.getName();
      VersionID vid = curArc.getVersionID();
      TreeSet<VersionID> allVers = mclient.getCheckedInVersionIDs(name);
      if (!vid.equals(allVers.last())) continue;

      NodeVersion ver = mclient.getCheckedInVersion(name, vid);
      Set<String> srcs = ver.getSourceNames();

      for (String updateAsset : pAssetManager.keySet()) {
        String hiResAsset = updateAsset.replace(lr, "");
        if (srcs.contains(hiResAsset)) {
          logLine("\t" + getShortName(hiResAsset) + ": " + getShortName(name));
          AssetInfo tempInfo = pAssetManager.get(updateAsset);

          String loRes = tempInfo.getMatchingLoResShot(name);
          if (loRes == null) {
            logLine(
                "!!!\nWARNING:"
                    + getShortName(hiResAsset)
                    + " is used in the "
                    + getShortName(name)
                    + " node which has no matching lo-res model in an anim node."
                    + " So it will not be changed\n!!!");
            continue;
          }

          tempInfo.getLoHiResShots().put(loRes, name);
        } // end if
      } // end for
    } // end for(ArchiveInfo)

    logLine("");

    for (String updateAsset : potentialUpdates) {
      TreeMap<String, String> shots = pAssetManager.get(updateAsset).getLoHiResShots();
      if (shots.isEmpty()) {
        logLine(getShortName(updateAsset) + " is not used in any shots");
        pAssetManager.remove(updateAsset);
      }
      for (String loRes : shots.keySet()) {
        if (shots.get(loRes) == null)
          logLine(
              getShortName(updateAsset)
                  + " is in a hi-res shot, "
                  + getShortName(loRes)
                  + ", but doesn't have a matching hi-res"
                  + "model in the lgt node.");
      }
    }

    if (pAssetManager.isEmpty()) return false;

    return true;
  } // end getShotsUsingAssets
  /**
   * Tries to update all the *existing* local packages. This version is intended to run without a
   * GUI and only outputs to the current {@link ILogger}.
   *
   * @param pkgFilter A list of {@link SdkRepoConstants#NODES} or {@link Package#installId()} or
   *     package indexes to limit the packages we can update or install. A null or empty list means
   *     to update everything possible.
   * @param includeAll True to list and install all packages, including obsolete ones.
   * @param dryMode True to check what would be updated/installed but do not actually download or
   *     install anything.
   * @return A list of archives that have been installed. Can be null if nothing was done.
   */
  public List<Archive> updateOrInstallAll_NoGUI(
      Collection<String> pkgFilter, boolean includeAll, boolean dryMode) {

    List<ArchiveInfo> archives = getRemoteArchives_NoGUI(includeAll);

    // Filter the selected archives to only keep the ones matching the filter
    if (pkgFilter != null && pkgFilter.size() > 0 && archives != null && archives.size() > 0) {
      // Map filter types to an SdkRepository Package type,
      // e.g. create a map "platform" => PlatformPackage.class
      HashMap<String, Class<? extends Package>> pkgMap =
          new HashMap<String, Class<? extends Package>>();

      mapFilterToPackageClass(pkgMap, SdkRepoConstants.NODES);
      mapFilterToPackageClass(pkgMap, SdkAddonConstants.NODES);

      // Prepare a map install-id => package instance
      HashMap<String, Package> installIdMap = new HashMap<String, Package>();
      for (ArchiveInfo ai : archives) {
        Archive a = ai.getNewArchive();
        if (a != null) {
          Package p = a.getParentPackage();
          if (p != null) {
            String id = p.installId();
            if (id != null && id.length() > 0 && !installIdMap.containsKey(id)) {
              installIdMap.put(id, p);
            }
          }
        }
      }

      // Now intersect this with the pkgFilter requested by the user, in order to
      // only keep the classes that the user wants to install.
      // We also create a set with the package indices requested by the user
      // and a set of install-ids requested by the user.

      HashSet<Class<? extends Package>> userFilteredClasses =
          new HashSet<Class<? extends Package>>();
      SparseIntArray userFilteredIndices = new SparseIntArray();
      Set<String> userFilteredInstallIds = new HashSet<String>();

      for (String type : pkgFilter) {
        if (installIdMap.containsKey(type)) {
          userFilteredInstallIds.add(type);

        } else if (type.replaceAll("[0-9]+", "").length() == 0) { // $NON-NLS-1$ //$NON-NLS-2$
          // An all-digit number is a package index requested by the user.
          int index = Integer.parseInt(type);
          userFilteredIndices.put(index, index);

        } else if (pkgMap.containsKey(type)) {
          userFilteredClasses.add(pkgMap.get(type));

        } else {
          // This should not happen unless there's a mismatch in the package map.
          mSdkLog.error(null, "Ignoring unknown package filter '%1$s'", type);
        }
      }

      // we don't need the maps anymore
      pkgMap = null;
      installIdMap = null;

      // Now filter the remote archives list to keep:
      // - any package which class matches userFilteredClasses
      // - any package index which matches userFilteredIndices
      // - any package install id which matches userFilteredInstallIds

      int index = 1;
      for (Iterator<ArchiveInfo> it = archives.iterator(); it.hasNext(); ) {
        boolean keep = false;
        ArchiveInfo ai = it.next();
        Archive a = ai.getNewArchive();
        if (a != null) {
          Package p = a.getParentPackage();
          if (p != null) {
            if (userFilteredInstallIds.contains(p.installId())
                || userFilteredClasses.contains(p.getClass())
                || userFilteredIndices.get(index) > 0) {
              keep = true;
            }

            index++;
          }
        }

        if (!keep) {
          it.remove();
        }
      }

      if (archives.size() == 0) {
        mSdkLog.info(
            LineUtil.reflowLine(
                "Warning: The package filter removed all packages. There is nothing to install.\nPlease consider trying to update again without a package filter.\n"));
        return null;
      }
    }

    if (archives != null && archives.size() > 0) {
      if (dryMode) {
        mSdkLog.info("Packages selected for install:\n");
        for (ArchiveInfo ai : archives) {
          Archive a = ai.getNewArchive();
          if (a != null) {
            Package p = a.getParentPackage();
            if (p != null) {
              mSdkLog.info("- %1$s\n", p.getShortDescription());
            }
          }
        }
        mSdkLog.info("\nDry mode is on so nothing is actually being installed.\n");
      } else {
        return installArchives(archives, NO_TOOLS_MSG);
      }
    } else {
      mSdkLog.info("There is nothing to install or update.\n");
    }

    return null;
  }
Example #7
0
  /**
   * Validates that all archive licenses are accepted.
   *
   * <p>There are 2 cases: <br>
   * - When {@code acceptLicenses} is given, the licenses specified are automatically accepted and
   * all those not specified are automatically rejected. <br>
   * - When {@code acceptLicenses} is empty or null, licenses are collected and there's an input
   * prompt on StdOut to ask a yes/no question. To output, this uses the current {@link #mSdkLog}
   * which should be configured to send {@link ILogger#info(String, Object...)} directly to {@link
   * System#out}. <br>
   * Finally only accepted licenses are kept in the archive list.
   *
   * @param archives The archives to validate.
   * @param acceptLicenseIds A comma-separated list of licenses ids already approved.
   * @param numRetries The number of times the command-line will ask to accept a given license when
   *     the input doesn't match the expected y/n/yes/no answer. Use 0 for infinite. Useful for
   *     unit-tests. Once the number of retries is reached, the license is assumed as rejected.
   * @return True if there are any archives left to install.
   */
  @VisibleForTesting(visibility = Visibility.PRIVATE)
  boolean acceptLicense(List<ArchiveInfo> archives, String acceptLicenseIds, final int numRetries) {
    TreeSet<String> acceptedLids = new TreeSet<String>();
    if (acceptLicenseIds != null) {
      acceptedLids.addAll(Arrays.asList(acceptLicenseIds.split(","))); // $NON-NLS-1$
    }
    boolean automated = !acceptedLids.isEmpty();

    TreeSet<String> rejectedLids = new TreeSet<String>();
    TreeMap<String, License> lidToAccept = new TreeMap<String, License>();
    TreeMap<String, List<String>> lidPkgNames = new TreeMap<String, List<String>>();

    // Find the licenses needed. Include those already accepted.
    for (ArchiveInfo ai : archives) {
      License lic = getArchiveInfoLicense(ai);
      if (lic == null) {
        continue;
      }
      String lid = getLicenseId(lic);
      if (!acceptedLids.contains(lid)) {
        if (automated) {
          // Automatically reject those not already accepted
          rejectedLids.add(lid);
        } else {
          // Queue it to ask for it to be accepted
          lidToAccept.put(lid, lic);
          List<String> list = lidPkgNames.get(lid);
          if (list == null) {
            list = new ArrayList<String>();
            lidPkgNames.put(lid, list);
          }
          list.add(ai.getShortDescription());
        }
      }
    }

    // Ask for each license that needs to be asked manually for confirmation
    nextEntry:
    for (Map.Entry<String, License> entry : lidToAccept.entrySet()) {
      String lid = entry.getKey();
      License lic = entry.getValue();
      mSdkLog.info("-------------------------------\n");
      mSdkLog.info("License id: %1$s\n", lid);
      mSdkLog.info(
          "Used by: \n - %1$s\n", Joiner.on("\n  - ").skipNulls().join(lidPkgNames.get(lid)));
      mSdkLog.info("-------------------------------\n\n");
      mSdkLog.info("%1$s\n", lic.getLicense());

      int retries = numRetries;
      tryAgain:
      while (true) {
        try {
          mSdkLog.info("Do you accept the license '%1$s' [y/n]: ", lid);

          byte[] buffer = new byte[256];
          if (mSdkLog instanceof IReaderLogger) {
            ((IReaderLogger) mSdkLog).readLine(buffer);
          } else {
            System.in.read(buffer);
          }
          mSdkLog.info("\n");

          String reply = new String(buffer, Charsets.UTF_8);
          reply = reply.trim().toLowerCase(Locale.US);

          if ("y".equals(reply) || "yes".equals(reply)) {
            acceptedLids.add(lid);
            continue nextEntry;

          } else if ("n".equals(reply) || "no".equals(reply)) {
            break tryAgain;

          } else {
            mSdkLog.info("Unknown response '%1$s'.\n", reply);
            if (--retries == 0) {
              mSdkLog.info("Max number of retries exceeded. Rejecting '%1$s'\n", lid);
              break tryAgain;
            }
            continue tryAgain;
          }

        } catch (IOException e) {
          // Panic. Don't install anything.
          e.printStackTrace();
          return false;
        }
      }
      rejectedLids.add(lid);
    }

    // Finally remove all archive which license is rejected or not accepted.
    for (Iterator<ArchiveInfo> it = archives.iterator(); it.hasNext(); ) {
      ArchiveInfo ai = it.next();
      License lic = getArchiveInfoLicense(ai);
      if (lic == null) {
        continue;
      }
      String lid = getLicenseId(lic);
      if (rejectedLids.contains(lid) || !acceptedLids.contains(lid)) {
        mSdkLog.info(
            "Package %1$s not installed due to rejected license '%2$s'.\n",
            ai.getShortDescription(), lid);
        it.remove();
      }
    }

    return !archives.isEmpty();
  }