mizipzor avatar mizipzor committed fed2edc

Minor polish and fixes.

Comments (0)

Files changed (5)

 {
     internal sealed class Options : CommandLineOptionsBase
     {
-        [Option("b", "build",
-            HelpText = "The build to download artifacts from")]
+        [Option("u", "url", Required = true,
+            HelpText = "Url to TeamCity instance.")]
+        public string Url { get; set; }
+
+        [Option("b", "build", Required = true,
+            HelpText = "The build to download artifacts from.")]
         public string BuildType { get; set; }
 
         [Option("i", "build-id", DefaultValue = "lastFinished",
-            HelpText = "The specific build to download (default: lastFinished)")]
+            HelpText = "The specific build to download (default: lastFinished).")]
         public string BuildId { get; set; }
 
         [Option("o", "outdir",
-            HelpText = "Directory to download files to (default: current)")]
+            HelpText = "Directory to download files to (default: current).")]
         public string OutDir { get; set; }
 
+        [Option("g", "glob", DefaultValue = "*.*",
+            HelpText = "Only download files matching glob expression.")]
+        public string Glob { get; set; }
+
         [Option("d", "dry-run",
-            HelpText = "Do not download any artifacts")]
+            HelpText = "Do not download any artifacts.")]
         public bool Dry { get; set; }
 
-        [Option("g", "glob", DefaultValue = "*.*",
-            HelpText = "Only download files matching glob expression")]
-        public string Glob { get; set; }
+        [Option("f", "flatten", DefaultValue = false,
+            HelpText = "Flatten the artifact folder structure.")]
+        public bool FlattenArtifactFolders { get; set; }
 
         [Option("v", "verbose",
-            HelpText = "Print every handled artifact")]
+            HelpText = "Print every handled artifact.")]
         public bool Verbose { get; set; }
 
-        [Option("r", "recursive",
-            HelpText = "If true, keeps the artifact folder structure as seen on TeamCity")]
-        public bool Recursive { get; set; }
-
-        [Option("u", "url",
-            HelpText = "Url to TeamCity instance.")]
-        public string Url { get; set; }
-
         [Option(null, "hidden", DefaultValue = false,
-            HelpText = "Include TeamCity generated hidden artifacts")]
+            HelpText = "Include TeamCity generated hidden artifacts.")]
         public bool IncludeHidden { get; set; }
 
         [HelpOption]
 {
     internal class Program
     {
-        private static void Main(string[] args)
+        private static int Main(string[] args)
         {
             var options = new Options();
             if (CommandLineParser.Default.ParseArguments(args, options))
             {
-                new TeamCityArtifactDownloader(options).Run();
+                return new TeamCityArtifactDownloader(options).Run();
             }
+            return -1;
         }
     }
 }

Properties/AssemblyInfo.cs

 using System.Reflection;
-using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 
 // General Information about an assembly is controlled through the following 
 // set of attributes. Change these attribute values to modify the information
 // associated with an assembly.
 [assembly: AssemblyTitle("tcad")]
+[assembly: AssemblyProduct("TeamCity Artifact Downloader")]
 
 // Setting ComVisible to false makes the types in this assembly not visible 
 // to COM components.  If you need to access a type in this assembly from 
 // You can specify all the values or you can default the Build and Revision Numbers 
 // by using the '*' as shown below:
 // [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("0.0.0.*")]
-[assembly: AssemblyFileVersion("0.0.0.*")]
-[assembly: AssemblyInformationalVersion("0.0.0.*")]
-
+[assembly: AssemblyVersion("0.0.1.*")]

TeamCityArtifactDownloader.cs

 using System.Net;
 using System.Text;
 using System.Xml;
-
-using tccli;
+using tcad;
 
 namespace Tcad
 {
     internal class TeamCityArtifactDownloader
     {
         private readonly Options options;
+        private string outdir;
         private UriBuilder uriBuilder;
-        private string outdir;
 
         public TeamCityArtifactDownloader(Options options)
         {
         /// <returns>Exit code.</returns>
         public int Run()
         {
-            // make sure a host was specified
-            if (options.Url == null)
-            {
-                // TODO tell user how to specify host
-
-                return -1;
-            }
-
             // enforce trailing separator for simplicity
             outdir = options.OutDir ?? Directory.GetCurrentDirectory();
             if (!outdir.EndsWith(Path.DirectorySeparatorChar.ToString()))
 
             // if no protocol is specified the uribuilder gets confused
             uriBuilder = new UriBuilder(options.Url.Contains("://")
-                ? options.Url :
-                "http://" + options.Url);
+                ? options.Url
+                : "http://" + options.Url);
 
-            // if credentials is not supplied, go interactive
+            // if credentials are not supplied prompt user
             if (!EnsureCredentials())
             {
                 return 0;
                 artifactPath = artifactPath.Replace(
                     '/', Path.DirectorySeparatorChar);
             }
-            localPath += options.Recursive
-                ? artifactPath
-                : artifactPath.Split(Path.DirectorySeparatorChar).Last();
+            localPath += options.FlattenArtifactFolders
+                ? artifactPath.Split(Path.DirectorySeparatorChar).Last()
+                : artifactPath;
 
             // make sure output directory exists
             string directory = Path.GetDirectoryName(localPath);
         /// <returns></returns>
         public IEnumerable<string> GetArtifacts()
         {
-            List<string> list = new List<string>();
-            using (MemoryStream stream = new MemoryStream())
+            var list = new List<string>();
+            using (var stream = new MemoryStream())
             {
                 string path = CreateFileRequest("teamcity-ivy.xml");
                 HttpWebRequest request = CreateWebRequest(path);
                 Utils.DownloadFile(request, stream);
                 stream.Seek(0, SeekOrigin.Begin);
-                XmlTextReader reader = new XmlTextReader(stream);
+                var reader = new XmlTextReader(stream);
                 while (reader.Read())
                 {
                     if (reader.NodeType != XmlNodeType.Element ||
 
         private HttpWebRequest CreateWebRequest(string uri)
         {
-            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
+            var request = (HttpWebRequest)WebRequest.Create(uri);
             //request.Proxy = null;
             string authInfo = CreateAuthInfo();
             request.Headers["Authorization"] = "Basic " + authInfo;
-using System;
-using System.IO;
+using System.IO;
 using System.Net;
 using System.Text.RegularExpressions;
 
-namespace tccli
+namespace tcad
 {
     public static class Utils
     {
                 // Jump to the start position of the stream
                 stream.Seek(0, SeekOrigin.Begin);
 
-                StreamReader reader = new StreamReader(stream);
+                var reader = new StreamReader(stream);
                 return reader.ReadToEnd();
             }
         }
                         if (remoteStream != null)
                         {
                             // Allocate a 1k buffer
-                            byte[] buffer = new byte[1024];
+                            var buffer = new byte[1024];
                             int bytesRead;
 
                             // Simple do/while loop to read from stream until
 
                                 // Increment total bytes processed
                                 bytesProcessed += bytesRead;
-                            }
-                            while (bytesRead > 0);
+                            } while (bytesRead > 0);
                         }
                     }
                 }
         {
             return new Regex(
                 "^" + Regex.Escape(wildcard).Replace(@"\*", ".*").Replace(@"\?", ".") + "$",
-                RegexOptions.IgnoreCase | RegexOptions.Singleline
-            ).IsMatch(str);
+                RegexOptions.IgnoreCase | RegexOptions.Singleline)
+                .IsMatch(str);
         }
     }
-}
+}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.