public static void listEntries(SVNRepository repository, String basePath, LrdNode root) throws SVNException { LrdProject project = root.getPath().getProject(); Collection entries = repository.getDir(basePath, -1, null, (Collection) null); Iterator iterator = entries.iterator(); while (iterator.hasNext()) { SVNDirEntry entry = (SVNDirEntry) iterator.next(); String path = ((basePath.length() == 0) ? "" : basePath + "/") + entry.getRelativePath(); if (entry.getKind() == SVNNodeKind.DIR) { int index = path.lastIndexOf('/'); LrdNode node; if (index <= 0) { // ルート直下 node = new LrdNode(new LrdPath(project, path), true); if (path.charAt(0) == '.') { // ルート直下の"."で始まるフォルダは無効とする node.setEnable(false); } root.addSubNode(node); } else { String baseDir = path.substring(0, index); StringTokenizer tokenizer = new StringTokenizer(baseDir, "/"); // LrdNode now = root; // while (tokenizer.hasMoreTokens()) { // String token = tokenizer.nextToken(); // now = now.searchSubNode(token); // } node = new LrdNode(new LrdPath(project, path), true); root.addSubNode(node); } listEntries( repository, (basePath.equals("")) ? entry.getName() : basePath + "/" + entry.getName(), node); } else { // int index = path.lastIndexOf('/'); // LrdNode now = root; // if (index >= 0) { // String baseDir = path.substring(0, index); // StringTokenizer tokenizer = new StringTokenizer(baseDir, "/"); // while (tokenizer.hasMoreTokens()) { // String token = tokenizer.nextToken(); // now = now.searchSubNode(token); // } // } LrdNode node = new LrdNode(new LrdPath(project, path), false); root.addSubNode(node); } } }
private static boolean isProjectRoot(SVNDirEntry directory, Collection<SVNDirEntry> entries) { List<String> projectFolders = new ArrayList<>(Arrays.asList("trunk")); // , // "branches" // )); // //, // "tags")); for (SVNDirEntry entry : entries) { if (!projectFolders.contains(entry.getName())) { // allow spurious extra folder names // return false; } else { projectFolders.remove(entry.getName()); } } if (!projectFolders.isEmpty()) { return false; } return true; }
/* * Called recursively to obtain all entries that make up the repository tree * repository - an SVNRepository which interface is used to carry out the * request, in this case it's a request to get all entries in the directory * located at the path parameter; * * path is a directory path relative to the repository location path (that * is a part of the URL used to create an SVNRepository instance); * */ public static void listEntries(SVNRepository repository, String path) throws SVNException { /* * Gets the contents of the directory specified by path at the latest * revision (for this purpose -1 is used here as the revision number to * mean HEAD-revision) getDir returns a Collection of SVNDirEntry * elements. SVNDirEntry represents information about the directory * entry. Here this information is used to get the entry name, the name * of the person who last changed this entry, the number of the revision * when it was last changed and the entry type to determine whether it's * a directory or a file. If it's a directory listEntries steps into a * next recursion to display the contents of this directory. The third * parameter of getDir is null and means that a user is not interested * in directory properties. The fourth one is null, too - the user * doesn't provide its own Collection instance and uses the one returned * by getDir. */ Collection entries = repository.getDir(path, -1, null, (Collection) null); Iterator iterator = entries.iterator(); while (iterator.hasNext()) { SVNDirEntry entry = (SVNDirEntry) iterator.next(); System.out.println( "/" + (path.equals("") ? "" : path + "/") + entry.getName() + " (author: '" + entry.getAuthor() + "'; revision: " + entry.getRevision() + "; date: " + entry.getDate() + ")"); /* * Checking up if the entry is a directory. */ if (entry.getKind() == SVNNodeKind.DIR) { listEntries(repository, (path.equals("")) ? entry.getName() : path + "/" + entry.getName()); } } }
private ObjectNode getMetaDataFromPath(int revision, String path) throws SVNException, IOException { org.tmatesoft.svn.core.io.SVNRepository repository = getSVNRepository(); SVNNodeKind nodeKind = repository.checkPath(path, revision); if (nodeKind == SVNNodeKind.DIR) { ObjectNode result = Json.newObject(); ObjectNode listData = Json.newObject(); SVNProperties prop = new SVNProperties(); Collection<SVNDirEntry> entries = repository.getDir(path, -1, prop, SVNDirEntry.DIRENT_ALL, (Collection) null); result.put("type", "folder"); for (SVNDirEntry entry : entries) { ObjectNode data = Json.newObject(); String author = entry.getAuthor(); User user = User.findByLoginId(author); Long commitTime = entry.getDate().getTime(); data.put("type", entry.getKind() == SVNNodeKind.DIR ? "folder" : "file"); data.put("msg", entry.getCommitMessage()); data.put("author", author); data.put("avatar", getAvatar(user)); data.put("userName", user.name); data.put("userLoginId", user.loginId); data.put("createdDate", commitTime); data.put("commitMessage", entry.getCommitMessage()); data.put("commiter", author); data.put("commitDate", commitTime); data.put("commitId", entry.getRevision()); data.put( "commitUrl", routes.CodeHistoryApp.show(ownerName, projectName, String.valueOf(entry.getRevision())) .url()); data.put("size", entry.getSize()); listData.put(entry.getName(), data); } result.put("data", listData); return result; } else if (nodeKind == SVNNodeKind.FILE) { return fileAsJson(path, repository); } else { return null; } }
@Override public ObjectNode findFileInfo(String path) throws SVNException { org.tmatesoft.svn.core.io.SVNRepository repository = getSVNRepository(); SVNNodeKind nodeKind = repository.checkPath(path, -1); if (nodeKind == SVNNodeKind.DIR) { // 폴더 내용 출력 ObjectNode result = Json.newObject(); result.put("type", "folder"); ObjectNode listData = Json.newObject(); SVNProperties prop = new SVNProperties(); Collection<SVNDirEntry> entries = repository.getDir(path, -1, prop, SVNDirEntry.DIRENT_ALL, (Collection) null); Iterator<SVNDirEntry> iterator = entries.iterator(); while (iterator.hasNext()) { SVNDirEntry entry = iterator.next(); ObjectNode data = Json.newObject(); String author = entry.getAuthor(); User user = User.findByLoginId(author); data.put("type", entry.getKind() == SVNNodeKind.DIR ? "folder" : "file"); data.put("msg", entry.getCommitMessage()); data.put("author", author); data.put("avatar", getAvatar(user)); data.put("userName", user.name); data.put("userLoginId", user.loginId); data.put("createdDate", entry.getDate().getTime()); listData.put(entry.getName(), data); } result.put("data", listData); return result; } else if (nodeKind == SVNNodeKind.FILE) { // 파일 내용 출력 return fileAsJson(path, repository); } else { return null; } }
/* * Called recursively to obtain all entries that make up the repository tree * repository - an SVNRepository which interface is used to carry out the * request, in this case it's a request to get all entries in the directory * located at the path parameter; * * path is a directory path relative to the repository location path (that * is a part of the URL used to create an SVNRepository instance); */ public static void listEntries(SVNRepository repository, String path) throws SVNException { Tokenizer tokenizer = new Tokenizer(); /* * Gets the contents of the directory specified by path at the latest * revision (for this purpose -1 is used here as the revision number to * mean HEAD-revision) getDir returns a Collection of SVNDirEntry * elements. SVNDirEntry represents information about the directory * entry. Here this information is used to get the entry name, the name * of the person who last changed this entry, the number of the revision * when it was last changed and the entry type to determine whether it's * a directory or a file. If it's a directory listEntries steps into a * next recursion to display the contents of this directory. The third * parameter of getDir is null and means that a user is not interested * in directory properties. The fourth one is null, too - the user * doesn't provide its own Collection instance and uses the one returned * by getDir. */ Collection entries = repository.getDir(path, -1, null, (Collection) null); Iterator iterator = entries.iterator(); while (iterator.hasNext()) { SVNDirEntry entry = (SVNDirEntry) iterator.next(); if (entry.getKind() == SVNNodeKind.DIR) { // listEntries(repository, (path.equals("")) ? entry.getName() // : path + "/" + entry.getName()); } else { String tpath = (path.equals("") ? "" : path + "/") + entry.getName(); ; String filename = url + "/" + tpath; if (Config.isSourceCode(filename)) { // System.out.println(filename); ByteArrayOutputStream baos = new ByteArrayOutputStream(); repository.getFile(tpath, -1, null, baos); InputStream is = new ByteArrayInputStream(baos.toByteArray()); String content; try { content = tokenizer.readAll(is); long hash = tokenizer.getContentHash(filename, content); System.out.print(tpath + " " + hash + "\t"); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }
public void findProjectRoots(String name, String path, List<SVNProjectRoot> list) throws SVNException { Collection<SVNDirEntry> entries = new ArrayList<>(); SVNDirEntry directory = repository.getDir(path, DEFAULT_HEAD_REVISION, false, (Collection<SVNDirEntry>) entries); logger.debug("Inspecting directory " + path); if (isProjectRoot(directory, entries)) { logger.debug("Found project root at {} now looking for branches and tags", path); Set<SVNDirEntry> branches = new HashSet<>(); String branchesPath = path + "/branches"; SVNNodeKind branchesNode = repository.checkPath(branchesPath, -1); if (branchesNode == SVNNodeKind.DIR) { repository.getDir(branchesPath, -1, false, branches); } Set<String> branchNames = branches.stream().map(d -> d.getName()).collect(Collectors.toSet()); logger.debug("Found {} branches: {}", branchNames.size(), branchNames); Set<SVNDirEntry> tags = new HashSet<>(); String tagsPath = path + "/tags"; SVNNodeKind tagsNode = repository.checkPath(tagsPath, -1); if (tagsNode == SVNNodeKind.DIR) { repository.getDir(tagsPath, -1, false, tags); } Set<String> tagNames = tags.stream().map(d -> d.getName()).collect(Collectors.toSet()); logger.debug("Found {} tags: {}", tagNames.size(), tagNames); list.add( new SVNProjectRoot( name, path, directory.getURL().toDecodedString(), branchNames, tagNames)); return; } for (SVNDirEntry entry : entries) { if (entry.getKind() == SVNNodeKind.DIR) { String dirPath = isRootPath(path) ? pathRelativeToRoot(path, entry) : pathRelativeToParent(path, entry); logger.debug("Moving into directory " + dirPath); findProjectRoots(entry.getName(), dirPath, list); } } }
/** validate the value for a remote (repository) location. */ public FormValidation doCheckCredentialsId( StaplerRequest req, @AncestorInPath SCMSourceOwner context, @QueryParameter String remoteBase, @QueryParameter String value) { // TODO suspiciously similar to // SubversionSCM.ModuleLocation.DescriptorImpl.checkCredentialsId; refactor into shared // method? // Test the connection only if we may use the credentials if (context == null && !Jenkins.getActiveInstance().hasPermission(Jenkins.ADMINISTER) || context != null && !context.hasPermission(CredentialsProvider.USE_ITEM)) { return FormValidation.ok(); } // if check remote is reporting an issue then we don't need to String url = Util.fixEmptyAndTrim(remoteBase); if (url == null) return FormValidation.ok(); if (!URL_PATTERN.matcher(url).matches()) return FormValidation.ok(); try { String urlWithoutRevision = SvnHelper.getUrlWithoutRevision(url); SVNURL repoURL = SVNURL.parseURIDecoded(urlWithoutRevision); StandardCredentials credentials = value == null ? null : CredentialsMatchers.firstOrNull( CredentialsProvider.lookupCredentials( StandardCredentials.class, context, ACL.SYSTEM, URIRequirementBuilder.fromUri(repoURL.toString()).build()), CredentialsMatchers.withId(value)); if (checkRepositoryPath(context, repoURL, credentials) != SVNNodeKind.NONE) { // something exists; now check revision if any SVNRevision revision = getRevisionFromRemoteUrl(url); if (revision != null && !revision.isValid()) { return FormValidation.errorWithMarkup( hudson.scm.subversion.Messages.SubversionSCM_doCheckRemote_invalidRevision()); } return FormValidation.ok(); } SVNRepository repository = null; try { repository = getRepository( context, repoURL, credentials, Collections.<String, Credentials>emptyMap(), null); long rev = repository.getLatestRevision(); // now go back the tree and find if there's anything that exists String repoPath = getRelativePath(repoURL, repository); String p = repoPath; while (p.length() > 0) { p = SVNPathUtil.removeTail(p); if (repository.checkPath(p, rev) == SVNNodeKind.DIR) { // found a matching path List<SVNDirEntry> entries = new ArrayList<SVNDirEntry>(); repository.getDir(p, rev, false, entries); // build up the name list List<String> paths = new ArrayList<String>(); for (SVNDirEntry e : entries) if (e.getKind() == SVNNodeKind.DIR) paths.add(e.getName()); String head = SVNPathUtil.head(repoPath.substring(p.length() + 1)); String candidate = EditDistance.findNearest(head, paths); return FormValidation.error( hudson.scm.subversion.Messages.SubversionSCM_doCheckRemote_badPathSuggest( p, head, candidate != null ? "/" + candidate : "")); } } return FormValidation.error( hudson.scm.subversion.Messages.SubversionSCM_doCheckRemote_badPath(repoPath)); } finally { if (repository != null) repository.closeSession(); } } catch (SVNException e) { LOGGER.log(Level.INFO, "Failed to access subversion repository " + url, e); String message = hudson.scm.subversion.Messages.SubversionSCM_doCheckRemote_exceptionMsg1( Util.escape(url), Util.escape(e.getErrorMessage().getFullMessage()), "javascript:document.getElementById('svnerror').style.display='block';" + "document.getElementById('svnerrorlink').style.display='none';" + "return false;") + "<br/><pre id=\"svnerror\" style=\"display:none\">" + Functions.printThrowable(e) + "</pre>"; return FormValidation.errorWithMarkup(message); } }
private String pathRelativeToRoot(String path, SVNDirEntry entry) { return path + entry.getName(); }
private String pathRelativeToParent(String path, SVNDirEntry entry) { return path + PATH_SEPARATOR + entry.getName(); }
private void doList( SVNRepository repos, long rev, final ISVNDirEntryHandler handler, boolean fetchLocks, SVNDepth depth, int entryFields, SVNURL externalParentUrl, String externalTarget) throws SVNException { boolean includeExternals = !getOperation().isIgnoreExternals(); Map<SVNURL, SVNPropertyValue> externals = includeExternals ? new HashMap<SVNURL, SVNPropertyValue>() : null; SVNURL url = repos.getLocation(); SVNURL reposRoot = repos.getRepositoryRoot(false); SVNDirEntry entry = null; SVNException error = null; try { entry = repos.info("", rev); } catch (SVNException svne) { if (svne.getErrorMessage().getErrorCode() == SVNErrorCode.RA_NOT_IMPLEMENTED) { error = svne; } else { throw svne; } } if (error != null) { SVNNodeKind kind = repos.checkPath("", rev); if (kind != SVNNodeKind.NONE) { if (!url.equals(reposRoot)) { String name = SVNPathUtil.tail(repos.getLocation().getPath()); repos.setLocation(repos.getLocation().removePathTail(), false); Collection<SVNDirEntry> dirEntries = repos.getDir("", rev, null, entryFields, (Collection) null); repos.setLocation(url, false); for (Iterator<SVNDirEntry> ents = dirEntries.iterator(); ents.hasNext(); ) { SVNDirEntry dirEntry = (SVNDirEntry) ents.next(); if (name.equals(dirEntry.getName())) { entry = dirEntry; break; } } if (entry != null) { entry.setRelativePath(kind == SVNNodeKind.FILE ? name : ""); } } else { SVNProperties props = new SVNProperties(); repos.getDir("", rev, props, entryFields, (Collection<SVNDirEntry>) null); SVNProperties revProps = repos.getRevisionProperties(rev, null); String author = revProps.getStringValue(SVNRevisionProperty.AUTHOR); String dateStr = revProps.getStringValue(SVNRevisionProperty.DATE); Date datestamp = null; if (dateStr != null) { datestamp = SVNDate.parseDateString(dateStr); } entry = new SVNDirEntry( url, reposRoot, "", kind, 0, !props.isEmpty(), rev, datestamp, author); entry.setRelativePath(""); } } } else if (entry != null) { if (entry.getKind() == SVNNodeKind.DIR) { entry.setName(""); } entry.setRelativePath(entry.getKind() == SVNNodeKind.DIR ? "" : entry.getName()); } if (entry == null) { SVNErrorMessage err = SVNErrorMessage.create( SVNErrorCode.FS_NOT_FOUND, "URL ''{0}'' non-existent in that revision", url); SVNErrorManager.error(err, SVNLogType.WC); } final Map locksMap = new SVNHashMap(); if (fetchLocks) { SVNLock[] locks = new SVNLock[0]; try { locks = repos.getLocks(""); } catch (SVNException e) { if (!(e.getErrorMessage() != null && e.getErrorMessage().getErrorCode() == SVNErrorCode.RA_NOT_IMPLEMENTED)) { throw e; } } if (locks != null && locks.length > 0) { SVNURL root = repos.getRepositoryRoot(true); for (int i = 0; i < locks.length; i++) { String repositoryPath = locks[i].getPath(); locksMap.put(root.appendPath(repositoryPath, false), locks[i]); } } } ISVNDirEntryHandler nestedHandler = new ISVNDirEntryHandler() { public void handleDirEntry(SVNDirEntry dirEntry) throws SVNException { dirEntry.setLock((SVNLock) locksMap.get(dirEntry.getURL())); handler.handleDirEntry(dirEntry); } }; entry.setExternalParentUrl(externalParentUrl); entry.setExternalTarget(externalTarget); nestedHandler.handleDirEntry(entry); if (entry.getKind() == SVNNodeKind.DIR && (depth == SVNDepth.FILES || depth == SVNDepth.IMMEDIATES || depth == SVNDepth.INFINITY)) { list( repos, "", rev, depth, entryFields, externals, externalParentUrl, externalTarget, nestedHandler); } if (includeExternals && externals != null && externals.size() > 0) { listExternals(repos, externals, depth, entryFields, fetchLocks, handler); } }
private static void list( SVNRepository repository, String path, long rev, SVNDepth depth, int entryFields, Map<SVNURL, SVNPropertyValue> externals, SVNURL externalParentUrl, String externalTarget, ISVNDirEntryHandler handler) throws SVNException { if (depth == SVNDepth.EMPTY) { return; } Collection entries = new TreeSet(); SVNProperties properties; try { properties = externals == null ? null : new SVNProperties(); entries = repository.getDir(path, rev, properties, entryFields, entries); } catch (SVNAuthenticationException e) { return; } catch (SVNException e) { if (e.getErrorMessage().getErrorCode() == SVNErrorCode.RA_NOT_AUTHORIZED) { return; } throw e; } SVNPropertyValue svnExternalsVaule = properties == null ? null : properties.getSVNPropertyValue(SVNProperty.EXTERNALS); if (svnExternalsVaule != null) { SVNURL location = repository.getLocation(); externals.put(location.appendPath(path, false), svnExternalsVaule); } for (Iterator iterator = entries.iterator(); iterator.hasNext(); ) { SVNDirEntry entry = (SVNDirEntry) iterator.next(); String childPath = SVNPathUtil.append(path, entry.getName()); entry.setRelativePath(childPath); if (entry.getKind() == SVNNodeKind.FILE || depth == SVNDepth.IMMEDIATES || depth == SVNDepth.INFINITY) { entry.setExternalParentUrl(externalParentUrl); entry.setExternalTarget(externalTarget); handler.handleDirEntry(entry); } if (entry.getKind() == SVNNodeKind.DIR && entry.getDate() != null && depth == SVNDepth.INFINITY) { list( repository, childPath, rev, depth, entryFields, externals, externalParentUrl, externalTarget, handler); } } }