From 7852a799fe07f3e7424ed5a289b0170e74906ac5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Spo=CC=88nemann?= Date: Wed, 8 Jun 2016 12:08:31 +0200 Subject: [PATCH] Implemented filter-branch tasks for each target repository --- splitting/build.gradle | 30 ++++++++ splitting/git-filter-branch.sh | 7 ++ splitting/parent-filter.sh | 10 +++ splitting/splitting.txt | 1 + .../eclipse/xtext/splitting/FindProjects.java | 10 +-- .../xtext/splitting/GenerateRemovals.java | 77 +++++++++++++++++++ .../xtext/splitting/ValidateSplitting.java | 11 +-- 7 files changed, 136 insertions(+), 10 deletions(-) create mode 100755 splitting/git-filter-branch.sh create mode 100755 splitting/parent-filter.sh create mode 100644 splitting/src/org/eclipse/xtext/splitting/GenerateRemovals.java diff --git a/splitting/build.gradle b/splitting/build.gradle index e930d415a..b26c63310 100644 --- a/splitting/build.gradle +++ b/splitting/build.gradle @@ -7,8 +7,11 @@ def allHistoryFiles = file(outputFilesDir + "/all-files.txt") def allProjects = file(outputFilesDir + "/all-projects.txt") def unmappedPaths = file(outputFilesDir + "/unmapped-paths.txt") def splittingFile = file("splitting.txt") +def repositories = ["core", "extras", "lib", "xtend", "eclipse", "idea", "web", "maven", "xtext-website", "xtend-website"] task listFiles(type: Exec) { + group 'Splitting Helper' + description 'Creates a list of all files that have ever been in the git history.' outputs.file allHistoryFiles workingDir '..' commandLine 'git', 'log', '--pretty=format:', '--name-only', '--diff-filter=A' @@ -19,6 +22,8 @@ task listFiles(type: Exec) { } task findProjects(type: JavaExec) { + group 'Splitting Helper' + description 'Creates a list of all projects that have ever been in the git history.' dependsOn(sourceSets.main.runtimeClasspath, listFiles) inputs.file allHistoryFiles outputs.files allProjects, unmappedPaths @@ -28,9 +33,34 @@ task findProjects(type: JavaExec) { } task validateSplitting(type: JavaExec) { + group 'Splitting Helper' + description 'Checks splitting.txt for validity.' dependsOn(sourceSets.main.runtimeClasspath, listFiles) inputs.files splittingFile, allHistoryFiles classpath = sourceSets.main.runtimeClasspath.filter{it.exists()} main = "org.eclipse.xtext.splitting.ValidateSplitting" args splittingFile, outputFilesDir } + +task generateRemovals(type: JavaExec) { + group 'Splitting Helper' + description 'Generates a list of files to remove for each repository.' + dependsOn(sourceSets.main.runtimeClasspath, validateSplitting) + inputs.files splittingFile + outputs.files repositories.collect{ file("$outputFilesDir/removals-${it}.txt") } + classpath = sourceSets.main.runtimeClasspath.filter{it.exists()} + main = "org.eclipse.xtext.splitting.GenerateRemovals" + args splittingFile, outputFilesDir +} + +repositories.each { targetRepo -> + def removalsFile = file("$outputFilesDir/removals-${targetRepo}.txt") + task "${targetRepo}FilterBranch"(type: Exec) { + group 'Git History Manipulation' + description "Filters the git history for the target repository ${targetRepo}." + dependsOn(generateRemovals) + inputs.file removalsFile + workingDir '..' + commandLine 'splitting/git-filter-branch.sh', removalsFile.path + } +} diff --git a/splitting/git-filter-branch.sh b/splitting/git-filter-branch.sh new file mode 100755 index 000000000..b81fd229e --- /dev/null +++ b/splitting/git-filter-branch.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +REMOVALS=`cat $1 | tr '\n' ' '` +git filter-branch -f --prune-empty \ + --index-filter "git rm -qrf --cached --ignore-unmatch $REMOVALS" \ + --parent-filter splitting/parent-filter.sh \ + HEAD diff --git a/splitting/parent-filter.sh b/splitting/parent-filter.sh new file mode 100755 index 000000000..64f90fa28 --- /dev/null +++ b/splitting/parent-filter.sh @@ -0,0 +1,10 @@ +#!/bin/bash +read INPUT +if [ -n "$INPUT" ] +then + SHOW_BRANCH=`git show-branch --independent ${INPUT//-p/}` + for PARENT in $SHOW_BRANCH + do + echo -n "-p $PARENT " + done +fi diff --git a/splitting/splitting.txt b/splitting/splitting.txt index 8b45a6d0c..87269e6b4 100644 --- a/splitting/splitting.txt +++ b/splitting/splitting.txt @@ -247,6 +247,7 @@ plugins/org.eclipse.emf.index >> delete plugins/org.eclipse.emf.index.ui >> delete plugins/org.eclipse.xtext.doc.manual >> delete settings.gradle >> delete +splitting >> delete test.txt >> delete tests/.settings >> delete tests/build.gradle >> delete diff --git a/splitting/src/org/eclipse/xtext/splitting/FindProjects.java b/splitting/src/org/eclipse/xtext/splitting/FindProjects.java index 571f7eff9..e685c5fe7 100644 --- a/splitting/src/org/eclipse/xtext/splitting/FindProjects.java +++ b/splitting/src/org/eclipse/xtext/splitting/FindProjects.java @@ -26,12 +26,12 @@ public class FindProjects { public static void main(String[] args) { if (args.length != 1) { - fail("Expected path to working directory as argument."); + fail("Expected path to output files as argument."); } - String workingDir = args[0]; + String outputDir = args[0]; try { final Directory root = new Directory(".", null); - try (BufferedReader reader = new BufferedReader(new FileReader(workingDir + "/" + ALL_FILES))) { + try (BufferedReader reader = new BufferedReader(new FileReader(outputDir + "/" + ALL_FILES))) { // Gather all paths in a directory structure String line; while ((line = reader.readLine()) != null) { @@ -64,7 +64,7 @@ public class FindProjects { // Write the collected projects into a file Collections.sort(projects); - try (FileWriter writer = new FileWriter(workingDir + "/" + ALL_PROJECTS)) { + try (FileWriter writer = new FileWriter(outputDir + "/" + ALL_PROJECTS)) { for (Directory project : projects) { writer.write(project.toString()); writer.write('\n'); @@ -73,7 +73,7 @@ public class FindProjects { // Write the unmapped paths into another file Collections.sort(otherPaths); - try (FileWriter writer = new FileWriter(workingDir + "/" + UNMAPPED_PATHS)) { + try (FileWriter writer = new FileWriter(outputDir + "/" + UNMAPPED_PATHS)) { for (DirectoryEntry path : otherPaths) { writer.write(path.toString()); writer.write('\n'); diff --git a/splitting/src/org/eclipse/xtext/splitting/GenerateRemovals.java b/splitting/src/org/eclipse/xtext/splitting/GenerateRemovals.java new file mode 100644 index 000000000..1b6c7267a --- /dev/null +++ b/splitting/src/org/eclipse/xtext/splitting/GenerateRemovals.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (c) 2016 TypeFox GmbH (http://www.typefox.io) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ +package org.eclipse.xtext.splitting; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.FileWriter; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class GenerateRemovals { + + public static void main(String[] args) { + if (args.length != 2) { + fail("Expected paths to splitting.txt and output files as arguments."); + } + String outputDir = args[1]; + try { + final Map> removalPaths = new HashMap<>(); + for (String targetRepo : ValidateSplitting.REPOSITORIES) { + removalPaths.put(targetRepo, new ArrayList<>()); + } + + // Gather paths to be removed from the history for each target repository + try (BufferedReader reader = new BufferedReader(new FileReader(args[0]))) { + String line; + while ((line = reader.readLine()) != null) { + if (!line.isEmpty()) { + String[] parts = line.split(">>"); + String[] repos = parts[1].split(","); + for (String targetRepo : ValidateSplitting.REPOSITORIES) { + boolean isInTargetRepo = false; + for (String repo : repos) { + if (targetRepo.equals(repo.trim())) { + isInTargetRepo = true; + break; + } + } + if (!isInTargetRepo) { + String path = parts[0].trim(); + removalPaths.get(targetRepo).add(path); + } + } + } + } + } + + // Write a removal list for each target repository + for (String targetRepo : ValidateSplitting.REPOSITORIES) { + try (FileWriter writer = new FileWriter(outputDir + "/removals-" + targetRepo + ".txt")) { + for (String path : removalPaths.get(targetRepo)) { + writer.write(path); + writer.write('\n'); + } + } + } + + } catch (Exception e) { + e.printStackTrace(); + System.exit(1); + } + } + + private static void fail(String message) { + System.err.print("ERROR: "); + System.err.println(message); + System.exit(1); + } + +} diff --git a/splitting/src/org/eclipse/xtext/splitting/ValidateSplitting.java b/splitting/src/org/eclipse/xtext/splitting/ValidateSplitting.java index 32bb5a242..2bddacc9b 100644 --- a/splitting/src/org/eclipse/xtext/splitting/ValidateSplitting.java +++ b/splitting/src/org/eclipse/xtext/splitting/ValidateSplitting.java @@ -12,23 +12,24 @@ import java.io.FileReader; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; public class ValidateSplitting { - public static final Set REPOSITORIES = Collections.unmodifiableSet(new HashSet<>(Arrays.asList( - "core", "extras", "lib", "xtend", "eclipse", "idea", "web", "maven", "xtext-website", "xtend-website" + public static final Set REPOSITORIES = Collections.unmodifiableSet(new LinkedHashSet<>(Arrays.asList( + "core", "extras", "lib", "xtend", "eclipse", "idea", "web", "maven", "xtext-website", "xtend-website" ))); public static final String DELETE = "delete"; public static void main(String[] args) { if (args.length != 2) { - fail("Expected paths to splitting.txt and working directory as arguments."); + fail("Expected paths to splitting.txt and output files as arguments."); } - String workingDir = args[1]; + String outputDir = args[1]; try { // Validate repositories and gather all paths from the splitting file @@ -59,7 +60,7 @@ public class ValidateSplitting { // Check whether each file has a specified path as prefix final Pattern segmentPattern = Pattern.compile("/"); - try (BufferedReader reader = new BufferedReader(new FileReader(workingDir + "/" + FindProjects.ALL_FILES))) { + try (BufferedReader reader = new BufferedReader(new FileReader(outputDir + "/" + FindProjects.ALL_FILES))) { String line; while ((line = reader.readLine()) != null) { if (!line.isEmpty()) {