Skip to content
This repository has been archived by the owner on Feb 12, 2019. It is now read-only.

Updated to newest version of TC API + new method to create project with projectId #98

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
1 change: 1 addition & 0 deletions packages/repositories.config
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
<repositories>
<repository path="..\src\Samples\TeamCitySharp.BuildMonitor\packages.config" />
<repository path="..\src\TeamCitySharp\packages.config" />
<repository path="..\src\Tests\IntegrationTests\packages.config" />
<repository path="..\src\Tests\UnitTests\packages.config" />
</repositories>
2 changes: 1 addition & 1 deletion src/TeamCitySharp/ActionTypes/BuildConfigs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public BuildConfig ByProjectIdAndConfigurationId(string projectId, string buildC

public List<BuildConfig> ByProjectId(string projectId)
{
var buildWrapper = _caller.GetFormat<BuildTypeWrapper>("/app/rest/projects/id:{0}/buildTypes", projectId);
var buildWrapper = _caller.GetFormat<BuildTypeWrapper>("/app/rest/projects/{0}/buildTypes", projectId);

if (buildWrapper == null || buildWrapper.BuildType == null) return new List<BuildConfig>();
return buildWrapper.BuildType;
Expand Down
2 changes: 2 additions & 0 deletions src/TeamCitySharp/ActionTypes/IProjects.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ public interface IProjects
Project ById(string projectLocatorId);
Project Details(Project project);
Project Create(string projectName);
Project Create(string projectName, string projectId);
void Delete(string projectName);
void DeleteProjectParameter(string projectName, string parameterName);
void SetProjectParameter(string projectName, string settingName, string settingValue);
bool SetName(string projectCode, string name);
}
}
9 changes: 9 additions & 0 deletions src/TeamCitySharp/ActionTypes/IUserGroups.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace TeamCitySharp.ActionTypes
{
public interface IUserGroups
{
bool AddGroup(string groupKey, string groupName);
bool RemoveGroup(string groupKey);
bool AddRoleToGroup(string groupKey, string roleId, string projectKey);
}
}
1 change: 1 addition & 0 deletions src/TeamCitySharp/ActionTypes/IUsers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ public interface IUsers
List<Role> AllUserRolesByUserGroup(string userGroupName);
bool Create(string username, string name, string email, string password);
bool AddPassword(string username, string password);
bool AddUserToGroup(string username, string groupKey);
}
}
1 change: 1 addition & 0 deletions src/TeamCitySharp/ActionTypes/IVcsRoots.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ public interface IVcsRoots
VcsRoot AttachVcsRoot(BuildTypeLocator locator, VcsRoot vcsRoot);
void DetachVcsRoot(BuildTypeLocator locator, string vcsRootId);
void SetVcsRootField(VcsRoot vcsRoot, VcsRootField field, object value);
VcsRoot Create(VcsRoot root);
}
}
61 changes: 55 additions & 6 deletions src/TeamCitySharp/ActionTypes/Projects.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@

namespace TeamCitySharp.ActionTypes
{
using System.Net;

using EasyHttp.Infrastructure;

internal class Projects : IProjects
{
private readonly TeamCityCaller _caller;
Expand All @@ -23,16 +27,12 @@ public List<Project> All()

public Project ByName(string projectLocatorName)
{
var project = _caller.GetFormat<Project>("/app/rest/projects/name:{0}", projectLocatorName);

return project;
return GetProject(string.Format("name:{0}", projectLocatorName));
}

public Project ById(string projectLocatorId)
{
var project = _caller.GetFormat<Project>("/app/rest/projects/id:{0}", projectLocatorId);

return project;
return GetProject(projectLocatorId);
}

public Project Details(Project project)
Expand All @@ -45,6 +45,37 @@ public Project Create(string projectName)
return _caller.Post<Project>(projectName, HttpContentTypes.TextPlain, "/app/rest/projects/", HttpContentTypes.ApplicationJson);
}

public bool SetName(string projectCode, string name)
{
try
{
var response = _caller.Put(name, HttpContentTypes.TextPlain, string.Format("/app/rest/projects/{0}/name", projectCode), null);
return response.StatusCode == HttpStatusCode.OK;
}
catch (HttpException ex)
{
if (ex.StatusCode == HttpStatusCode.NotFound)
{
return false;
}

throw;
}
}

public Project Create(string projectName, string projectId)
{

var content = string.Format
(@"<newProjectDescription name='{0}' id='{1}' copyAllAssociatedSettings='true'> </newProjectDescription>"
, projectName, projectId);
/* extended xml version:
* <newProjectDescription name='New Project Name' id='newProjectId' copyAllAssociatedSettings='true'><parentProject locator='id:project1'/><sourceProject locator='id:project2'/></newProjectDescription>
* more details could be found in documentation: https://confluence.jetbrains.com/display/TCD9/REST+API#RESTAPI-ProjectSettings
*/
return _caller.Post<Project>(content, HttpContentTypes.ApplicationXml, "/app/rest/projects/", HttpContentTypes.ApplicationJson);
}

public void Delete(string projectName)
{
_caller.DeleteFormat("/app/rest/projects/name:{0}", projectName);
Expand All @@ -59,5 +90,23 @@ public void SetProjectParameter(string projectName, string settingName, string s
{
_caller.PutFormat(settingValue, "/app/rest/projects/name:{0}/parameters/{1}", projectName, settingName);
}

private Project GetProject(string locator)
{
try
{
var project = _caller.GetFormat<Project>("/app/rest/projects/{0}", locator);
return project;
}
catch (HttpException ex)
{
if (ex.StatusCode == HttpStatusCode.NotFound)
{
return null;
}

throw;
}
}
}
}
64 changes: 64 additions & 0 deletions src/TeamCitySharp/ActionTypes/UserGroups.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using System.Collections.Generic;
using System.Net;

using EasyHttp.Http;

using TeamCitySharp.Connection;
using TeamCitySharp.Util;

namespace TeamCitySharp.ActionTypes
{
using EasyHttp.Infrastructure;

internal class UserGroups : IUserGroups
{
private readonly TeamCityCaller _caller;

internal UserGroups(TeamCityCaller caller)
{
_caller = caller;
}

public bool AddGroup(string groupKey, string groupName)
{
ArgumentUtil.CheckNotNull(() => groupKey, () => groupName);

var attributesDictionary = new Dictionary<string, string> { { "key", groupKey }, { "name", groupName } };
var payload = XmlUtil.SingleElementDocument("group", attributesDictionary);
var response = _caller.Post(payload, HttpContentTypes.ApplicationXml, "/app/rest/userGroups", null);

return response.StatusCode == HttpStatusCode.OK;
}

public bool RemoveGroup(string groupKey)
{
ArgumentUtil.CheckNotNull(() => groupKey);

try
{
_caller.Delete(string.Format("/app/rest/userGroups/key:{0}", groupKey));
return true;
}
catch (HttpException ex)
{
if (ex.StatusCode == HttpStatusCode.NotFound)
{
return false;
}

throw;
}
}

public bool AddRoleToGroup(string groupKey, string roleId, string projectKey)
{
ArgumentUtil.CheckNotNull(() => groupKey, () => roleId, () => projectKey);

var attributesDictionary = new Dictionary<string, string> { { "roleId", roleId }, { "scope", string.Format("p:{0}", projectKey) } };
var payload = XmlUtil.SingleElementDocument("role", attributesDictionary);
var response = _caller.Post(payload, HttpContentTypes.ApplicationXml, string.Format("/app/rest/userGroups/key:{0}/roles", groupKey), null);

return response.StatusCode == HttpStatusCode.OK;
}
}
}
31 changes: 31 additions & 0 deletions src/TeamCitySharp/ActionTypes/Users.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,13 @@
using TeamCitySharp.Connection;
using TeamCitySharp.DomainEntities;

using TeamCitySharp.Locators;
using TeamCitySharp.Util;

namespace TeamCitySharp.ActionTypes
{
using EasyHttp.Infrastructure;

internal class Users : IUsers
{
private readonly TeamCityCaller _caller;
Expand Down Expand Up @@ -100,5 +105,31 @@ public bool AddPassword(string username, string password)
return result;
}

public bool AddUserToGroup(string username, string groupKey)
{
ArgumentUtil.CheckNotNull(() => username, () => groupKey);

var attributesDictionary = new Dictionary<string, string> { { "key", groupKey } };
var payload = XmlUtil.SingleElementDocument("group", attributesDictionary);

try
{
var response = _caller.Post(
payload,
HttpContentTypes.ApplicationXml,
string.Format("/app/rest/users/{0}/groups", UserLocator.WithUserName(username)),
null);
return response.StatusCode == HttpStatusCode.OK;
}
catch (HttpException ex)
{
if (ex.StatusCode == HttpStatusCode.NotFound)
{
return false;
}

throw;
}
}
}
}
31 changes: 31 additions & 0 deletions src/TeamCitySharp/ActionTypes/VcsRoots.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EasyHttp.Http;
using TeamCitySharp.Connection;
using TeamCitySharp.DomainEntities;
Expand Down Expand Up @@ -30,6 +32,35 @@ public VcsRoot ById(string vcsRootId)
return vcsRoot;
}


public VcsRoot Create(VcsRoot root)
{
var sb = new StringBuilder();
var rootStr =
string.Format(
@"<vcs-root id=""{0}"" name=""{1}"" vcsName=""{2}"" status=""{3}"">"
,root.Id,root.Name,root.vcsName,root.Status);
sb.Append(rootStr);
var projectStr =
string.Format(
@"<project id=""{0}"" name=""{1}"" />"
,root.Project.Id,root.Project.Name);
sb.Append(projectStr);
if (root.Properties != null && root.Properties.Property != null && root.Properties.Property.Any())
{
sb.Append(string.Format(@"<properties count=""{0}"">", root.Properties.Property.Count));
foreach (var property in root.Properties.Property)
{
sb.Append(string.Format(@"<property name = ""{0}"" value = ""{1}""/>", property.Name, property.Value));
}
sb.Append(@"</properties>");
}
sb.Append("</vcs-root>");
var xml = sb.ToString();

return _caller.PostFormat<VcsRoot>(xml, HttpContentTypes.ApplicationXml, HttpContentTypes.ApplicationJson, "/app/rest/vcs-roots/");
}

public VcsRoot AttachVcsRoot(BuildTypeLocator locator, VcsRoot vcsRoot)
{
var xml = string.Format(@"<vcs-root-entry><vcs-root id=""{0}""/></vcs-root-entry>", vcsRoot.Id);
Expand Down
3 changes: 3 additions & 0 deletions src/TeamCitySharp/DomainEntities/Role.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
{
public class Role
{
public const string ProjectAdministrator = "PROJECT_ADMIN";
public const string ProjectDeveloper = "PROJECT_DEVELOPER";

public string Href { get; set; }
public string Scope { get; set; }
public string RoleId { get; set; }
Expand Down
2 changes: 2 additions & 0 deletions src/TeamCitySharp/DomainEntities/VcsRoot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,7 @@ public override string ToString()
}

public Properties Properties { get; set; }
public Project Project { get; set; }

}
}
1 change: 1 addition & 0 deletions src/TeamCitySharp/ITeamCityClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public interface ITeamCityClient
IProjects Projects { get; }
IServerInformation ServerInformation { get; }
IUsers Users { get; }
IUserGroups UserGroups { get; }
IAgents Agents { get; }
IVcsRoots VcsRoots { get; }
IChanges Changes { get; }
Expand Down
10 changes: 8 additions & 2 deletions src/TeamCitySharp/TeamCityClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@ public class TeamCityClient : IClientConnection, ITeamCityClient
private IBuildConfigs _buildConfigs;
private IServerInformation _serverInformation;
private IUsers _users;
private IUserGroups _userGroups;
private IAgents _agents;
private IVcsRoots _vcsRoots;
private IChanges _changes;
private IBuildArtifacts _artifacts;
private IBuildArtifacts _artifacts;

public TeamCityClient(string hostName, bool useSsl = false)
{
_caller = new TeamCityCaller(hostName, useSsl);
Expand Down Expand Up @@ -61,6 +62,11 @@ public IUsers Users
get { return _users ?? (_users = new Users(_caller)); }
}

public IUserGroups UserGroups
{
get { return _userGroups ?? (_userGroups = new UserGroups(_caller)); }
}

public IAgents Agents
{
get { return _agents ?? (_agents = new Agents(_caller)); }
Expand Down
Loading