<project version="4">\r
<component name="CodeStyleSettingsManager">\r
<option name="PER_PROJECT_SETTINGS">\r
- <value />\r
+ <value>\r
+ <ADDITIONAL_INDENT_OPTIONS fileType="java">\r
+ <option name="INDENT_SIZE" value="4" />\r
+ <option name="CONTINUATION_INDENT_SIZE" value="8" />\r
+ <option name="TAB_SIZE" value="4" />\r
+ <option name="USE_TAB_CHARACTER" value="false" />\r
+ <option name="SMART_TABS" value="false" />\r
+ <option name="LABEL_INDENT_SIZE" value="0" />\r
+ <option name="LABEL_INDENT_ABSOLUTE" value="false" />\r
+ <option name="USE_RELATIVE_INDENTS" value="false" />\r
+ </ADDITIONAL_INDENT_OPTIONS>\r
+ <ADDITIONAL_INDENT_OPTIONS fileType="jsp">\r
+ <option name="INDENT_SIZE" value="4" />\r
+ <option name="CONTINUATION_INDENT_SIZE" value="8" />\r
+ <option name="TAB_SIZE" value="4" />\r
+ <option name="USE_TAB_CHARACTER" value="false" />\r
+ <option name="SMART_TABS" value="false" />\r
+ <option name="LABEL_INDENT_SIZE" value="0" />\r
+ <option name="LABEL_INDENT_ABSOLUTE" value="false" />\r
+ <option name="USE_RELATIVE_INDENTS" value="false" />\r
+ </ADDITIONAL_INDENT_OPTIONS>\r
+ <ADDITIONAL_INDENT_OPTIONS fileType="xml">\r
+ <option name="INDENT_SIZE" value="4" />\r
+ <option name="CONTINUATION_INDENT_SIZE" value="8" />\r
+ <option name="TAB_SIZE" value="4" />\r
+ <option name="USE_TAB_CHARACTER" value="false" />\r
+ <option name="SMART_TABS" value="false" />\r
+ <option name="LABEL_INDENT_SIZE" value="0" />\r
+ <option name="LABEL_INDENT_ABSOLUTE" value="false" />\r
+ <option name="USE_RELATIVE_INDENTS" value="false" />\r
+ </ADDITIONAL_INDENT_OPTIONS>\r
+ </value>\r
</option>\r
</component>\r
</project>\r
- user may tweak download url to download malicious file instead of expected one => checkes required
- Add an API to provide pluginData path without use of ServerPaths class and specifying names explicitly
- Extract interfaces from jetbrains.buildServer.controllers.admin.projects.EditBuildTypeFormFactory#getOrCreateForm to make it available in open API
+ - No Ant Path matcher component to convert relative and absolute patterns to list of files.
API gaps NuGet:
- Allow to call nuget.exe with plugins without installing them into %USERPROFILE%
\r
final List<String> patterns = new ArrayList<String>();\r
for (String _pattern : myParameters.getFiles()) {\r
- final String pattern = _pattern.trim();\r
+ String pattern = _pattern.trim();\r
if (StringUtil.isEmptyOrSpaces(pattern)) {\r
continue;\r
}\r
\r
- final File file = new File(pattern);\r
- if (file.isAbsolute()) {\r
- found = true;\r
- LOG.debug("Found .nugkg to push: " + file);\r
- myCallback.fileFound(file);\r
- continue;\r
+ if (SystemInfo.isWindows\r
+ && (pattern.startsWith("/") || pattern.startsWith("\\"))\r
+ && !(pattern.startsWith("//") || pattern.startsWith("\\\\"))) {\r
+ pattern = pattern.substring(1);\r
+ }\r
+\r
+ if (!pattern.contains("*") && !pattern.contains("?")) {\r
+ final File file = new File(pattern);\r
+ if (file.isAbsolute()) {\r
+ found = true;\r
+ LOG.debug("Found .nugkg to push: " + file);\r
+ myCallback.fileFound(file);\r
+ continue;\r
+ }\r
}\r
\r
patterns.add(pattern.replace('\\', '/'));\r
--- /dev/null
+/*\r
+ * Copyright 2000-2011 JetBrains s.r.o.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package jetbrains.buildServer.nuget.agent.runner.publish.fsScanner;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+public class AntPatternState {\r
+ public enum MatchResult {\r
+ YES,\r
+ NO,\r
+ MAYBELATER\r
+ }\r
+\r
+ private final List<Wildcard> myPatternParts;\r
+ private final List<Integer> myPatternPositions;\r
+\r
+ public AntPatternState(List<Wildcard> patternParts, List<Integer> patternPositions) {\r
+ myPatternParts = patternParts;\r
+ myPatternPositions = patternPositions;\r
+ }\r
+\r
+ public AntPatternState(List<Wildcard> patternParts) {\r
+ this(patternParts, initialList());\r
+ }\r
+\r
+ private static List<Integer> initialList() {\r
+ List<Integer> list = new ArrayList<Integer>();\r
+ list.add(0);\r
+ return list;\r
+ }\r
+\r
+ public List<Integer> PatternPositions() {\r
+ return myPatternPositions;\r
+ }\r
+\r
+ public static class AntPatternStateMatch {\r
+ private final MatchResult myResult;\r
+ private final AntPatternState myState;\r
+\r
+ public AntPatternStateMatch(MatchResult result, AntPatternState state) {\r
+ myResult = result;\r
+ myState = state;\r
+ }\r
+\r
+ public MatchResult getResult() {\r
+ return myResult;\r
+ }\r
+\r
+ public AntPatternState getState() {\r
+ return myState;\r
+ }\r
+ }\r
+\r
+\r
+ public AntPatternStateMatch Enter(String component) {\r
+ if (myPatternParts.size() == 0) {\r
+ return new AntPatternStateMatch(MatchResult.NO, this);\r
+ }\r
+\r
+ MatchResult match = MatchResult.MAYBELATER;\r
+\r
+ //TODO:replace list with array operations\r
+\r
+ List<Integer> newPositions = new ArrayList<Integer>(myPatternPositions.size());\r
+ for (int pos : myPatternPositions) {\r
+ Wildcard wildcard = myPatternParts.get(pos);\r
+ if (wildcard != null) {\r
+ if (wildcard.IsMatch(component))\r
+ if (pos == myPatternParts.size() - 1)\r
+ match = MatchResult.YES;\r
+ else if (pos == myPatternParts.size() - 2 && myPatternParts.get(pos + 1) == null) {\r
+ match = MatchResult.YES;\r
+ newPositions.add(pos + 1);\r
+ } else newPositions.add(pos + 1);\r
+ else if (match == MatchResult.MAYBELATER) match = MatchResult.NO;\r
+ } else {\r
+ // **\r
+ newPositions.add(pos);\r
+\r
+ if (pos == myPatternParts.size() - 1)\r
+ match = MatchResult.YES;\r
+ else {\r
+ if (myPatternParts.get(pos + 1).IsMatch(component)) {\r
+ if (pos == myPatternParts.size() - 2)\r
+ match = MatchResult.YES;\r
+ else\r
+ newPositions.add(pos + 2);\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ return new AntPatternStateMatch(\r
+ match,\r
+ new AntPatternState(myPatternParts, newPositions));\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+/*\r
+ * Copyright 2000-2011 JetBrains s.r.o.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package jetbrains.buildServer.nuget.agent.runner.publish.fsScanner;\r
+\r
+import jetbrains.buildServer.util.StringUtil;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Arrays;\r
+import java.util.Collections;\r
+import java.util.List;\r
+\r
+public class AntPatternUtil\r
+ {\r
+ private static String NormalizePatternString(String pattern)\r
+ {\r
+ pattern = pattern.trim();\r
+ pattern = pattern.replace('\\', '/');\r
+ pattern = pattern.replaceAll("[//]+", "/");\r
+ pattern = pattern.replaceAll("\\*\\*[\\*]+", "**");\r
+ pattern = pattern.replaceAll("\\*\\*/\\*\\*", "**");\r
+ if (pattern.startsWith("/")) pattern = pattern.substring(1);\r
+ return pattern;\r
+ }\r
+\r
+ public static boolean IsFileNameMatch(String pattern, String name)\r
+ {\r
+ name = name.trim();\r
+ name = name.replace('\\', '/');\r
+ name = name.replaceAll("[//]+", "/");\r
+\r
+ List<Wildcard> wildcards = ParsePattern(pattern, false);\r
+ AntPatternState state = new AntPatternState(wildcards);\r
+\r
+ List<String> splitted = new ArrayList<String>(Arrays.asList(name.split("/")));\r
+ List<String> nameComponents = new ArrayList<String>();\r
+ for (String s : splitted)\r
+ {\r
+ if (!StringUtil.isEmptyOrSpaces(s))\r
+ {\r
+ nameComponents.add(s);\r
+ }\r
+ }\r
+\r
+ AntPatternState.MatchResult matchResult = AntPatternState.MatchResult.NO;\r
+\r
+ for (int i = 0; i < nameComponents.size(); i++)\r
+ {\r
+ if (nameComponents.get(i).equals(".") && i < nameComponents.size() - 1)\r
+ continue;\r
+\r
+ final AntPatternState.AntPatternStateMatch enter = state.Enter(nameComponents.get(i));\r
+ matchResult = enter.getResult();\r
+ state = enter.getState();\r
+ }\r
+\r
+ return matchResult == AntPatternState.MatchResult.YES;\r
+ }\r
+\r
+ public static List<Wildcard> ParsePattern(String pattern, boolean caseSensitive)\r
+ {\r
+ pattern = NormalizePatternString(pattern);\r
+ if (pattern.length() == 0)\r
+ return Collections.emptyList();\r
+\r
+ List<Wildcard> result = new ArrayList<Wildcard>();\r
+ for (String component : pattern.split("/"))\r
+ {\r
+ int astIndex = component.indexOf("**");\r
+ if (astIndex < 0)\r
+ {\r
+ result.add(new Wildcard(component, caseSensitive));\r
+ continue;\r
+ }\r
+\r
+ if (astIndex > 0)\r
+ result.add(new Wildcard(component.substring(0, astIndex) + "*", caseSensitive));\r
+\r
+ int cur = astIndex;\r
+ while (astIndex >= 0)\r
+ {\r
+ if (astIndex - cur > 0)\r
+ result.add(new Wildcard("*" + component.substring(cur, astIndex) + "*", caseSensitive));\r
+\r
+ result.add(null);\r
+\r
+ cur = astIndex + 2;\r
+ astIndex = component.indexOf("**", cur);\r
+ }\r
+\r
+ if (cur < component.length())\r
+ result.add(new Wildcard("*" + component.substring(cur), caseSensitive));\r
+ }\r
+\r
+ RemoveTwoDots(result);\r
+ RemoveOneDot(result);\r
+\r
+ return result;\r
+ }\r
+\r
+ private static void RemoveOneDot(List<Wildcard> wildcards)\r
+ {\r
+ int i = 0;\r
+ while (i < wildcards.size() - 1)\r
+ {\r
+ if (wildcards.get(i) != null && wildcards.get(i).Pattern().equals("."))\r
+ wildcards.remove(i);\r
+ else\r
+ i++;\r
+ }\r
+ }\r
+\r
+ private static void RemoveTwoDots(List<Wildcard> wildcards)\r
+ {\r
+ int i = 0;\r
+ while (i < wildcards.size() - 1)\r
+ {\r
+ if (wildcards.get(i + 1) != null && wildcards.get(i + 1).Pattern().equals(".."))\r
+ {\r
+ wildcards.remove(i);\r
+ wildcards.remove(i);\r
+\r
+ if (i > 0)\r
+ i--;\r
+ }\r
+ else\r
+ i++;\r
+ }\r
+\r
+ while (wildcards.size() > 0 && wildcards.get(0) != null && wildcards.get(0).Pattern().equals(".."))\r
+ wildcards.remove(0);\r
+ }\r
+ }\r
--- /dev/null
+/*\r
+ * Copyright 2000-2011 JetBrains s.r.o.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package jetbrains.buildServer.nuget.agent.runner.publish.fsScanner;\r
+\r
+import com.intellij.openapi.diagnostic.Logger;\r
+import org.jetbrains.annotations.NotNull;\r
+\r
+import java.io.File;\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+import java.util.List;\r
+\r
+/// <summary>\r
+/// Nant-syntax wildcard matcher on file system trees\r
+/// </summary>\r
+public class DirectoryScanner {\r
+ private static final Logger LOG = Logger.getInstance(DirectoryScanner.class.getName());\r
+\r
+ public static Collection<File> FindFiles(@NotNull File root, String[] includes, String[] excludes) {\r
+ return FindFiles(new RealFileSystem(), new RealDirectoryEntry(new FileSystemPath(root)), includes, excludes);\r
+ }\r
+\r
+ private static Collection<File> FindFiles(IFileSystem fs, IDirectoryEntry root, String[] includes, String[] excludes) {\r
+ List<Wildcard> basePath = BuildSearchPrefix(root, fs.CaseSensitive());\r
+\r
+ List<FileSystemPath> result = new ArrayList<FileSystemPath>();\r
+ FindFilesRec(\r
+ fs.Root(),\r
+ result,\r
+ ToAntPatternState(fs, basePath, fs.CaseSensitive(), includes),\r
+ ToAntPatternState(fs, basePath, fs.CaseSensitive(), excludes)\r
+ );\r
+\r
+ List<File> foundFiles = new ArrayList<File>();\r
+ for (FileSystemPath path : result) {\r
+ foundFiles.add(path.FilePath());\r
+ }\r
+ return foundFiles;\r
+ }\r
+\r
+ private static List<Wildcard> BuildSearchPrefix(@NotNull IDirectoryEntry root, boolean caseSensitive) {\r
+ List<Wildcard> wildcardPrefix = new ArrayList<Wildcard>();\r
+ while (root.Parent() != null) {\r
+ wildcardPrefix.add(new Wildcard(root.Name(), caseSensitive));\r
+ root = root.Parent();\r
+ }\r
+ Collections.reverse(wildcardPrefix);\r
+\r
+ return wildcardPrefix;\r
+ }\r
+\r
+ private static List<AntPatternState> ToAntPatternState(IFileSystem fs, List<Wildcard> wildcardPrefix, boolean caseSensitive, String[] patterns) {\r
+ List<AntPatternState> result = new ArrayList<AntPatternState>();\r
+ for (String x : patterns) {\r
+ result.add(new AntPatternState(ParsePattern(fs, wildcardPrefix, caseSensitive, x)));\r
+ }\r
+ return result;\r
+ }\r
+\r
+ private static List<Wildcard> ParsePattern(IFileSystem fs, List<Wildcard> rootPrefix, boolean caseSensitive, String pattern) {\r
+ List<Wildcard> wildcards = AntPatternUtil.ParsePattern(pattern, caseSensitive);\r
+\r
+ if (fs.IsPathAbsolute(pattern))\r
+ return wildcards;\r
+\r
+ List<Wildcard> result = new ArrayList<Wildcard>();\r
+ result.addAll(rootPrefix);\r
+ result.addAll(wildcards);\r
+\r
+ return result;\r
+ }\r
+\r
+ private interface AnyPredicate {\r
+ boolean matches(AntPatternState.MatchResult r);\r
+ }\r
+\r
+ private static boolean Any(List<AntPatternState> state, String component, AnyPredicate predicate, List<AntPatternState> newState) {\r
+ boolean any = false;\r
+\r
+ for (int i = 0; i < state.size(); i++) {\r
+ final AntPatternState.AntPatternStateMatch enter = state.get(i).Enter(component);\r
+ AntPatternState.MatchResult match = enter.getResult();\r
+ newState.add(i, enter.getState());\r
+\r
+ if (predicate.matches(match))\r
+ any = true;\r
+ }\r
+\r
+ return any;\r
+ }\r
+\r
+ private static void FindFilesRec(IDirectoryEntry directory, List<FileSystemPath> result, List<AntPatternState> includeState, List<AntPatternState> excludeState) {\r
+ LOG.debug("Scanning directory: " + directory.Name());\r
+ for (IFileEntry file : directory.Files()) {\r
+ List<AntPatternState> newState = new ArrayList<AntPatternState>();\r
+\r
+ if (!Any(includeState, file.Name(), AntPredicateImpl.Predicate(false, AntPatternState.MatchResult.YES), newState))\r
+ continue;\r
+\r
+ newState.clear();\r
+ if (Any(excludeState, file.Name(), AntPredicateImpl.Predicate(false, AntPatternState.MatchResult.YES), newState))\r
+ continue;\r
+\r
+ result.add(file.Path());\r
+ }\r
+\r
+ for (IDirectoryEntry subEntry : directory.Subdirectories()) {\r
+ String name = subEntry.Name();\r
+\r
+ List<AntPatternState> newIncludeState = new ArrayList<AntPatternState>();\r
+ if (!Any(includeState, name, AntPredicateImpl.Predicate(true, AntPatternState.MatchResult.NO), newIncludeState))\r
+ continue;\r
+\r
+ List<AntPatternState> newExcludeState = new ArrayList<AntPatternState>();\r
+ if (Any(excludeState, name, AntPredicateImpl.Predicate(false, AntPatternState.MatchResult.YES), newExcludeState))\r
+ continue;\r
+\r
+ FindFilesRec(subEntry, result, newIncludeState, newExcludeState);\r
+ }\r
+ }\r
+\r
+ private static class AntPredicateImpl {\r
+ private final boolean myNegatiate;\r
+ private final AntPatternState.MatchResult myResult;\r
+\r
+ private AntPredicateImpl(boolean negatiate, AntPatternState.MatchResult result) {\r
+ myNegatiate = negatiate;\r
+ myResult = result;\r
+ }\r
+\r
+ private boolean AnyPredicateImpl(AntPatternState.MatchResult r) {\r
+ return myNegatiate ? myResult != r : myResult == r;\r
+ }\r
+\r
+\r
+ public static AnyPredicate Predicate(boolean not, AntPatternState.MatchResult state) {\r
+ final AntPredicateImpl antPredicate = new AntPredicateImpl(not, state);\r
+ return new AnyPredicate() {\r
+ public boolean matches(AntPatternState.MatchResult r) {\r
+ return antPredicate.AnyPredicateImpl(r);\r
+ }\r
+ };\r
+ }\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright 2000-2011 JetBrains s.r.o.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package jetbrains.buildServer.nuget.agent.runner.publish.fsScanner;\r
+\r
+import org.jetbrains.annotations.NotNull;\r
+\r
+import java.io.File;\r
+\r
+public class FileSystemPath\r
+ {\r
+ private final File myPath;\r
+\r
+ public FileSystemPath(@NotNull String path)\r
+ {\r
+ while(path.endsWith("/") || path.endsWith("\\"))\r
+ path = path.substring(0, path.length()-1);\r
+ myPath = new File(path);\r
+ }\r
+\r
+ public FileSystemPath(File path) {\r
+ myPath = path;\r
+ }\r
+\r
+ @NotNull\r
+ public String Name()\r
+ {\r
+\r
+ String name = myPath.getName();\r
+ if (name == null || name.length() == 0) return myPath.getPath();\r
+ return name;\r
+\r
+ }\r
+\r
+ @NotNull\r
+ public File FilePath()\r
+ {\r
+ return myPath;\r
+ }\r
+ }\r
--- /dev/null
+/*\r
+ * Copyright 2000-2011 JetBrains s.r.o.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package jetbrains.buildServer.nuget.agent.runner.publish.fsScanner;\r
+\r
+import org.jetbrains.annotations.NotNull;\r
+import org.jetbrains.annotations.Nullable;\r
+\r
+public interface IDirectoryEntry {\r
+ @NotNull\r
+ String Name();\r
+\r
+ @Nullable\r
+ IDirectoryEntry Parent();\r
+ \r
+ @NotNull\r
+ IDirectoryEntry[] Subdirectories();\r
+\r
+ @NotNull\r
+ IFileEntry[] Files();\r
+ }\r
--- /dev/null
+/*\r
+ * Copyright 2000-2011 JetBrains s.r.o.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package jetbrains.buildServer.nuget.agent.runner.publish.fsScanner;\r
+\r
+public interface IFileEntry\r
+ {\r
+ String Name();\r
+ FileSystemPath Path();\r
+ }
\ No newline at end of file
--- /dev/null
+/*\r
+ * Copyright 2000-2011 JetBrains s.r.o.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package jetbrains.buildServer.nuget.agent.runner.publish.fsScanner;\r
+\r
+import org.jetbrains.annotations.NotNull;\r
+\r
+public interface IFileSystem {\r
+ boolean IsPathAbsolute(@NotNull String path);\r
+\r
+ @NotNull\r
+ IDirectoryEntry Root();\r
+\r
+ boolean CaseSensitive();\r
+}\r
--- /dev/null
+/*\r
+ * Copyright 2000-2011 JetBrains s.r.o.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package jetbrains.buildServer.nuget.agent.runner.publish.fsScanner;\r
+\r
+\r
+import com.intellij.openapi.util.SystemInfo;\r
+import jetbrains.buildServer.util.StringUtil;\r
+import org.jetbrains.annotations.NotNull;\r
+\r
+import java.io.File;\r
+import java.io.FileFilter;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+public class RealDirectoryEntry implements IDirectoryEntry {\r
+ private final FileSystemPath myPath;\r
+\r
+ public RealDirectoryEntry(FileSystemPath path) {\r
+ myPath = path;\r
+ }\r
+\r
+ @NotNull\r
+ public String Name() {\r
+ {\r
+ String name = myPath.Name();\r
+ if (SystemInfo.isWindows) {\r
+ if (name.length() == 3 && name.charAt(1) == ':')\r
+ return name.charAt(0) + ":";\r
+ }\r
+\r
+ return name;\r
+ }\r
+ }\r
+\r
+ public IDirectoryEntry Parent() {\r
+ if (StringUtil.isEmptyOrSpaces(myPath.FilePath().getPath()))\r
+ return RealFileSystem.ROOT;\r
+\r
+ String parent = myPath.FilePath().getParent();\r
+ if (parent == null)\r
+ return RealFileSystem.ROOT;\r
+\r
+ FileSystemPath parentPath = new FileSystemPath(parent);\r
+ if (StringUtil.isEmptyOrSpaces(parentPath.FilePath().getPath()))\r
+ return RealFileSystem.ROOT;\r
+\r
+ return new RealDirectoryEntry(parentPath);\r
+ }\r
+\r
+ @NotNull\r
+ public IDirectoryEntry[] Subdirectories() {\r
+ try {\r
+ List<IDirectoryEntry> list = new ArrayList<IDirectoryEntry>();\r
+ for (File dir : FilePath().listFiles(new FileFilter() {\r
+ public boolean accept(File pathname) {\r
+ return pathname.isDirectory();\r
+ }\r
+ })) {\r
+ list.add(new RealDirectoryEntry(new FileSystemPath(dir)));\r
+ }\r
+ return list.toArray(new IDirectoryEntry[list.size()]);\r
+ } catch (Exception e) {\r
+ return new IDirectoryEntry[0];\r
+ }\r
+ }\r
+\r
+ private File FilePath() {\r
+ String filePath = myPath.FilePath().getPath();\r
+\r
+ if (SystemInfo.isWindows && filePath.endsWith(":")) {\r
+ return new File(filePath + "\\");\r
+ }\r
+ if (!SystemInfo.isWindows && filePath.equals("")) {\r
+ return new File("/");\r
+ }\r
+\r
+ return new File(filePath);\r
+ }\r
+\r
+ @NotNull\r
+ public IFileEntry[] Files() {\r
+\r
+ try {\r
+ List<IFileEntry> list = new ArrayList<IFileEntry>();\r
+ for (File dir : FilePath().listFiles(new FileFilter() {\r
+ public boolean accept(File pathname) {\r
+ return pathname.isFile();\r
+ }\r
+ })) {\r
+ list.add(new RealFileEntry(new FileSystemPath(dir)));\r
+ }\r
+ return list.toArray(new IFileEntry[list.size()]);\r
+ } catch (Exception e) {\r
+ return new IFileEntry[0];\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public String toString() {\r
+ return "{d:" + myPath.FilePath() + "|" + Name() + "}";\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright 2000-2011 JetBrains s.r.o.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package jetbrains.buildServer.nuget.agent.runner.publish.fsScanner;\r
+\r
+public class RealFileEntry implements IFileEntry {\r
+ private final FileSystemPath myPath;\r
+\r
+ public RealFileEntry(FileSystemPath path) {\r
+ myPath = path;\r
+ }\r
+\r
+ public String Name() {\r
+ return myPath.Name();\r
+ }\r
+\r
+ public FileSystemPath Path() {\r
+ return myPath;\r
+ }\r
+\r
+ @Override\r
+ public String toString() {\r
+ return "{f:" + myPath.FilePath() + "|" + Name() + "}";\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+/*\r
+ * Copyright 2000-2011 JetBrains s.r.o.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package jetbrains.buildServer.nuget.agent.runner.publish.fsScanner;\r
+\r
+import com.intellij.openapi.util.SystemInfo;\r
+import org.jetbrains.annotations.NotNull;\r
+\r
+import java.io.File;\r
+\r
+public class RealFileSystem implements IFileSystem {\r
+ public static final IDirectoryEntry ROOT = new RealRootDirectory();\r
+\r
+ public boolean IsPathAbsolute(@NotNull String path) {\r
+ if (SystemInfo.isWindows) {\r
+ if ((path.startsWith("/") || path.startsWith("\\")))\r
+ return false;\r
+\r
+ return new File(path).isAbsolute();\r
+ }\r
+ return path.startsWith("/");\r
+ }\r
+\r
+ @NotNull\r
+ public IDirectoryEntry Root() {\r
+ return ROOT;\r
+ }\r
+\r
+ public boolean CaseSensitive() {\r
+ return SystemInfo.isFileSystemCaseSensitive;\r
+ }\r
+}\r
+\r
--- /dev/null
+/*\r
+ * Copyright 2000-2011 JetBrains s.r.o.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package jetbrains.buildServer.nuget.agent.runner.publish.fsScanner;\r
+\r
+import com.intellij.openapi.util.SystemInfo;\r
+import org.jetbrains.annotations.NotNull;\r
+\r
+import java.io.File;\r
+import java.io.FileFilter;\r
+import java.util.ArrayList;\r
+\r
+public class RealRootDirectory implements IDirectoryEntry\r
+ {\r
+ @NotNull\r
+ public String Name()\r
+ {\r
+ return "";\r
+ }\r
+\r
+ public IDirectoryEntry Parent()\r
+ {\r
+ return null;\r
+ }\r
+\r
+ @NotNull\r
+ public IDirectoryEntry[] Subdirectories()\r
+ {\r
+ {\r
+ ArrayList<IDirectoryEntry> result = new ArrayList<IDirectoryEntry>();\r
+ if (SystemInfo.isWindows)\r
+ { \r
+ for (File drive : File.listRoots())\r
+ {\r
+ result.add(new RealDirectoryEntry(new FileSystemPath(drive)));\r
+ } \r
+ } else\r
+ {\r
+ for (File ch : new File("/").listFiles(new FileFilter() {\r
+ public boolean accept(File pathname) {\r
+ return pathname.isDirectory();\r
+ }\r
+ }))\r
+ {\r
+ result.add(new RealDirectoryEntry(new FileSystemPath(ch)));\r
+ }\r
+ }\r
+\r
+ return result.toArray(new IDirectoryEntry[result.size()]);\r
+ }\r
+ }\r
+\r
+ @NotNull\r
+ public IFileEntry[] Files()\r
+ {\r
+ return new IFileEntry[0];\r
+ }\r
+\r
+ @Override\r
+ public String toString()\r
+ {\r
+ return "{d:FS_META_ROOT}";\r
+ }\r
+ }\r
--- /dev/null
+/*\r
+ * Copyright 2000-2011 JetBrains s.r.o.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package jetbrains.buildServer.nuget.agent.runner.publish.fsScanner;\r
+\r
+import jetbrains.buildServer.util.StringUtil;\r
+import org.jetbrains.annotations.NotNull;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+public class Wildcard\r
+ {\r
+ private final String myPattern;\r
+ private final boolean myCaseSensitive;\r
+\r
+ public Wildcard(String pattern, boolean caseSensitive)\r
+ {\r
+ pattern = pattern.replaceAll("[\\*]+", "*");\r
+ myCaseSensitive = caseSensitive;\r
+\r
+ myPattern = !caseSensitive ? pattern.toLowerCase() : pattern;\r
+ }\r
+\r
+ public String Pattern()\r
+ {\r
+ return myPattern;\r
+ }\r
+\r
+ public boolean IsMatch(@NotNull String str)\r
+ {\r
+ String pattern = myPattern;\r
+\r
+ if (StringUtil.isEmptyOrSpaces(pattern))\r
+ return StringUtil.isEmptyOrSpaces(str);\r
+\r
+ if (!myCaseSensitive)\r
+ str = str.toLowerCase();\r
+\r
+ int patlen = pattern.length();\r
+ List<Integer> positions = new ArrayList<Integer>();\r
+ positions.add(0);\r
+ for (int j = 0; j < str.length(); j++)\r
+ {\r
+ char c = str.charAt(j);\r
+\r
+ boolean hasPositionsToMatch = false;\r
+\r
+ int len = positions.size();\r
+ for (int i = 0; i < len; i++)\r
+ {\r
+ int pat = positions.get(i);\r
+ if (pat >= patlen || pat < 0)\r
+ continue;\r
+\r
+ hasPositionsToMatch = true;\r
+\r
+ if (pattern.charAt(pat) == '*')\r
+ {\r
+ if (pat == patlen - 1)\r
+ return true;\r
+\r
+ if (MatchChars(pattern.charAt(pat + 1), c))\r
+ {\r
+ if (pat == patlen - 2 && j == str.length() - 1)\r
+ return true;\r
+ positions.add(pat + 2);\r
+ }\r
+ }\r
+ else\r
+ {\r
+ if (MatchChars(pattern.charAt(pat), c))\r
+ {\r
+ if (pat == patlen - 1 && j == str.length() - 1)\r
+ return true;\r
+\r
+ positions.set(i, positions.get(i) + 1);\r
+ }\r
+ else positions.set(i, -1);\r
+ }\r
+ }\r
+\r
+ if (!hasPositionsToMatch)\r
+ return false;\r
+ }\r
+\r
+ for (Integer x : positions)\r
+ {\r
+ if (x == patlen - 1 && pattern.charAt(x) == '*')\r
+ return true;\r
+ }\r
+ return false;\r
+ }\r
+\r
+ private static boolean MatchChars(char pat, char c)\r
+ {\r
+ return pat == '?' || pat == c;\r
+ }\r
+\r
+ @Override\r
+ public String toString()\r
+ {\r
+ return "Wildcard{" + myPattern + "}";\r
+ }\r
+ }\r
m.assertIsSatisfied();\r
}\r
\r
+ @Test\r
+ public void test_match_full_file_wildcard3() throws RunBuildException {\r
+ final File dest = new File(root, "q/e/r/t/aaa.txt");\r
+ FileUtil.createParentDirs(dest);\r
+ FileUtil.writeFile(dest, "some content");\r
+\r
+ m.checking(new Expectations() {{\r
+ oneOf(cb).fileFound(dest);\r
+ }});\r
+\r
+ files.add(dest.getParentFile() + "/*");\r
+ assertRunSuccessfully(match, BuildFinishedStatus.FINISHED_SUCCESS);\r
+\r
+ m.assertIsSatisfied();\r
+ }\r
+\r
+\r
@Test\r
public void test_match_fullPath_file2() throws RunBuildException {\r
final File dest = new File(root, "a/b/c/aaa.txt");\r
--- /dev/null
+/*\r
+ * Copyright 2000-2011 JetBrains s.r.o.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package jetbrains.buildServer.nuget.tests.util.fsScanner;\r
+\r
+import com.intellij.openapi.util.SystemInfo;\r
+import jetbrains.buildServer.BaseTestCase;\r
+import jetbrains.buildServer.nuget.agent.runner.publish.fsScanner.RealFileSystem;\r
+import org.testng.Assert;\r
+import org.testng.annotations.Test;\r
+\r
+public class DirectoryFileFilesystemTest extends BaseTestCase {\r
+ @Test\r
+ public void TestDirectoryRootsWindows() {\r
+ if (!SystemInfo.isWindows) return;\r
+\r
+ DoAbsTest("C:/", true);\r
+ DoAbsTest("C:\\", true);\r
+ DoAbsTest("\\", false);\r
+ DoAbsTest("/", false);\r
+ DoAbsTest("aaa", false);\r
+ DoAbsTest("aaa/vvv", false);\r
+ DoAbsTest("aaa\\vvv", false);\r
+ DoAbsTest("\\aaa\\vvv", false);\r
+ DoAbsTest("/aaa\\vvv", false);\r
+ }\r
+\r
+ @Test\r
+ public void TestDirectoryRootUnix() {\r
+ if (SystemInfo.isWindows) return;\r
+\r
+ DoAbsTest("/", true);\r
+ DoAbsTest("aaa/bbb", false);\r
+ }\r
+\r
+ private static void DoAbsTest(String path, boolean result) {\r
+ RealFileSystem fs = new RealFileSystem();\r
+ Assert.assertEquals(result, fs.IsPathAbsolute(path));\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright 2000-2011 JetBrains s.r.o.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package jetbrains.buildServer.nuget.tests.util.fsScanner;\r
+\r
+import jetbrains.buildServer.BaseTestCase;\r
+import jetbrains.buildServer.nuget.agent.runner.publish.fsScanner.AntPatternState;\r
+import jetbrains.buildServer.nuget.agent.runner.publish.fsScanner.AntPatternUtil;\r
+import jetbrains.buildServer.nuget.agent.runner.publish.fsScanner.Wildcard;\r
+import org.jetbrains.annotations.Nullable;\r
+import org.testng.Assert;\r
+import org.testng.annotations.Test;\r
+\r
+import java.util.Arrays;\r
+import java.util.List;\r
+\r
+public class TestAntPatternState extends BaseTestCase {\r
+ private static void AssertPatternState(String pattern, @Nullable List<Integer> pos, String enter, String expectedResult) {\r
+ List<Wildcard> wildcards = AntPatternUtil.ParsePattern(pattern, false);\r
+\r
+ AntPatternState state = pos == null\r
+ ? new AntPatternState(wildcards)\r
+ : new AntPatternState(wildcards, pos);\r
+\r
+ final AntPatternState.AntPatternStateMatch e = state.Enter(enter);\r
+ AntPatternState.MatchResult match = e.getResult();\r
+ AntPatternState newState = e.getState();\r
+\r
+ StringBuilder sb = new StringBuilder();\r
+ sb.append(match);\r
+ sb.append(" ");\r
+ for (int p : newState.PatternPositions()) {\r
+ sb.append(p);\r
+ sb.append(":");\r
+ }\r
+\r
+ String result = sb.toString();\r
+ Assert.assertEquals(expectedResult, result);\r
+ }\r
+\r
+ @Test\r
+ public void PatternState() {\r
+ AssertPatternState("a*", null, "a", "YES ");\r
+ AssertPatternState("a*", null, "abc", "YES ");\r
+ AssertPatternState("a*", null, "b", "NO ");\r
+\r
+ AssertPatternState("a*/**", null, "b", "NO ");\r
+ AssertPatternState("a*/**", null, "a", "YES 1:");\r
+\r
+ AssertPatternState("**", null, "b", "YES 0:");\r
+ AssertPatternState("**/a", null, "b", "MAYBELATER 0:");\r
+ AssertPatternState("**/a", null, "a", "YES 0:");\r
+ AssertPatternState("**/a/**/a", Arrays.asList(0, 2), "a", "YES 0:2:2:"); // fix?\r
+\r
+ AssertPatternState("**/a/**/b", Arrays.asList(0, 2), "a", "MAYBELATER 0:2:2:");\r
+ AssertPatternState("**/a/**/b", Arrays.asList(0, 2), "b", "YES 0:2:");\r
+ AssertPatternState("**/a/**/b", Arrays.asList(0, 2), "c", "MAYBELATER 0:2:");\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright 2000-2011 JetBrains s.r.o.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package jetbrains.buildServer.nuget.tests.util.fsScanner;\r
+\r
+\r
+import jetbrains.buildServer.BaseTestCase;\r
+import jetbrains.buildServer.nuget.agent.runner.publish.fsScanner.AntPatternUtil;\r
+import jetbrains.buildServer.nuget.agent.runner.publish.fsScanner.Wildcard;\r
+import jetbrains.buildServer.util.StringUtil;\r
+import org.testng.Assert;\r
+import org.testng.annotations.Test;\r
+\r
+import java.util.List;\r
+\r
+public class TestAntPatternUtil extends BaseTestCase {\r
+ private static void AssertParseResult(String pattern, String expectedResult) {\r
+ List<Wildcard> wildcards = AntPatternUtil.ParsePattern(pattern, false);\r
+ StringBuilder sb = new StringBuilder();\r
+ for (Wildcard w : wildcards) {\r
+ sb.append(w == null ? "**" : w.Pattern());\r
+ sb.append(":");\r
+ }\r
+ String result = StringUtil.trimEnd(sb.toString(), ":");\r
+ Assert.assertEquals(expectedResult, result);\r
+ }\r
+\r
+ @Test\r
+ public void IsFileNameMatch() {\r
+ Assert.assertTrue(AntPatternUtil.IsFileNameMatch("a*/**b**", "abc/ss/aa/vv/ggbbhh/qq"));\r
+ Assert.assertFalse(AntPatternUtil.IsFileNameMatch("a*/**b**", "abc/ss/aa/vv/gghh/qq"));\r
+ Assert.assertTrue(AntPatternUtil.IsFileNameMatch("**/bin/**.exe", "My/BiN/Debug/program.exe"));\r
+ Assert.assertFalse(AntPatternUtil.IsFileNameMatch("**/bin/**.exe", "My/BiN/Debug/program.dll"));\r
+ Assert.assertTrue(AntPatternUtil.IsFileNameMatch("**/bin/**.exe", "bin/program.exe"));\r
+\r
+ Assert.assertTrue(AntPatternUtil.IsFileNameMatch("**aaa**ddd***ccc**", "aaa/aaa/ddd/ddd/ccc/ccc"));\r
+ Assert.assertFalse(AntPatternUtil.IsFileNameMatch("**aaa**ddd***ccc**", "aaa/aaa/ccc/ccc"));\r
+\r
+ Assert.assertTrue(AntPatternUtil.IsFileNameMatch(".\\s.slN", "S.sln"));\r
+ Assert.assertTrue(AntPatternUtil.IsFileNameMatch("s.slN", ".\\S.sln"));\r
+\r
+ Assert.assertFalse(AntPatternUtil.IsFileNameMatch(".", ""));\r
+ }\r
+\r
+ @Test\r
+ public void ParsePattern() {\r
+ AssertParseResult("a///\\\\bcd", "a:bcd");\r
+ AssertParseResult("//", "");\r
+ AssertParseResult("*****/**.exe", "**:*.exe");\r
+ AssertParseResult("**/bin/**.dll", "**:bin:**:*.dll"); // real-life example\r
+ AssertParseResult("**a**b**/bin", "**:*a*:**:*b*:**:bin");\r
+ AssertParseResult("a**a**b**", "a*:**:*a*:**:*b*:**");\r
+ AssertParseResult("**a**b**d", "**:*a*:**:*b*:**:*d");\r
+\r
+ AssertParseResult("../a/b/c", "a:b:c");\r
+ AssertParseResult("a/../b/../c", "c");\r
+ AssertParseResult("a/b/c/..", "a:b");\r
+ AssertParseResult("a/../../c", "c");\r
+ AssertParseResult("a/b/../../c", "c");\r
+ AssertParseResult("a/b/c/../../../d", "d");\r
+ }\r
+\r
+ @Test\r
+ public void TestParseLeadingSlash() {\r
+ AssertParseResult("/aaa/bbb/ccc", "aaa:bbb:ccc");\r
+ }\r
+\r
+ @Test\r
+ public void TestParseWindowsFullPath() {\r
+ AssertParseResult("c:/aaa/bbb/ccc", "c::aaa:bbb:ccc");\r
+ }\r
+\r
+}\r
--- /dev/null
+/*\r
+ * Copyright 2000-2011 JetBrains s.r.o.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package jetbrains.buildServer.nuget.tests.util.fsScanner;\r
+\r
+\r
+import com.intellij.openapi.util.SystemInfo;\r
+import jetbrains.buildServer.BaseTestCase;\r
+import jetbrains.buildServer.nuget.agent.runner.publish.fsScanner.DirectoryScanner;\r
+import jetbrains.buildServer.util.FileUtil;\r
+import org.testng.Assert;\r
+import org.testng.annotations.Test;\r
+\r
+import java.io.File;\r
+import java.io.IOException;\r
+import java.util.Collection;\r
+import java.util.Iterator;\r
+import java.util.Set;\r
+import java.util.TreeSet;\r
+\r
+public class TestDirectoryScanner extends BaseTestCase {\r
+ private void AssertScannerResult(String[] fsDescription, String[] includePatterns, String[] excludePatterns, String[] expectedResult) throws IOException {\r
+ File fsp = createTempDir();\r
+\r
+ CreateDirectories(fsDescription, fsp);\r
+ Collection<File> findFiles = DirectoryScanner.FindFiles(fsp, includePatterns, excludePatterns);\r
+\r
+ Set<File> expected = new TreeSet<File>();\r
+ for (String s : expectedResult) {\r
+ expected.add(new File(fsp, s));\r
+ }\r
+ Set<File> actual = new TreeSet<File>();\r
+\r
+ System.out.println("Found: ");\r
+ for (File file : findFiles) {\r
+ actual.add(file);\r
+ System.out.println(" " + file);\r
+ }\r
+\r
+ Assert.assertEquals(expected.size(), actual.size());\r
+ final Iterator<File> eIt = expected.iterator();\r
+ final Iterator<File> aIt = actual.iterator();\r
+\r
+ for (int i = 0; i < expected.size(); i++)\r
+\r
+ {\r
+ final File eNext = eIt.next();\r
+ final File aNext = aIt.next();\r
+ Assert.assertEquals(PreparePath(eNext), PreparePath(aNext));\r
+ }\r
+ }\r
+\r
+\r
+ private static void CreateDirectories(String[] fsDescription, File fsp) {\r
+ for (String f : fsDescription) {\r
+ File path = new File(fsp, f.substring(2));\r
+ if (f.startsWith("f:")) {\r
+ FileUtil.createParentDirs(path);\r
+ FileUtil.writeFile(path, "text");\r
+ } else if (f.startsWith("d:"))\r
+ path.mkdirs();\r
+ else\r
+ Assert.fail("Wrong fsDescription: " + f);\r
+ }\r
+ }\r
+\r
+\r
+ @Test\r
+ public void TestSmoke() throws IOException {\r
+ AssertScannerResult(\r
+ new String[]\r
+ {\r
+ "d:a",\r
+ "f:a/a.exe",\r
+ "f:a/a.dll",\r
+ "f:a/a.ca",\r
+ },\r
+ new String[]{"**"},\r
+ new String[]{"**/*.exe"},\r
+ new String[]{"a/a.ca", "a/a.dll"});\r
+ }\r
+\r
+ @Test\r
+ public void TestEmptyExclude() throws IOException {\r
+ AssertScannerResult(\r
+ new String[]\r
+ {\r
+ "d:a",\r
+ "f:a/a.exe",\r
+ "f:a/a.dll",\r
+ "f:a/a.ca",\r
+ },\r
+ new String[]{"**"},\r
+ new String[]{},\r
+ new String[]{"a/a.ca", "a/a.dll", "a/a.exe"});\r
+ }\r
+\r
+ @Test\r
+ public void TestEmptyInclude() throws IOException {\r
+ AssertScannerResult(\r
+ new String[]\r
+ {\r
+ "d:a",\r
+ "f:a/a.exe",\r
+ "f:a/a.dll",\r
+ "f:a/a.ca",\r
+ },\r
+ new String[]{},\r
+ new String[]{"**"},\r
+ new String[]{});\r
+ }\r
+\r
+ @Test\r
+ public void TestBothEmpty() throws IOException {\r
+ AssertScannerResult(\r
+ new String[]\r
+ {\r
+ "d:a",\r
+ "f:a/a.exe",\r
+ "f:a/a.dll",\r
+ "f:a/a.ca",\r
+ },\r
+ new String[]{},\r
+ new String[]{},\r
+ new String[]{});\r
+ }\r
+\r
+ @Test\r
+ public void TestShouldNotMatchDirectory() throws IOException {\r
+ AssertScannerResult(\r
+ new String[]\r
+ {\r
+ "f:a/b/c/d/e/f/g/h/i/p/g/aaa.txt",\r
+ "d:a/r/c/d/e/f/g/h/i/p/g/aaa.txt",\r
+ },\r
+ new String[]{"**/*.txt"},\r
+ new String[]{},\r
+ new String[]{"a/b/c/d/e/f/g/h/i/p/g/aaa.txt"});\r
+ }\r
+\r
+ @Test\r
+ public void TestCaseSensitive() throws IOException {\r
+ if (SystemInfo.isWindows) return;\r
+\r
+ AssertScannerResult(\r
+ new String[]\r
+ {\r
+ "f:a/b/c/d/e/f/g/h/i/p/g/aAa.txt",\r
+ "f:a/r/e/a/l/f/g/h/i/p/g/aaa.txt",\r
+ },\r
+ new String[]{"**/*A*.txt"},\r
+ new String[]{},\r
+ new String[]{"a/b/c/d/e/f/g/h/i/p/g/aAa.txt"});\r
+ }\r
+\r
+ @Test\r
+ public void TestCaseInSensitive() throws IOException {\r
+ if (SystemInfo.isWindows) return;\r
+\r
+ AssertScannerResult(\r
+ new String[]\r
+ {\r
+ "f:a/b/c/d/e/f/g/h/i/p/g/aAa.txt",\r
+ "f:a/r/e/a/l/f/g/h/i/p/g/aaa.txt",\r
+ },\r
+ new String[]{"**/*A*.txt"},\r
+ new String[]{},\r
+ new String[]\r
+ {\r
+ "a/b/c/d/e/f/g/h/i/p/g/aAa.txt",\r
+ "a/r/e/a/l/f/g/h/i/p/g/aaa.txt",\r
+ });\r
+ }\r
+\r
+\r
+ @Test\r
+ public void AbsoluteIncludePath() throws IOException {\r
+\r
+ File fsp = createTempDir();\r
+ File atxtFsp = new File(fsp, "a.txt");\r
+ FileUtil.writeFile(atxtFsp, "text");\r
+\r
+ Collection<File> files = DirectoryScanner.FindFiles(fsp, new String[]{atxtFsp.getPath()}, new String[0]);\r
+ Assert.assertEquals(1, files.size());\r
+ Assert.assertEquals(PreparePath(atxtFsp), PreparePath(files.iterator().next()));\r
+ }\r
+\r
+ private static String PreparePath(File f) {\r
+ String path = f.getPath();\r
+ path = path.replace('\\', '/');\r
+ if (!SystemInfo.isWindows) {\r
+ return path;\r
+ } else {\r
+ return path.toLowerCase();\r
+ }\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright 2000-2011 JetBrains s.r.o.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package jetbrains.buildServer.nuget.tests.util.fsScanner;\r
+\r
+\r
+import com.intellij.openapi.util.SystemInfo;\r
+import jetbrains.buildServer.BaseTestCase;\r
+import jetbrains.buildServer.nuget.agent.runner.publish.fsScanner.*;\r
+import org.testng.Assert;\r
+import org.testng.annotations.Test;\r
+\r
+import java.io.File;\r
+import java.io.IOException;\r
+import java.util.ArrayList;\r
+import java.util.Collections;\r
+import java.util.List;\r
+\r
+public class TestReadFileSystem extends BaseTestCase {\r
+ private interface FilesAction {\r
+ void action(RealDirectoryEntry r1, RealDirectoryEntry r2, RealDirectoryEntry r3, RealDirectoryEntry r4);\r
+ }\r
+\r
+\r
+ @Test\r
+ public void TestCaseSensitive() {\r
+ Assert.assertEquals(!SystemInfo.isWindows, new RealFileSystem().CaseSensitive());\r
+ }\r
+\r
+ private void TestFSTest(FilesAction a) throws IOException {\r
+\r
+ File path1 = createTempDir();\r
+ File path2 = new File(path1, "aaa");\r
+ File path3 = new File(path2, "bbb");\r
+ File path4 = new File(path3, "ccc");\r
+ path2.mkdirs();\r
+ path3.mkdirs();\r
+ path4.mkdirs();\r
+\r
+ RealDirectoryEntry r4 = new RealDirectoryEntry(new FileSystemPath(path4));\r
+ RealDirectoryEntry r3 = new RealDirectoryEntry(new FileSystemPath(path3));\r
+ RealDirectoryEntry r2 = new RealDirectoryEntry(new FileSystemPath(path2));\r
+ RealDirectoryEntry r1 = new RealDirectoryEntry(new FileSystemPath(path1));\r
+\r
+ a.action(r1, r2, r3, r4);\r
+\r
+ }\r
+\r
+\r
+ @Test\r
+ public void TestNames() throws IOException {\r
+ TestFSTest(new FilesAction() {\r
+ public void action(RealDirectoryEntry r1, RealDirectoryEntry r2, RealDirectoryEntry r3, RealDirectoryEntry r4) {\r
+ Assert.assertEquals("ccc", r4.Name());\r
+ Assert.assertEquals("bbb", r3.Name());\r
+ Assert.assertEquals("aaa", r2.Name());\r
+ }\r
+ });\r
+ }\r
+\r
+ @Test\r
+ public void TestParent() throws IOException {\r
+ TestFSTest(\r
+ new FilesAction() {\r
+ public void action(RealDirectoryEntry r1, RealDirectoryEntry r2, RealDirectoryEntry r3, RealDirectoryEntry r4) {\r
+ AssertDirectoriesEqual(r4.Parent(), r3);\r
+ AssertDirectoriesEqual(r4.Parent().Parent(), r2);\r
+ AssertDirectoriesEqual(r4.Parent().Parent().Parent(), r1);\r
+\r
+ AssertDirectoriesEqual(r3.Parent(), r2);\r
+ AssertDirectoriesEqual(r3.Parent().Parent(), r1);\r
+\r
+ AssertDirectoriesEqual(r2.Parent(), r1);\r
+\r
+\r
+ }\r
+ });\r
+ }\r
+\r
+ @Test\r
+ public void TestSubdirectories() throws IOException {\r
+ TestFSTest(\r
+ new FilesAction() {\r
+ public void action(RealDirectoryEntry r1, RealDirectoryEntry r2, RealDirectoryEntry r3, RealDirectoryEntry r4) {\r
+ Assert.assertEquals(0, r4.Subdirectories().length);\r
+ Assert.assertEquals(1, r3.Subdirectories().length);\r
+ Assert.assertEquals(1, r2.Subdirectories().length);\r
+ Assert.assertEquals(1, r1.Subdirectories().length);\r
+\r
+ AssertDirectoriesEqual(r3.Subdirectories()[0], r4);\r
+ AssertDirectoriesEqual(r2.Subdirectories()[0], r3);\r
+ AssertDirectoriesEqual(r1.Subdirectories()[0], r2);\r
+\r
+ }\r
+ });\r
+ }\r
+\r
+ @Test\r
+ public void TestRootSubdirectories() {\r
+ RealRootDirectory root = new RealRootDirectory();\r
+ Assert.assertTrue(root.Subdirectories().length > 0);\r
+ }\r
+\r
+ @Test(enabled = false)\r
+ public void TestRootSubdirectoriesWalk() {\r
+ int k = 10;\r
+ for (IDirectoryEntry sub1 : new RealRootDirectory().Subdirectories()) {\r
+ if (k-- < 0) break;\r
+ int j = 10;\r
+ for (IDirectoryEntry sub2 : sub1.Subdirectories()) {\r
+ if (j-- < 0) break;\r
+ int i = 10;\r
+ for (IDirectoryEntry sub3 : sub2.Subdirectories()) {\r
+ if (i-- < 0) break;\r
+ System.out.println("sub3 = " + sub3);\r
+ }\r
+ }\r
+ }\r
+\r
+ }\r
+\r
+\r
+ @Test\r
+ public void TestRealRoot() {\r
+ IDirectoryEntry root = RealFileSystem.ROOT;\r
+ DumpItem(root);\r
+ Assert.assertTrue(root.Subdirectories().length > 0);\r
+ }\r
+\r
+ private static void DumpItem(IDirectoryEntry e) {\r
+ Assert.assertNotNull(e);\r
+ System.out.println("entry = " + e);\r
+ for (IDirectoryEntry sub : e.Subdirectories()) {\r
+ System.out.println("entry->sub = " + sub);\r
+ }\r
+ for (IFileEntry fileEntry : e.Files()) {\r
+ System.out.println("entry->file = " + fileEntry);\r
+ }\r
+ }\r
+\r
+ @Test\r
+ public void TestSimpleUpDown() throws IOException {\r
+\r
+ File path = new File(createTempDir(), "aaa");\r
+ path.mkdirs();\r
+\r
+\r
+ IDirectoryEntry e = cd(path);\r
+ IDirectoryEntry p = e.Parent();\r
+ Assert.assertNotNull(p);\r
+\r
+ for (IDirectoryEntry dir : p.Subdirectories()) {\r
+ if (dir.Name().equals(e.Name())) {\r
+ AssertDirectoriesEqual(dir, e);\r
+ return;\r
+ }\r
+ }\r
+ Assert.fail("Failed to find child");\r
+ }\r
+\r
+\r
+ private static RealDirectoryEntry cd(File path) {\r
+ return new RealDirectoryEntry(new FileSystemPath(path));\r
+ }\r
+\r
+ @Test\r
+ public void TestShouldFindRootFS() throws IOException {\r
+ IDirectoryEntry r = cd(createTempDir());\r
+ while (true) {\r
+ IDirectoryEntry p = r.Parent();\r
+ if (p == null) break;\r
+ r = p;\r
+ }\r
+\r
+ Assert.assertNotNull(r);\r
+ Assert.assertEquals(r.getClass(), RealRootDirectory.class);\r
+ }\r
+\r
+ @Test\r
+ public void TestWalkUpAndDown() throws IOException {\r
+\r
+ File path = createTempDir();\r
+ for (String cc : new String[]{"a", "b", "c", "d", "e", "f", "g", "h"}) {\r
+ path = new File(path, cc);\r
+ path.mkdirs();\r
+ }\r
+\r
+ IDirectoryEntry test = new RealDirectoryEntry(new FileSystemPath(path));\r
+\r
+ List<String> loop = new ArrayList<String>();\r
+ while (true) {\r
+ System.out.println("p = " + test);\r
+ loop.add(test.Name());\r
+ IDirectoryEntry p = test.Parent();\r
+ if (p == null) break;\r
+ test = p;\r
+ }\r
+ Collections.reverse(loop);\r
+\r
+\r
+ IDirectoryEntry root = new RealRootDirectory();\r
+ Assert.assertEquals(root.Name(), loop.get(0));\r
+ loop.remove(0);\r
+\r
+ for (String name : loop) {\r
+ boolean found = false;\r
+ for (IDirectoryEntry sub : root.Subdirectories()) {\r
+ if (sub.Name().equals(name)) {\r
+ found = true;\r
+ root = sub;\r
+ }\r
+ }\r
+ if (!found) {\r
+ System.out.println("Looking for name '" + name + "{0}'");\r
+ System.out.println("Looking under '" + root + "'");\r
+ DumpItem(root);\r
+\r
+ Assert.assertTrue(found, "Failed to find " + name + " under " + root);\r
+ }\r
+ }\r
+\r
+ }\r
+\r
+ private static void AssertDirectoriesEqual(IDirectoryEntry e1, IDirectoryEntry e2) {\r
+ Assert.assertEquals(e1.toString(), e2.toString());\r
+ }\r
+\r
+ @Test\r
+ public void TestEquality() throws IOException {\r
+ final File dir = createTempDir();\r
+ AssertDirectoriesEqual(new RealDirectoryEntry(new FileSystemPath(dir)), new RealDirectoryEntry(new FileSystemPath(dir)));\r
+ }\r
+\r
+ @Test\r
+ public void TestParentDirectory() throws IOException {\r
+ File path = createTempDir();\r
+\r
+ List<IDirectoryEntry> entries = new ArrayList<IDirectoryEntry>();\r
+ IDirectoryEntry e = new RealDirectoryEntry(new FileSystemPath(path));\r
+ while (e.Parent() != null) {\r
+ System.out.println("e = " + e);\r
+ entries.add(e);\r
+ e = e.Parent();\r
+ }\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright 2000-2011 JetBrains s.r.o.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package jetbrains.buildServer.nuget.tests.util.fsScanner;\r
+\r
+import jetbrains.buildServer.nuget.agent.runner.publish.fsScanner.Wildcard;\r
+import org.testng.Assert;\r
+import org.testng.annotations.Test;\r
+\r
+public class TestWildcard {\r
+ @Test\r
+ public void test_01() {\r
+ Assert.assertFalse(new Wildcard("abcd", true).IsMatch("a"));\r
+ Assert.assertFalse(new Wildcard("*.cs", true).IsMatch("hello.csc"));\r
+\r
+ Assert.assertTrue(new Wildcard("", true).IsMatch(""));\r
+ Assert.assertFalse(new Wildcard("", true).IsMatch("asdsad"));\r
+\r
+ Assert.assertTrue(new Wildcard("*.cs", true).IsMatch("hello.cs"));\r
+ Assert.assertTrue(new Wildcard("h*.cs", true).IsMatch("hello.cs"));\r
+ Assert.assertFalse(new Wildcard("a*.cs", true).IsMatch("hello.cs"));\r
+ Assert.assertTrue(new Wildcard("*.cs*", true).IsMatch("hello.cs"));\r
+ Assert.assertTrue(new Wildcard("*.cs", true).IsMatch(".cs"));\r
+ Assert.assertFalse(new Wildcard("*.cs", true).IsMatch("hello.s"));\r
+\r
+ Assert.assertTrue(new Wildcard("*a*c", true).IsMatch("1221abcccac"));\r
+ Assert.assertTrue(new Wildcard("a", true).IsMatch("a"));\r
+ Assert.assertTrue(new Wildcard("?", true).IsMatch("z"));\r
+ Assert.assertFalse(new Wildcard("*?*", true).IsMatch(""));\r
+ Assert.assertTrue(new Wildcard("*?*", true).IsMatch("k"));\r
+\r
+ }\r
+\r
+ @Test\r
+ public void test_02() {\r
+ Assert.assertTrue(new Wildcard("*?**", true).IsMatch("k"));\r
+ Assert.assertTrue(new Wildcard("*?*", true).IsMatch("111k"));\r
+ Assert.assertTrue(new Wildcard("*?*", true).IsMatch("11k22"));\r
+ Assert.assertTrue(new Wildcard("*?*m*", true).IsMatch("11mk22"));\r
+ Assert.assertFalse(new Wildcard("*??*m*", true).IsMatch("1mk22"));\r
+ Assert.assertTrue(\r
+ new Wildcard("*non-greedy character*matching", true).IsMatch(\r
+ "non-greedy character matching compared to greedy character matching"));\r
+ Assert.assertFalse(\r
+ new Wildcard("*non-greedy character*matching2", true).IsMatch(\r
+ "non-greedy character matching compared to greedy character matching"));\r
+ }\r
+}\r