Skip to content
This repository was 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
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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