Ejemplo n.º 1
0
		/// <summary>
		/// Creates a repository for the given student, and pushes the non-test files
		/// from the source project to the new repository.
		/// </summary>
		private async Task<CreateAndPushResult> CreateAndPushAsync(
			Project project,
			ClassroomMembership student,
			string webhookUrl,
			bool overwriteIfSafe,
			ICollection<GitHubTeam> teams,
			ICollection<GitHubRepository> repositories,
			IArchive templateContents)
		{
			string orgName = project.Classroom.GitHubOrganization;
			string repoName = $"{project.Name}_{student.GitHubTeam}";

			try
			{
				var repository = repositories.SingleOrDefault(repo => repo.Name == repoName);
				var team = teams.First(teamCandidate => teamCandidate.Name == student.GitHubTeam);
				bool repositoryAlreadyExisted = (repository != null);

				if (repositoryAlreadyExisted)
				{
					if (!overwriteIfSafe)
						return CreateAndPushResult.Exists;

					var commits = await _repoClient.GetAllCommitsAsync(orgName, repoName);
					if (commits.Count > c_numInitialCommits)
						return CreateAndPushResult.Exists;
				}
				else
				{
					repository = await _repoClient.CreateRepositoryAsync
					(
						orgName,
						repoName,
						team,
						overwrite: false
					);

					var staffTeam = GetStaffTeam(project.Classroom, teams);
					if (staffTeam != null)
					{
						await _teamClient.AddRepositoryAsync(orgName, repoName, staffTeam);
					}
				}

				await _repoClient.OverwriteRepositoryAsync
				(
					repository,
					c_starterCommitMessage,
					templateContents,
					entry => project.GetFileType(entry) != FileType.Private,
					entry => project.GetFileType(entry) == FileType.Immutable
				);

				await _repoClient.EnsurePushWebhookAsync(repository, webhookUrl);

				return repositoryAlreadyExisted
					? CreateAndPushResult.Overwritten
					: CreateAndPushResult.Created;
			}
			catch (Exception ex)
			{
				_logger.LogError
				(
					(EventId)0,
					ex,
					"Failed to create repository {RepoName} in organization {Org}.", repoName, orgName
				);

				return CreateAndPushResult.Failed;
			}
		}
Ejemplo n.º 2
0
		/// <summary>
		/// Retunrs a list of files in a project repository.
		/// </summary>
		public async Task<IList<ProjectRepositoryFile>> GetRepoFileListAsync(
			Project project)
		{
			using
			(
				var repoFiles = await _repoClient.GetRepositoryContentsAsync
				(
					project.Classroom.GitHubOrganization,
					project.TemplateRepoName,
					null /*branchName*/,
					ArchiveStore.Memory
				)
			)
			{
				return repoFiles.Files.Select
				(
					entry => new ProjectRepositoryFile
					(
						project.GetFileType(entry),
						entry.FullPath
					)
				).ToList();
			}		
		}
		/// <summary>
		/// Writes the contents of a submission to an archive.
		/// </summary>
		private async Task WriteSubmissionToArchiveAsync(
			ZipArchive archive,
			Project project,
			ClassroomMembership student,
			IArchive templateContents,
			IArchive submissionContents)
		{
			var studentFolder = $"EclipseProjects\\{student.GitHubTeam}";

			// The project will contain all non-immutable submission files, 
			// plus all immutable and private files from the template project.

			var projectContents = submissionContents.Files
				.Where
				(
					entry => project.GetFileType(entry) == FileType.Public
				)
				.Concat
				(
					templateContents.Files.Where
					(
						entry => project.GetFileType(entry) != FileType.Public
					)
				)
				.ToList();

			foreach (var entry in projectContents)
			{
				if (ExcludeEntry(project, entry))
					continue;

				var contents = _transformer.GetFileContents(project, student, entry);

				var archiveFilePath = entry.FullPath;
				var archiveFileFolder = archiveFilePath.Contains("/")
					? archiveFilePath.Substring(0, archiveFilePath.LastIndexOf("/"))
					: archiveFilePath;

				var localFileFolder = $"{studentFolder}\\{archiveFileFolder}";
				var fileName = archiveFilePath.Substring(archiveFilePath.LastIndexOf("/") + 1);
				var localFilePath = $"{localFileFolder}\\{fileName}";

				// Add the file to the student project folder.
				var projectFolderEntry = archive.CreateEntry(localFilePath);
				using (Stream stream = projectFolderEntry.Open())
				{
					await stream.WriteAsync(contents, offset: 0, count: contents.Length);
				}

				// Add the file to the folder containing all files, if applicable.
				if (fileName.EndsWith(".java") && project.GetFileType(entry) == FileType.Public)
				{
					var allFilesEntry = archive.CreateEntry($"AllFiles\\{student.GitHubTeam}-{fileName}");
					using (Stream stream = allFilesEntry.Open())
					{
						await stream.WriteAsync(contents, offset: 0, count: contents.Length);
					}
				}
			}
		}