public void TestExtractRegex()
        {
            BuildArtifactsMapping mapping = new BuildArtifactsMapping();

            mapping.input = @"obj\Debug\(.+)\(.+).dll";
            string regex = BuildArtifactsMapping.getRegexPattern(mapping);
            string regexExpect = @"(.+)\(.+).dll";
            Assert.AreEqual(regex, regexExpect);
        }
        public static string getRegexPattern(BuildArtifactsMapping mapping)
        {
            string rootDirectory = getRootDirectory(mapping);

            if (String.IsNullOrWhiteSpace(rootDirectory))
                return mapping.input;

            return mapping.input.Replace(rootDirectory, String.Empty);
        }
 public void TestExtractRootDirectory()
 {
     BuildArtifactsMapping mapping = new BuildArtifactsMapping();
     
     mapping.input = @"obj\Debug\(.+)\(.+).dll";
     string path = BuildArtifactsMapping.getRootDirectory(mapping);
     string pathExpect = @"obj\Debug\";
     Assert.AreEqual(path, pathExpect);
 }
        public static string getRootDirectory(BuildArtifactsMapping mapping)
        {
            string input = mapping.input;
            int firstParenthesesIndex = input.IndexOf("(");
            if (firstParenthesesIndex == -1)
                return input;

            return input.Substring(0, firstParenthesesIndex);
        }
        public static string getRegexPattern(BuildArtifactsMapping mapping)
        {
            string rootDirectory = getRootDirectory(mapping);

            if (String.IsNullOrWhiteSpace(rootDirectory))
            {
                return(mapping.input);
            }

            return(mapping.input.Replace(rootDirectory, String.Empty));
        }
        public static string getRootDirectory(BuildArtifactsMapping mapping)
        {
            string input = mapping.input;
            int    firstParenthesesIndex = input.IndexOf("(");

            if (firstParenthesesIndex == -1)
            {
                return(input);
            }

            return(input.Substring(0, firstParenthesesIndex));
        }
        private static string NormalizeRegexInput(BuildArtifactsMapping mapping)
        {
            string regexNormalize = mapping.input.Replace("\\", "\\\\");
            Regex reg = new Regex(@"(\(.*?\))");
            Match matchParentheses = reg.Match(regexNormalize);
            while (matchParentheses.Success) 
            {
                regexNormalize = regexNormalize.Replace(matchParentheses.Value, Regex.Unescape(matchParentheses.Value));
                matchParentheses = matchParentheses.NextMatch();
            }

            return regexNormalize;
        }
        private static string NormalizeRegexInput(BuildArtifactsMapping mapping)
        {
            string regexNormalize   = mapping.input.Replace("\\", "\\\\");
            Regex  reg              = new Regex(@"(\(.*?\))");
            Match  matchParentheses = reg.Match(regexNormalize);

            while (matchParentheses.Success)
            {
                regexNormalize   = regexNormalize.Replace(matchParentheses.Value, Regex.Unescape(matchParentheses.Value));
                matchParentheses = matchParentheses.NextMatch();
            }

            return(regexNormalize);
        }
        public void TestPlaceHoldersList()
        {
            BuildArtifactsMapping mapping = new BuildArtifactsMapping();
            ISet<Int32> groupList = null;

            mapping.output = "a-$1-$2-$3.dll";
            groupList = BuildArtifactsMapping.getPlaceHoldersList(mapping, 3);
            CollectionAssert.AreEqual(groupList, new HashSet<Int32>() { 1, 2, 3 });

            AssertExtension.Throws<ArgumentException>(() => BuildArtifactsMapping.getPlaceHoldersList(mapping, 2));

            mapping.output = "a-$1-$Z-$3.dll";
            AssertExtension.Throws<ArgumentException>(() => BuildArtifactsMapping.getPlaceHoldersList(mapping, 3));
        }
        public void TestLessPlaceholdersInOutput()
        {
            string projectPath = Path.GetDirectoryName(Path.GetDirectoryName(System.IO.Directory.GetCurrentDirectory()));
            Dictionary<string, string> resultMap = new Dictionary<string, string>();
            BuildArtifactsMapping mapping = new BuildArtifactsMapping();

            mapping.input = @"regex_test\(.+)\(.+).dll";
            mapping.output = @"a/$2.dll";

            BuildArtifactsMappingResolver.matchMappingArtifacts(mapping, projectPath, resultMap);
            Dictionary<string, string> resultMapExpected = new Dictionary<string, string>();

            CollectionAssert.Contains(resultMap, new KeyValuePair<string, string>(projectPath + @"\regex_test\obj\Debug\JFrog.Artifactory.dll",
                                                                                                @"a/JFrog.Artifactory.dll"));
        }
 public static List<DeployDetails> resolve(ProjectModel.DeployAttribute deployAttribute, string projectDirectory, string repository)
 {          
     Dictionary<string, string> resultMap = new Dictionary<string, string>();
     BuildArtifactsMapping mapping = new BuildArtifactsMapping(deployAttribute.InputPattern, deployAttribute.OutputPattern);
     BuildArtifactsMappingResolver.matchMappingArtifacts(mapping, projectDirectory, resultMap);
   
     return resultMap.Select(a => new DeployDetails
     {
         artifactPath = a.Value,
         file = new FileInfo(a.Key),
         md5 = MD5CheckSum.GenerateMD5(a.Key),
         sha1 = Sha1Reference.GenerateSHA1(a.Key),
         targetRepository = repository
     }).ToList();
 }
        public static List <DeployDetails> resolve(ProjectModel.DeployAttribute deployAttribute, string projectDirectory, string repository)
        {
            Dictionary <string, string> resultMap = new Dictionary <string, string>();
            BuildArtifactsMapping       mapping   = new BuildArtifactsMapping(deployAttribute.InputPattern, deployAttribute.OutputPattern);

            BuildArtifactsMappingResolver.matchMappingArtifacts(mapping, projectDirectory, resultMap);

            return(resultMap.Select(a => new DeployDetails
            {
                artifactPath = a.Value,
                file = new FileInfo(a.Key),
                md5 = MD5CheckSum.GenerateMD5(a.Key),
                sha1 = Sha1Reference.GenerateSHA1(a.Key),
                targetRepository = repository
            }).ToList());
        }
        public void TestComplexRegex()
        {
            string projectPath = Path.GetDirectoryName(Path.GetDirectoryName(System.IO.Directory.GetCurrentDirectory()));
            Dictionary<string, string> resultMap = new Dictionary<string, string>();
            BuildArtifactsMapping mapping = new BuildArtifactsMapping();

            //Enforce only file with digits
            mapping.input = @"regex_test\(.+)\(.+[\d].+)";
            mapping.output = @"a/$2";

            BuildArtifactsMappingResolver.matchMappingArtifacts(mapping, projectPath, resultMap);
            Dictionary<string, string> resultMapExpected = new Dictionary<string, string>();

            CollectionAssert.Contains(resultMap, new KeyValuePair<string, string>(
                                            projectPath + @"\regex_test\lib\TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs",
                                                          @"a/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs"
                                     ));
        }
        // override object.Equals
        public override bool Equals(Object obj)
        {
            if (obj == null)
            {
                return(false);
            }

            BuildArtifactsMapping p = obj as BuildArtifactsMapping;

            if ((System.Object)p == null)
            {
                return(false);
            }

            if (p.input.Equals(this.input) && p.output.Equals(this.output))
            {
                return(true);
            }

            return(false);
        }
        public static ISet <Int32> getPlaceHoldersList(BuildArtifactsMapping mapping, int inputGroupsNum)
        {
            HashSet <Int32> placeHoldersSet = new HashSet <Int32>();

            if (String.IsNullOrWhiteSpace(mapping.output) || inputGroupsNum < 1)
            {
                // No output mapping or input has no capturing groups
                return(placeHoldersSet);
            }

            Match placeHoldersMatcher = Regex.Match(mapping.output, PLACE_HOLDER_PATTERN);

            // int capturingNumber = 1;
            while (placeHoldersMatcher.Success)
            {
                int    placeHolderGroupNum;
                string group = placeHoldersMatcher.Groups[1].Value;
                try
                {
                    placeHolderGroupNum = Int32.Parse(group);

                    if (placeHolderGroupNum > inputGroupsNum)
                    {
                        throw new ArgumentException(String.Format("Place holder number '{0}' exceeds the number of capture groups ('{1}') in the matching mapping input '{2}'",
                                                                  placeHolderGroupNum, inputGroupsNum, mapping.input));
                    }
                }
                catch (FormatException e)
                {
                    throw new ArgumentException(String.Format("Place holder '{0}' from mapping output '{1}' is not a valid number", group, mapping.output), e.InnerException);
                }

                placeHoldersSet.Add(placeHolderGroupNum);
                // capturingNumber++;
                placeHoldersMatcher = placeHoldersMatcher.NextMatch();
            }

            return(placeHoldersSet);
        }
        public static ISet<Int32> getPlaceHoldersList(BuildArtifactsMapping mapping, int inputGroupsNum)
        {
            HashSet<Int32> placeHoldersSet = new HashSet<Int32>();

            if (String.IsNullOrWhiteSpace(mapping.output) || inputGroupsNum < 1) 
            {
                // No output mapping or input has no capturing groups
                return placeHoldersSet;
            }

            Match placeHoldersMatcher = Regex.Match(mapping.output, PLACE_HOLDER_PATTERN);
           // int capturingNumber = 1;
            while (placeHoldersMatcher.Success)
            {
                int placeHolderGroupNum;
                string group = placeHoldersMatcher.Groups[1].Value;
                try 
                {
                    placeHolderGroupNum = Int32.Parse(group);

                    if (placeHolderGroupNum > inputGroupsNum) 
                    {
                        throw new ArgumentException(String.Format("Place holder number '{0}' exceeds the number of capture groups ('{1}') in the matching mapping input '{2}'",
                            placeHolderGroupNum, inputGroupsNum, mapping.input));
                    }
                }
                catch (FormatException e)
                {                 
                    throw new ArgumentException(String.Format("Place holder '{0}' from mapping output '{1}' is not a valid number", group, mapping.output), e.InnerException);
                }

                placeHoldersSet.Add(placeHolderGroupNum);
               // capturingNumber++;
                placeHoldersMatcher = placeHoldersMatcher.NextMatch();
            }

            return placeHoldersSet;
        }
        public void TestMatchMapping()
        {
            BuildArtifactsMapping mapping = new BuildArtifactsMapping();
            mapping.input = @"regex_test\(.+)\(.+).dll";
            mapping.output = @"msbuild-test\$1\$2.dll";
            
            Dictionary<string, string> resultMap = new Dictionary<string, string>();
            string projectPath = Path.GetDirectoryName(Path.GetDirectoryName(System.IO.Directory.GetCurrentDirectory()));

            BuildArtifactsMappingResolver.matchMappingArtifacts(mapping, projectPath, resultMap);

            Dictionary<string, string> resultMapExpected = new Dictionary<string, string>();
            resultMapExpected.Add(projectPath + @"\regex_test\lib\JFrog.Artifactory.dll",
                                        @"msbuild-test\lib\JFrog.Artifactory.dll");
            resultMapExpected.Add(projectPath + @"\regex_test\obj\Debug\JFrog.Artifactory.dll",
                                        @"msbuild-test\obj\Debug\JFrog.Artifactory.dll");
            resultMapExpected.Add(projectPath + @"\regex_test\obj\Release\JFrog.Artifactory.dll",
                                        @"msbuild-test\obj\Release\JFrog.Artifactory.dll");

            CollectionAssert.AreEqual(resultMap, resultMapExpected);


            mapping.input = @"regex_test\(.+)\(.+).dll";
            mapping.output = @"msbuild-test\$2\$1.dll";

            resultMap.Clear();
            resultMapExpected.Clear();
            BuildArtifactsMappingResolver.matchMappingArtifacts(mapping, projectPath, resultMap);        
            resultMapExpected.Add(projectPath + @"\regex_test\lib\JFrog.Artifactory.dll",
                                        @"msbuild-test\JFrog.Artifactory\lib.dll");
            resultMapExpected.Add(projectPath + @"\regex_test\obj\Debug\JFrog.Artifactory.dll",
                                        @"msbuild-test\JFrog.Artifactory\obj\Debug.dll");
            resultMapExpected.Add(projectPath + @"\regex_test\obj\Release\JFrog.Artifactory.dll",
                                        @"msbuild-test\JFrog.Artifactory\obj\Release.dll");

            //none exists folder need to check
            CollectionAssert.AreEqual(resultMap, resultMapExpected);
        }
        public static void matchMappingArtifacts(BuildArtifactsMapping mapping, string projectDirectory, Dictionary<string, string> resultMap)
        {           
            string rootDirectory = BuildArtifactsMapping.getRootDirectory(mapping);

            /*Incase we have none relative pattern, we need to add the project path for the 
             * regular expression not to recognize it as part of the capturing groups. 
             */
            //if (String.IsNullOrWhiteSpace(rootDirectory) || !System.IO.Path.IsPathRooted(rootDirectory))
            if (!System.IO.Path.IsPathRooted(rootDirectory))
            {
                mapping.input = projectDirectory + "\\" + mapping.input;
                rootDirectory = projectDirectory + "\\" + rootDirectory; 
            }

            if (Directory.Exists(rootDirectory) || File.Exists(rootDirectory))
            {
                IEnumerable<string> fileList;
                //Incase we have a path with a file
                if (File.Exists(rootDirectory))
                {
                    fileList = new string[] { rootDirectory };
                }
                else 
                {
                    fileList = Directory.GetFiles(rootDirectory, "*.*", SearchOption.AllDirectories);
                }


                string regexNormalize = NormalizeRegexInput(mapping);
                Regex regex = new Regex(regexNormalize);
                int inputGroupsNum = regex.GetGroupNumbers().Length - 1;

                ISet<Int32> placeHoldersSet = BuildArtifactsMapping.getPlaceHoldersList(mapping, inputGroupsNum);

                foreach (string file in fileList)
                {
                    Match fileMatcher = regex.Match(file);
                    if (fileMatcher.Success)
                    {
                        /* In case we didn't receive an output pattern, 
                        *   the target will be the root of the repository
                        */
                        if (String.IsNullOrWhiteSpace(mapping.output))
                        {
                            FileInfo fileInfo = new FileInfo(file);
                            resultMap.Add(file, fileInfo.Name);
                        }
                        else
                        {
                            List<string> replacementList = new List<string>();
                            string repositoryPath = mapping.output;

                            foreach (int groupIndex in placeHoldersSet) 
                            {
                                repositoryPath = repositoryPath.Replace("$" + groupIndex, fileMatcher.Groups[groupIndex].Value);
                            }

                            if (!resultMap.ContainsKey(file))
                                resultMap.Add(file, repositoryPath);
                        }
                    }
                }
            }
        }
        public static void matchMappingArtifacts(BuildArtifactsMapping mapping, string projectDirectory, Dictionary <string, string> resultMap)
        {
            string rootDirectory = BuildArtifactsMapping.getRootDirectory(mapping);

            /*Incase we have none relative pattern, we need to add the project path for the
             * regular expression not to recognize it as part of the capturing groups.
             */
            //if (String.IsNullOrWhiteSpace(rootDirectory) || !System.IO.Path.IsPathRooted(rootDirectory))
            if (!System.IO.Path.IsPathRooted(rootDirectory))
            {
                mapping.input = projectDirectory + "\\" + mapping.input;
                rootDirectory = projectDirectory + "\\" + rootDirectory;
            }

            if (Directory.Exists(rootDirectory) || File.Exists(rootDirectory))
            {
                IEnumerable <string> fileList;
                //Incase we have a path with a file
                if (File.Exists(rootDirectory))
                {
                    fileList = new string[] { rootDirectory };
                }
                else
                {
                    fileList = Directory.GetFiles(rootDirectory, "*.*", SearchOption.AllDirectories);
                }


                string regexNormalize = NormalizeRegexInput(mapping);
                Regex  regex          = new Regex(regexNormalize);
                int    inputGroupsNum = regex.GetGroupNumbers().Length - 1;

                ISet <Int32> placeHoldersSet = BuildArtifactsMapping.getPlaceHoldersList(mapping, inputGroupsNum);

                foreach (string file in fileList)
                {
                    Match fileMatcher = regex.Match(file);
                    if (fileMatcher.Success)
                    {
                        /* In case we didn't receive an output pattern,
                         *   the target will be the root of the repository
                         */
                        if (String.IsNullOrWhiteSpace(mapping.output))
                        {
                            FileInfo fileInfo = new FileInfo(file);
                            resultMap.Add(file, fileInfo.Name);
                        }
                        else
                        {
                            List <string> replacementList = new List <string>();
                            string        repositoryPath  = mapping.output;

                            foreach (int groupIndex in placeHoldersSet)
                            {
                                repositoryPath = repositoryPath.Replace("$" + groupIndex, fileMatcher.Groups[groupIndex].Value);
                            }

                            if (!resultMap.ContainsKey(file))
                            {
                                resultMap.Add(file, repositoryPath);
                            }
                        }
                    }
                }
            }
        }