package com.perforce.p4simulink.workspace; /** * Perforce SCM Integration */ import com.mathworks.cmlink.api.FileState; import com.perforce.p4java.server.IOptionsServer; import com.perforce.p4simulink.P4CMException; import com.perforce.p4simulink.connection.Config; import com.perforce.p4simulink.connection.Connection; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import java.io.File; import java.util.*; public class WorkspaceState { private static final Logger log = LogManager.getLogger(WorkspaceState.class.getName()); private final Config config; private final Map<File, FileState> fileStateMap; /** * @param files List of files and directories to check * @param config Perforce connection config * @throws com.perforce.p4simulink.P4CMException */ public WorkspaceState(Collection<File> files, Config config) throws P4CMException { this.config = config; fileStateMap = new HashMap<>(); setFileStateMap(files); } /** * Get the state of the named file or, if it's a directory, all the files under it. * * @param file The file or directory to be checked * @param config Perforce connection config */ public WorkspaceState(File file, Config config) throws P4CMException { this.config = config; fileStateMap = new HashMap<>(); setFileStateMap(file); } public Map<File, FileState> getFileStateMap() { return fileStateMap; } private void setFileStateMap(File file) throws P4CMException { log.debug("Building FileStateMap for single File object"); List<String> filePaths = new ArrayList<>(); if (file.isDirectory()) { if (file.getAbsolutePath().endsWith("/")) { filePaths.add(file.getAbsolutePath() + "..."); } else { filePaths.add(file.getAbsolutePath() + "/..."); } } else { filePaths.add(file.getAbsolutePath()); } reconcileFiles(filePaths); } /** * Iterate over the list of files and build the file state map. * <p/> * If it's a directory, we can skip it and add an empty FileState as * Perforce doesn't version directories. If it's a file, stash the path in * an ArrayList. Once we have a list of all the files to be checked, run a * 'p4 fstat' and a 'p4 reconcile' to find the status of the files in the * workspace. * * @param files List of files and directories to check */ private void setFileStateMap(Collection<File> files) throws P4CMException { log.debug("Building FileStateMap"); List<String> filePaths = new ArrayList<>(); for (File file : files) { if (file.isDirectory()) { fileStateMap.put(file, new P4FileState()); } else { filePaths.add(file.getAbsolutePath()); } } // Nothing to do if filePaths is empty. if (!filePaths.isEmpty()) { reconcileFiles(filePaths); } } /** * Run 'p4 reconcile' against the files in the workspace and work out what * state they're in! * * @param filePaths List of files that need to be reconciled. * @throws P4CMException */ private void reconcileFiles(List<String> filePaths) throws P4CMException { log.debug("Reconciling: {}", filePaths.toString()); String localFile = "localFile"; try (Connection connection = new Connection()) { connection.connect(config); filePaths.addAll(0, Arrays.asList("-n", "-l", "-f")); String[] fileArgs = filePaths.toArray(new String[filePaths.size()]); IOptionsServer server = connection.getServer(); Map<String, Object>[] cmdOutput = server.execMapCmd("reconcile", fileArgs, null); for (Map<String, Object> entry : cmdOutput) { if (entry.containsKey(localFile)) { String localPath = (String) entry.get(localFile); File file = new File(localPath); FileState fileState = new P4FileState(entry); fileStateMap.put(file, fileState); log.trace("File: {}", file.getAbsolutePath()); log.trace("FileState:\n{}", fileState.toString()); } } } catch (Exception e) { P4CMException ex = new P4CMException(e); log.error(ex.getStackTrace()); throw ex; } } }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#4 | 11637 | Paul Allen |
Fix up isLatest, uncheckout, add back code that searched for a .p4rc file within the sandbox directory first, then looks in ~/.p4simulink/ and finally ~/. Transferred from p4://perforce.perforce.com:1666@950121 |
||
#3 | 11636 | Paul Allen |
Updates to integrate with Simulink, merging into one directory. Added auto submits to add, remove, etc since this is what Simulink expects. Transferred from p4://perforce.perforce.com:1666@947024 |
||
#2 | 11635 | Paul Allen |
Updated gradle build to create a "fat jar", fixed some issues with the interfaces when it runs in Simulink itself. Added connection.configuration pane, switched the adapter to use a current changelist which gives a more svn-ish feel (which the Adapter is expecting). Added some more unit tests. General re-factoring. Transferred from p4://perforce.perforce.com:1666@946607 |
||
#1 | 11632 | Paul Allen |
Added commons-exec library, server startup/shutdown for unit tests, fixed a bunch of NPEs. Transferred from p4://perforce.perforce.com:1666@937331 |