From 08d84e4784949fb5aadf415081b519082205936f Mon Sep 17 00:00:00 2001 From: Chris Cosby Date: Wed, 19 Dec 2012 15:33:36 -0500 Subject: [PATCH 1/3] Add scm version 3.1.0 version test --- .../plugins/rtc/commands/VersionCommandTest.java | 9 +++++++-- .../jenkins/plugins/rtc/commands/scm-version-3.1.0.txt | 10 ++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 src/test/resources/com/deluan/jenkins/plugins/rtc/commands/scm-version-3.1.0.txt diff --git a/src/test/java/com/deluan/jenkins/plugins/rtc/commands/VersionCommandTest.java b/src/test/java/com/deluan/jenkins/plugins/rtc/commands/VersionCommandTest.java index 1749c07..a7e9b03 100644 --- a/src/test/java/com/deluan/jenkins/plugins/rtc/commands/VersionCommandTest.java +++ b/src/test/java/com/deluan/jenkins/plugins/rtc/commands/VersionCommandTest.java @@ -19,6 +19,13 @@ public void versionCommandArguments() throws Exception { assertThat(cmd.getArguments().toStringWithQuote(), is("version")); } + @Test + public void versionCommandParse_3_1_0() throws Exception { + BufferedReader reader = getReader("scm-version-3.1.0.txt"); + String result = cmd.parse(reader); + assertThat(result, is("3.1.0")); + } + @Test public void versionCommandParse_2_1_0() throws Exception { BufferedReader reader = getReader("scm-version-2.1.0.txt"); @@ -40,6 +47,4 @@ public void parse() throws Exception { assertThat(result, is("3.1.100")); } - - } diff --git a/src/test/resources/com/deluan/jenkins/plugins/rtc/commands/scm-version-3.1.0.txt b/src/test/resources/com/deluan/jenkins/plugins/rtc/commands/scm-version-3.1.0.txt new file mode 100644 index 0000000..80a7ba6 --- /dev/null +++ b/src/test/resources/com/deluan/jenkins/plugins/rtc/commands/scm-version-3.1.0.txt @@ -0,0 +1,10 @@ +Build Id: RTC-I20120612-0919 + +com.ibm.team.filesystem.cli.core, version 3.1.0.v20120519_2357 + Subcommands: help version daemon daemon/start daemon/stop daemon/deregister daemon/register + +com.ibm.team.filesystem.cli.client, version 3.1.0.v20120519_2357 + Subcommands: load login logout create create/workspace create/baseline create/changeset create/snapshot create/component create/loadrules create/stream changeset changeset/comment changeset/complete changeset/current changeset/relocate changeset/associate changeset/disassociate changeset/suspend changeset/resume changeset/discard changeset/extract changeset/locate change-target change-target/workspace change-target/component change-target/unset-workspace list list/workspaces list/projectareas list/teamareas list/streams list/components list/remotefiles list/credentials list/daemons list/snapshots list/locks list/properties list/changes list/users list/baselines list/changesets list/states checkin accept deliver status conflicts resolve move lastmod share discard undo compare history diff repair workspace workspace/change-target workspace/component workspace/unset workspace/add-components workspace/remove-components workspace/replace-components workspace/delete workspace/unload property property/list property/get property/set property/remove lock lock/list lock/acquire lock/release annotate snapshot snapshot/promote refresh users users/set delete delete/state-content changeaccess extract extract/file + +com.ibm.team.filesystem.cli.tools, version 3.1.0.v20120510_0526 + Subcommands: tools.verify tools.validate tools.echo.stdin tools.metronome tools.pkgtest tools.configvalue tools.log From 8658d03df15bfd426ddf2f20144cd7f7cb0b07b0 Mon Sep 17 00:00:00 2001 From: Chris Cosby Date: Thu, 20 Dec 2012 15:13:58 -0500 Subject: [PATCH 2/3] Add ability to parse scm 3.1.0 accept output Patched on 0.3 release versioned 0.3.1-SNAPSHOT Also updated name of some variables to more accurately reflect their scm version requirement. Added initial research on parsing JSON output of 3.1.0 commands, but ran out of time. Included the output txt file if anyone has time to hack it in. --- .../plugins/rtc/commands/AcceptCommand.java | 13 +- .../accept/AcceptOutputParser_3_1_0.java | 24 ++ .../accept/JsonAcceptOutputParser.java | 131 ++++++++ .../rtc/commands/AcceptCommandTest.java | 48 ++- .../plugins/rtc/commands/BaseCommandTest.java | 3 +- .../plugins/rtc/commands/CommandTest.java | 6 +- .../rtc/commands/CompareCommandTest.java | 2 +- .../plugins/rtc/commands/scm-accept-3.1.0.txt | 41 +++ .../rtc/commands/scm-accept-json-3.1.0.txt | 317 ++++++++++++++++++ 9 files changed, 566 insertions(+), 19 deletions(-) create mode 100644 src/main/java/com/deluan/jenkins/plugins/rtc/commands/accept/AcceptOutputParser_3_1_0.java create mode 100644 src/main/java/com/deluan/jenkins/plugins/rtc/commands/accept/JsonAcceptOutputParser.java create mode 100644 src/test/resources/com/deluan/jenkins/plugins/rtc/commands/scm-accept-3.1.0.txt create mode 100644 src/test/resources/com/deluan/jenkins/plugins/rtc/commands/scm-accept-json-3.1.0.txt diff --git a/src/main/java/com/deluan/jenkins/plugins/rtc/commands/AcceptCommand.java b/src/main/java/com/deluan/jenkins/plugins/rtc/commands/AcceptCommand.java index 60c1c78..e4cf21a 100644 --- a/src/main/java/com/deluan/jenkins/plugins/rtc/commands/AcceptCommand.java +++ b/src/main/java/com/deluan/jenkins/plugins/rtc/commands/AcceptCommand.java @@ -2,6 +2,7 @@ import com.deluan.jenkins.plugins.rtc.JazzConfiguration; import com.deluan.jenkins.plugins.rtc.changelog.JazzChangeSet; +import com.deluan.jenkins.plugins.rtc.commands.accept.AcceptOutputParser_3_1_0; import com.deluan.jenkins.plugins.rtc.commands.accept.AcceptNewOutputParser; import com.deluan.jenkins.plugins.rtc.commands.accept.AcceptOldOutputParser; import com.deluan.jenkins.plugins.rtc.commands.accept.BaseAcceptOutputParser; @@ -19,7 +20,8 @@ */ public class AcceptCommand extends AbstractCommand implements ParseableCommand> { - public static final String NEW_FORMAT_VERSION = "2.1.0"; + public static final String FORMAT_VERSION_2_1_0 = "2.1.0"; + public static final String FORMAT_VERSION_3_1_0 = "3.1.0"; private Collection changeSets; private BaseAcceptOutputParser parser; protected boolean oldFormat = false; @@ -27,8 +29,13 @@ public class AcceptCommand extends AbstractCommand implements ParseableCommand changeSets, String version) { super(configurationProvider); this.changeSets = new LinkedHashSet(changeSets); - this.oldFormat = (version.compareTo(NEW_FORMAT_VERSION) < 0); - parser = (oldFormat) ? new AcceptOldOutputParser() : new AcceptNewOutputParser(); + + if (version.compareTo(FORMAT_VERSION_3_1_0) >= 0) { + parser = new AcceptOutputParser_3_1_0(); + } else { + this.oldFormat = (version.compareTo(FORMAT_VERSION_2_1_0) < 0); + parser = (oldFormat) ? new AcceptOldOutputParser() : new AcceptNewOutputParser(); + } } public ArgumentListBuilder getArguments() { diff --git a/src/main/java/com/deluan/jenkins/plugins/rtc/commands/accept/AcceptOutputParser_3_1_0.java b/src/main/java/com/deluan/jenkins/plugins/rtc/commands/accept/AcceptOutputParser_3_1_0.java new file mode 100644 index 0000000..e9eaf24 --- /dev/null +++ b/src/main/java/com/deluan/jenkins/plugins/rtc/commands/accept/AcceptOutputParser_3_1_0.java @@ -0,0 +1,24 @@ +package com.deluan.jenkins.plugins.rtc.commands.accept; + +/** + * @author: Chris Cosby + */ + +public class AcceptOutputParser_3_1_0 extends BaseAcceptOutputParser { + + public AcceptOutputParser_3_1_0() { + super("^\\s{6}[^\\d\\s]+(\\d+)[^\\d]+\\s(.*)$", + "^\\s{10}(.{5})\\s+(.*)$", + "^\\s{10}[^\\d\\s]+(\\d+)[^\\d]+(.*)$"); + } + + @Override + protected String parseWorkItem(String string) { + return string; + } + + @Override + protected String parseEditFlag(String string) { + return string.substring(2, 3); + } +} diff --git a/src/main/java/com/deluan/jenkins/plugins/rtc/commands/accept/JsonAcceptOutputParser.java b/src/main/java/com/deluan/jenkins/plugins/rtc/commands/accept/JsonAcceptOutputParser.java new file mode 100644 index 0000000..d95a4db --- /dev/null +++ b/src/main/java/com/deluan/jenkins/plugins/rtc/commands/accept/JsonAcceptOutputParser.java @@ -0,0 +1,131 @@ +package com.deluan.jenkins.plugins.rtc.commands.accept; + +import com.deluan.jenkins.plugins.rtc.changelog.JazzChangeSet; +import hudson.scm.EditType; +import net.sf.json.JSONArray; +import net.sf.json.JSONObject; + +import java.io.BufferedReader; +import java.io.IOException; +import java.text.ParseException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @author Chris Cosby + */ + +abstract public class JsonAcceptOutputParser { + protected JsonAcceptOutputParser() { + } + + /* + * The intention here is to parse JSON output of 'scm accept' but I'm out of time. + */ + protected void doSomething(BufferedReader reader) { + String line; + StringBuilder json = new StringBuilder(); + try { + while ((line = reader.readLine()) != null) { + json.append(line); + } + } catch (IOException e) { + e.printStackTrace(); + } + + // And this is parsing the output of the compare command, not accept + JSONObject jazzCompareObj = JSONObject.fromObject(json.toString()); + JSONArray jazzDirections = jazzCompareObj.getJSONArray("direction"); + for ( + Iterator jazzCompareIter = jazzDirections.iterator(); + jazzCompareIter.hasNext(); ) + + { + JSONObject direction = jazzCompareIter.next(); + JSONArray components = direction.getJSONArray("components"); + boolean incomingChanges = direction.getBoolean("incoming-changes"); + boolean outgoingChanges = direction.getBoolean("outgoing-changes"); + + if (!incomingChanges) continue; + + for (Iterator jazzComponentIter = components.iterator(); jazzComponentIter.hasNext(); ) { + JSONObject component = jazzComponentIter.next(); + System.out.println("uuid: " + component.getString("uuid")); + JSONArray changesets = component.getJSONArray("changesets"); + + for (Iterator jazzChangesetIter = changesets.iterator(); jazzChangesetIter.hasNext(); ) { + JSONObject changeset = jazzChangesetIter.next(); + } + } + } + } + + + protected Pattern startChangesetPattern; + protected Pattern filePattern; + protected Pattern workItemPattern; + + public JsonAcceptOutputParser(String startChangesetPattern, String filePattern, String workItemPattern) { + this.workItemPattern = Pattern.compile(workItemPattern); + this.startChangesetPattern = Pattern.compile(startChangesetPattern); + this.filePattern = Pattern.compile(filePattern); + } + + public Map parse(BufferedReader reader) throws ParseException, IOException { + Map result = new HashMap(); + + String line; + JazzChangeSet changeSet = null; + Matcher matcher; + + while ((line = reader.readLine()) != null) { + if ((matcher = startChangesetPattern.matcher(line)).matches()) { + if (changeSet != null) { + result.put(changeSet.getRev(), changeSet); + } + changeSet = new JazzChangeSet(); + changeSet.setRev(matcher.group(1)); + } else if ((matcher = filePattern.matcher(line)).matches()) { + assert changeSet != null; + String action = parseAction(matcher.group(1)); + String path = parsePath(matcher.group(2)); + changeSet.addItem(path, action); + } else if ((matcher = workItemPattern.matcher(line)).matches()) { + assert changeSet != null; + changeSet.addWorkItem(parseWorkItem(matcher.group(2))); + } + } + + if (changeSet != null) { + result.put(changeSet.getRev(), changeSet); + } + + return result; + } + + abstract protected String parseWorkItem(String string); + + abstract protected String parseEditFlag(String string); + + protected String parsePath(String string) { + String path = string.replaceAll("\\\\", "/").trim(); + if (path.startsWith("/")) { + path = path.substring(1); + } + return path; + } + + protected String parseAction(String string) { + String flag = parseEditFlag(string); + String action = EditType.EDIT.getName(); + if ("a".equals(flag)) { + action = EditType.ADD.getName(); + } else if ("d".equals(flag)) { + action = EditType.DELETE.getName(); + } + return action; + } +} diff --git a/src/test/java/com/deluan/jenkins/plugins/rtc/commands/AcceptCommandTest.java b/src/test/java/com/deluan/jenkins/plugins/rtc/commands/AcceptCommandTest.java index b429a25..69ed64d 100644 --- a/src/test/java/com/deluan/jenkins/plugins/rtc/commands/AcceptCommandTest.java +++ b/src/test/java/com/deluan/jenkins/plugins/rtc/commands/AcceptCommandTest.java @@ -15,37 +15,63 @@ public class AcceptCommandTest extends BaseCommandTest { @Test public void acceptCommandArguments() throws Exception { - AcceptCommand cmd = new AcceptCommand(config, Arrays.asList(TEST_REVISIONS), "2.1.0"); + AcceptCommand cmd = new AcceptCommand(config, Arrays.asList(TEST_REVISIONS_2_1_0), "2.1.0"); assertEquals("accept -u user -P password -d c:\\test -s \"My Stream\" --flow-components -o -v -c 1714 1657 1652 1651 1650 1648 1645 1640 1625", cmd.getArguments().toStringWithQuote()); } @Test public void createCommandForVersion_2_0_2() throws Exception { - AcceptCommand cmd = new AcceptCommand(config, Arrays.asList(TEST_REVISIONS), "2.0.2"); + AcceptCommand cmd = new AcceptCommand(config, Arrays.asList(TEST_REVISIONS_2_1_0), "2.0.2"); assertThat(cmd.oldFormat, is(true)); } @Test public void createCommandForVersion_2_1_0() throws Exception { - AcceptCommand cmd = new AcceptCommand(config, Arrays.asList(TEST_REVISIONS), "2.1.0"); + AcceptCommand cmd = new AcceptCommand(config, Arrays.asList(TEST_REVISIONS_2_1_0), "2.1.0"); assertThat(cmd.oldFormat, is(false)); } @Test public void createCommandForVersion_3_0_0() throws Exception { - AcceptCommand cmd = new AcceptCommand(config, Arrays.asList(TEST_REVISIONS), "3.0.0"); + AcceptCommand cmd = new AcceptCommand(config, Arrays.asList(TEST_REVISIONS_2_1_0), "3.0.0"); assertThat(cmd.oldFormat, is(false)); } + @Test + public void acceptCommandParse_3_1_0() throws Exception { + AcceptCommand cmd = new AcceptCommand(config, Arrays.asList(TEST_REVISIONS_3_1_0), "3.1.0"); + Map result = callParser(cmd, "scm-accept-3.1.0.txt", TEST_REVISIONS_3_1_0); + + JazzChangeSet changeSet = result.get("1008"); + assertEquals("The number of files in the changesets was incorrect", 6, changeSet.getAffectedPaths().size()); + assertEquals("The number of work items in the changesets was incorrect", 2, changeSet.getWorkItems().size()); + + JazzChangeSet.Item item = changeSet.getItems().get(3); + assertTrue("The file is not the expected one", item.getPath().endsWith(".jazzignore")); + assertEquals("The edit type is not the expected one", EditType.ADD, item.getEditType()); + + + changeSet = result.get("1010"); + item = changeSet.getItems().get(0); + assertTrue("The file is not the expected one", item.getPath().endsWith("MyThingAPI.C")); + assertEquals("The edit type is not the expected one", EditType.EDIT, item.getEditType()); + + + changeSet = result.get("1009"); + item = changeSet.getItems().get(0); + assertTrue("The file is not the expected one", item.getPath().endsWith(".jazzignore")); + assertEquals("The edit type is not the expected one", EditType.DELETE, item.getEditType()); + } + @Test public void acceptCommandParse_2_1_0() throws Exception { - AcceptCommand cmd = new AcceptCommand(config, Arrays.asList(TEST_REVISIONS), "2.1.0"); - Map result = callParser(cmd, "scm-accept-2.1.0.txt", TEST_REVISIONS); + AcceptCommand cmd = new AcceptCommand(config, Arrays.asList(TEST_REVISIONS_2_1_0), "2.1.0"); + Map result = callParser(cmd, "scm-accept-2.1.0.txt", TEST_REVISIONS_2_1_0); JazzChangeSet changeSet = result.get("1714"); assertEquals("The number of files in the changesets was incorrect", 8, changeSet.getAffectedPaths().size()); - assertEquals("The number of work itens in the changesets was incorrect", 2, changeSet.getWorkItems().size()); + assertEquals("The number of work items in the changesets was incorrect", 2, changeSet.getWorkItems().size()); JazzChangeSet.Item item = changeSet.getItems().get(0); assertTrue("The file is not the expected one", item.getPath().endsWith("GerenteOferta.java")); @@ -61,12 +87,12 @@ public void acceptCommandParse_2_1_0() throws Exception { @Test public void acceptCommandParse_Chinese() throws Exception { - AcceptCommand cmd = new AcceptCommand(config, Arrays.asList(TEST_REVISIONS), "2.0.2"); + AcceptCommand cmd = new AcceptCommand(config, Arrays.asList(TEST_REVISIONS_2_1_0), "2.0.2"); Map result = callParser(cmd, "scm-accept-chinese.txt", "1019", "1021", "1020"); JazzChangeSet changeSet = result.get("1020"); assertEquals("The number of files in the changesets was incorrect", 2, changeSet.getAffectedPaths().size()); - assertEquals("The number of work itens in the changesets was incorrect", 1, changeSet.getWorkItems().size()); + assertEquals("The number of work items in the changesets was incorrect", 1, changeSet.getWorkItems().size()); JazzChangeSet.Item item = changeSet.getItems().get(0); assertTrue("The file is not the expected one", item.getPath().endsWith("com_tps_eppic_ConfigValues_core_properties")); @@ -78,12 +104,12 @@ public void acceptCommandParse_Chinese() throws Exception { @Test public void acceptCommandParse_2_0_2() throws Exception { - AcceptCommand cmd = new AcceptCommand(config, Arrays.asList(TEST_REVISIONS), "2.0.2"); + AcceptCommand cmd = new AcceptCommand(config, Arrays.asList(TEST_REVISIONS_2_1_0), "2.0.2"); Map result = callParser(cmd, "scm-accept-2.0.2.txt", "1002", "1001", "1008", "1009"); JazzChangeSet changeSet = result.get("1002"); assertEquals("The number of files in the changesets was incorrect", 5, changeSet.getAffectedPaths().size()); - assertEquals("The number of work itens in the changesets was incorrect", 1, changeSet.getWorkItems().size()); + assertEquals("The number of work items in the changesets was incorrect", 1, changeSet.getWorkItems().size()); JazzChangeSet.Item item = changeSet.getItems().get(3); assertTrue("The file is not the expected one", item.getPath().endsWith("FabricaEJBBean.java")); diff --git a/src/test/java/com/deluan/jenkins/plugins/rtc/commands/BaseCommandTest.java b/src/test/java/com/deluan/jenkins/plugins/rtc/commands/BaseCommandTest.java index 2b7f86e..38d3ea8 100644 --- a/src/test/java/com/deluan/jenkins/plugins/rtc/commands/BaseCommandTest.java +++ b/src/test/java/com/deluan/jenkins/plugins/rtc/commands/BaseCommandTest.java @@ -17,7 +17,8 @@ */ abstract public class BaseCommandTest { - protected static final String[] TEST_REVISIONS = new String[]{"1714", "1657", "1652", "1651", "1650", "1648", "1645", "1640", "1625"}; + protected static final String[] TEST_REVISIONS_2_1_0 = new String[]{"1714", "1657", "1652", "1651", "1650", "1648", "1645", "1640", "1625"}; + protected static final String[] TEST_REVISIONS_3_1_0 = new String[]{"1010", "1009", "1007", "1008", "1006", "1004"}; protected JazzConfiguration config; @Before diff --git a/src/test/java/com/deluan/jenkins/plugins/rtc/commands/CommandTest.java b/src/test/java/com/deluan/jenkins/plugins/rtc/commands/CommandTest.java index a7a1a8b..2c3852a 100644 --- a/src/test/java/com/deluan/jenkins/plugins/rtc/commands/CommandTest.java +++ b/src/test/java/com/deluan/jenkins/plugins/rtc/commands/CommandTest.java @@ -38,15 +38,15 @@ public void stopDaemonCommandArguments() throws Exception { @Test public void listCommandArguments() throws Exception { - ListCommand cmd = new ListCommand(config, Arrays.asList(TEST_REVISIONS)); + ListCommand cmd = new ListCommand(config, Arrays.asList(TEST_REVISIONS_2_1_0)); assertEquals("list changesets -u user -P password -d c:\\test 1714 1657 1652 1651 1650 1648 1645 1640 1625", cmd.getArguments().toStringWithQuote()); } @Test public void listCommandParse() throws Exception { - ListCommand cmd = new ListCommand(config, Arrays.asList(TEST_REVISIONS)); - Map result = callParser(cmd, "scm-list.txt", TEST_REVISIONS); + ListCommand cmd = new ListCommand(config, Arrays.asList(TEST_REVISIONS_2_1_0)); + Map result = callParser(cmd, "scm-list.txt", TEST_REVISIONS_2_1_0); JazzChangeSet changeSet = result.get("1714"); assertEquals("The number of files in the changesets was incorrect", 8, changeSet.getAffectedPaths().size()); diff --git a/src/test/java/com/deluan/jenkins/plugins/rtc/commands/CompareCommandTest.java b/src/test/java/com/deluan/jenkins/plugins/rtc/commands/CompareCommandTest.java index 5df28a3..6fd07c2 100644 --- a/src/test/java/com/deluan/jenkins/plugins/rtc/commands/CompareCommandTest.java +++ b/src/test/java/com/deluan/jenkins/plugins/rtc/commands/CompareCommandTest.java @@ -18,7 +18,7 @@ public void compareCommandArguments() throws Exception { @Test public void compareCommandParse() throws Exception { - Map result = callParser(new CompareCommand(config), "scm-compare.txt", TEST_REVISIONS); + Map result = callParser(new CompareCommand(config), "scm-compare.txt", TEST_REVISIONS_2_1_0); JazzChangeSet changeSet = result.get("1657"); assertEquals("Roberto", changeSet.getUser()); diff --git a/src/test/resources/com/deluan/jenkins/plugins/rtc/commands/scm-accept-3.1.0.txt b/src/test/resources/com/deluan/jenkins/plugins/rtc/commands/scm-accept-3.1.0.txt new file mode 100644 index 0000000..217bb20 --- /dev/null +++ b/src/test/resources/com/deluan/jenkins/plugins/rtc/commands/scm-accept-3.1.0.txt @@ -0,0 +1,41 @@ +Repository: https://my-rtc.company.com:9443/path/ +Workspace: (1015) "thing-1.0-shared" + Component: (1000) "thing" + Change sets: + (1010) ---$ Boy Developer "fix Thinger to match new requirement" 12-Dec-2012 03:06 PM + Changes: + ---c- /thing/src/lib/MyThingAPI.C + Work items: + (1005) 8112 "Fix the thing" + (1009) ---$ Boy Developer "Girl removed the .jazzignore from conversion as no longer needed and we decided to just pick up the .project for future use" 12-Dec-2012 03:33 PM + Changes: + --d-- /thing/.jazzignore + --a-- /thing/.project + Work items: + (1005) 8112 "Fix the thing" + (1007) ---$ "Update Makefile to use $(MAKE) instead of make" 14-Dec-2012 04:48 PM + Changes: + ---c- /thing/Makefile + Work items: + (1005) 8112 "Fix the thing" + (1008) ---$ Girl Developer "omit bin directories for those without bin in platform preferences" 13-Dec-2012 10:19 AM + Changes: + --a-- /thing/.jazzignore + --a-- /thing/src/cfg/.jazzignore + --a-- /thing/src/lib/.jazzignore + --a-- /thing/src/MDS/.jazzignore + --a-- /thing/src/PIDS/.jazzignore + --a-- /thing/src/SVC/.jazzignore + Work items: + (1004) 8111 "A dummy workitem for 3.1.0 test case" + (1005) 8112 "Fix the thing" + (1006) ---$ "Remove CM Synergy .ccmwaid.inf" 14-Dec-2012 05:10 PM + Changes: + --d-- /thing/.ccmwaid.inf + Work items: + (1005) 8112 "Fix the thing" + (1004) ---$ "Add simple build.xml for testing RTC / Jenkins integration" 17-Dec-2012 05:36 PM + Changes: + --a-- /thing/build.xml + Work items: + (1005) 8112 "Fix the thing" diff --git a/src/test/resources/com/deluan/jenkins/plugins/rtc/commands/scm-accept-json-3.1.0.txt b/src/test/resources/com/deluan/jenkins/plugins/rtc/commands/scm-accept-json-3.1.0.txt new file mode 100644 index 0000000..50e5444 --- /dev/null +++ b/src/test/resources/com/deluan/jenkins/plugins/rtc/commands/scm-accept-json-3.1.0.txt @@ -0,0 +1,317 @@ +{ + "repos": [ + { + "repo-url": "https:\/\/my-rtc.company.com:9443\/path\/", + "workspaces": [ + { + "components": [ + { + "changes": [ + { + "author": "Boy Developer", + "changes": [ + { + "inaccessible-change": false, + "path": "\/thing\/src\/lib\/MyThingAPI.C", + "state": { + "add": false, + "conflict": false, + "content_change": true, + "delete": false, + "move": false, + "potential_conflict": false, + "property_change": false + } + } + ], + "comment": "fix Thinger to match new requirement", + "modified": "12-Dec-2012 03:06 PM", + "state": { + "active": false, + "complete": true, + "conflict": false, + "current": false, + "potential_conflict": false + }, + "url": "https:\/\/my-rtc.company.com:9443\/path\/", + "uuid": "_etjOekOlEeKJEZt6NdfIqg", + "workitems": [ + { + "id": 8112, + "uuid": "_PTlXoEOhEeKdbuKS2aCWjw", + "workitem-label": "Fix the thing" + } + ] + }, + { + "author": "Boy Developer", + "changes": [ + { + "inaccessible-change": false, + "path": "\/thing\/.jazzignore", + "state": { + "add": false, + "conflict": false, + "content_change": false, + "delete": true, + "move": false, + "potential_conflict": false, + "property_change": false + } + }, + { + "inaccessible-change": false, + "path": "\/thing\/.project", + "state": { + "add": true, + "conflict": false, + "content_change": false, + "delete": false, + "move": false, + "potential_conflict": false, + "property_change": false + } + } + ], + "comment": "Girl removed the .jazzignore from conversion as no longer needed and we decided to just pick up the .project for future use", + "modified": "12-Dec-2012 03:33 PM", + "state": { + "active": false, + "complete": true, + "conflict": false, + "current": false, + "potential_conflict": false + }, + "url": "https:\/\/my-rtc.company.com:9443\/path\/", + "uuid": "_K4DX40SbEeKJFZt6NdfIqg", + "workitems": [ + { + "id": 8112, + "uuid": "_PTlXoEOhEeKdbuKS2aCWjw", + "workitem-label": "Fix the thing" + } + ] + }, + { + "author": "", + "changes": [ + { + "inaccessible-change": false, + "path": "\/thing\/Makefile", + "state": { + "add": false, + "conflict": false, + "content_change": true, + "delete": false, + "move": false, + "potential_conflict": false, + "property_change": false + } + } + ], + "comment": "Update Makefile to use $(MAKE) instead of make", + "modified": "14-Dec-2012 04:48 PM", + "state": { + "active": false, + "complete": true, + "conflict": false, + "current": false, + "potential_conflict": false + }, + "url": "https:\/\/my-rtc.company.com:9443\/path\/", + "uuid": "_r_6ZYUY3EeKJIJt6NdfIqg", + "workitems": [ + { + "id": 8112, + "uuid": "_PTlXoEOhEeKdbuKS2aCWjw", + "workitem-label": "Fix the thing" + } + ] + }, + { + "author": "Girl Developer", + "changes": [ + { + "inaccessible-change": false, + "path": "\/thing\/.jazzignore", + "state": { + "add": true, + "conflict": false, + "content_change": false, + "delete": false, + "move": false, + "potential_conflict": false, + "property_change": false + } + }, + { + "inaccessible-change": false, + "path": "\/thing\/src\/cfg\/.jazzignore", + "state": { + "add": true, + "conflict": false, + "content_change": false, + "delete": false, + "move": false, + "potential_conflict": false, + "property_change": false + } + }, + { + "inaccessible-change": false, + "path": "\/thing\/src\/lib\/.jazzignore", + "state": { + "add": true, + "conflict": false, + "content_change": false, + "delete": false, + "move": false, + "potential_conflict": false, + "property_change": false + } + }, + { + "inaccessible-change": false, + "path": "\/thing\/src\/MDS\/.jazzignore", + "state": { + "add": true, + "conflict": false, + "content_change": false, + "delete": false, + "move": false, + "potential_conflict": false, + "property_change": false + } + }, + { + "inaccessible-change": false, + "path": "\/thing\/src\/PIDS\/.jazzignore", + "state": { + "add": true, + "conflict": false, + "content_change": false, + "delete": false, + "move": false, + "potential_conflict": false, + "property_change": false + } + }, + { + "inaccessible-change": false, + "path": "\/thing\/src\/SVC\/.jazzignore", + "state": { + "add": true, + "conflict": false, + "content_change": false, + "delete": false, + "move": false, + "potential_conflict": false, + "property_change": false + } + } + ], + "comment": "omit bin directories for those without bin in platform preferences", + "modified": "13-Dec-2012 10:19 AM", + "state": { + "active": false, + "complete": true, + "conflict": false, + "current": false, + "potential_conflict": false + }, + "url": "https:\/\/my-rtc.company.com:9443\/path\/", + "uuid": "_d2oMcUU4EeKJGJt6NdfIqg", + "workitems": [ + { + "id": 8112, + "uuid": "_PTlXoEOhEeKdbuKS2aCWjw", + "workitem-label": "Fix the thing" + } + ] + }, + { + "author": "", + "changes": [ + { + "inaccessible-change": false, + "path": "\/thing\/.ccmwaid.inf", + "state": { + "add": false, + "conflict": false, + "content_change": false, + "delete": true, + "move": false, + "potential_conflict": false, + "property_change": false + } + } + ], + "comment": "Remove CM Synergy .ccmwaid.inf", + "modified": "14-Dec-2012 05:10 PM", + "state": { + "active": false, + "complete": true, + "conflict": false, + "current": false, + "potential_conflict": false + }, + "url": "https:\/\/my-rtc.company.com:9443\/path\/", + "uuid": "_F9ue60Y7EeKJIJt6NdfIqg", + "workitems": [ + { + "id": 8112, + "uuid": "_PTlXoEOhEeKdbuKS2aCWjw", + "workitem-label": "Fix the thing" + } + ] + }, + { + "author": "", + "changes": [ + { + "inaccessible-change": false, + "path": "\/thing\/build.xml", + "state": { + "add": true, + "conflict": false, + "content_change": false, + "delete": false, + "move": false, + "potential_conflict": false, + "property_change": false + } + } + ], + "comment": "Add simple build.xml for testing RTC \/ Jenkins integration", + "modified": "17-Dec-2012 05:36 PM", + "state": { + "active": false, + "complete": true, + "conflict": false, + "current": false, + "potential_conflict": false + }, + "url": "https:\/\/my-rtc.company.com:9443\/path\/", + "uuid": "_RBKcUUiaEeKJLpt6NdfIqg", + "workitems": [ + { + "id": 8112, + "uuid": "_PTlXoEOhEeKdbuKS2aCWjw", + "workitem-label": "Fix the thing" + } + ] + } + ], + "name": "thing", + "url": "https:\/\/my-rtc.company.com:9443\/path\/", + "uuid": "_dl2BQzf5EeK96-QDKUBbtg" + } + ], + "name": "thing-1.0-shared", + "url": "https:\/\/my-rtc.company.com:9443\/path\/", + "uuid": "_GDPO0EidEeKJLpt6NdfIqg" + } + ] + } + ] +} From 9a30c2209598b68b3b4ba0e75fd3b92bd95a0e6d Mon Sep 17 00:00:00 2001 From: Chris Cosby Date: Fri, 21 Dec 2012 10:14:04 -0500 Subject: [PATCH 3/3] Add experimental JSON support for accept. The JSON support here is meant as an example for future development. I don't think the Jazz JSON API is stable enough to rely on at this point, so all we're providing here is a basic HOWTO. In particular, the UUID doesn't map to one of the (1001) style descriptive numbers anywhere and the scm compare command doesn't provide the UUID for the changeset in its JSON output. Neat, huh? --- .../plugins/rtc/commands/AcceptCommand.java | 11 +- .../accept/JsonAcceptOutputParser.java | 131 ++++++++---------- .../rtc/commands/AcceptCommandTest.java | 32 +++++ .../plugins/rtc/commands/BaseCommandTest.java | 2 + .../rtc/commands/scm-accept-json-3.1.0.txt | 5 + 5 files changed, 103 insertions(+), 78 deletions(-) diff --git a/src/main/java/com/deluan/jenkins/plugins/rtc/commands/AcceptCommand.java b/src/main/java/com/deluan/jenkins/plugins/rtc/commands/AcceptCommand.java index e4cf21a..2ea8d50 100644 --- a/src/main/java/com/deluan/jenkins/plugins/rtc/commands/AcceptCommand.java +++ b/src/main/java/com/deluan/jenkins/plugins/rtc/commands/AcceptCommand.java @@ -2,10 +2,7 @@ import com.deluan.jenkins.plugins.rtc.JazzConfiguration; import com.deluan.jenkins.plugins.rtc.changelog.JazzChangeSet; -import com.deluan.jenkins.plugins.rtc.commands.accept.AcceptOutputParser_3_1_0; -import com.deluan.jenkins.plugins.rtc.commands.accept.AcceptNewOutputParser; -import com.deluan.jenkins.plugins.rtc.commands.accept.AcceptOldOutputParser; -import com.deluan.jenkins.plugins.rtc.commands.accept.BaseAcceptOutputParser; +import com.deluan.jenkins.plugins.rtc.commands.accept.*; import hudson.util.ArgumentListBuilder; import java.io.BufferedReader; @@ -23,15 +20,17 @@ public class AcceptCommand extends AbstractCommand implements ParseableCommand changeSets; + private boolean useJson; private BaseAcceptOutputParser parser; protected boolean oldFormat = false; public AcceptCommand(JazzConfiguration configurationProvider, Collection changeSets, String version) { super(configurationProvider); this.changeSets = new LinkedHashSet(changeSets); + this.useJson = version.equals("3.1.0-json"); // TODO: Obviously only for testing. if (version.compareTo(FORMAT_VERSION_3_1_0) >= 0) { - parser = new AcceptOutputParser_3_1_0(); + parser = useJson ? new JsonAcceptOutputParser() : new AcceptOutputParser_3_1_0(); } else { this.oldFormat = (version.compareTo(FORMAT_VERSION_2_1_0) < 0); parser = (oldFormat) ? new AcceptOldOutputParser() : new AcceptNewOutputParser(); @@ -46,6 +45,8 @@ public ArgumentListBuilder getArguments() { addLocalWorkspaceArgument(args); addSourceStream(args); args.add("--flow-components", "-o", "-v"); + if (useJson) args.add("--json"); + if (hasAnyChangeSets()) { addChangeSets(args); } diff --git a/src/main/java/com/deluan/jenkins/plugins/rtc/commands/accept/JsonAcceptOutputParser.java b/src/main/java/com/deluan/jenkins/plugins/rtc/commands/accept/JsonAcceptOutputParser.java index d95a4db..026d10a 100644 --- a/src/main/java/com/deluan/jenkins/plugins/rtc/commands/accept/JsonAcceptOutputParser.java +++ b/src/main/java/com/deluan/jenkins/plugins/rtc/commands/accept/JsonAcceptOutputParser.java @@ -11,23 +11,25 @@ import java.util.HashMap; import java.util.Iterator; import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; /** * @author Chris Cosby */ -abstract public class JsonAcceptOutputParser { - protected JsonAcceptOutputParser() { +public class JsonAcceptOutputParser extends BaseAcceptOutputParser { + + public JsonAcceptOutputParser() { + super("", "", ""); + System.err.println("JSON Parser is still very experimental"); } - /* - * The intention here is to parse JSON output of 'scm accept' but I'm out of time. - */ - protected void doSomething(BufferedReader reader) { + public Map parse(BufferedReader reader) throws ParseException, IOException { + Map result = new HashMap(); + String line; StringBuilder json = new StringBuilder(); + JazzChangeSet changeSet; + try { while ((line = reader.readLine()) != null) { json.append(line); @@ -36,80 +38,62 @@ protected void doSomething(BufferedReader reader) { e.printStackTrace(); } - // And this is parsing the output of the compare command, not accept - JSONObject jazzCompareObj = JSONObject.fromObject(json.toString()); - JSONArray jazzDirections = jazzCompareObj.getJSONArray("direction"); - for ( - Iterator jazzCompareIter = jazzDirections.iterator(); - jazzCompareIter.hasNext(); ) - - { - JSONObject direction = jazzCompareIter.next(); - JSONArray components = direction.getJSONArray("components"); - boolean incomingChanges = direction.getBoolean("incoming-changes"); - boolean outgoingChanges = direction.getBoolean("outgoing-changes"); - - if (!incomingChanges) continue; - - for (Iterator jazzComponentIter = components.iterator(); jazzComponentIter.hasNext(); ) { - JSONObject component = jazzComponentIter.next(); - System.out.println("uuid: " + component.getString("uuid")); - JSONArray changesets = component.getJSONArray("changesets"); - - for (Iterator jazzChangesetIter = changesets.iterator(); jazzChangesetIter.hasNext(); ) { - JSONObject changeset = jazzChangesetIter.next(); - } - } - } - } - + // TODO: Are there multiple items in these arrays? I'm only grabbing #0 + JSONObject jazzAcceptObj = JSONObject.fromObject(json.toString()); + JSONArray jazzChanges = jazzAcceptObj.getJSONArray("repos").getJSONObject(0).getJSONArray("workspaces").getJSONObject(0).getJSONArray("components").getJSONObject(0).getJSONArray("changes"); + for (Iterator jazzChangesIter = jazzChanges.iterator(); jazzChangesIter.hasNext(); ) { + JSONObject jazzChange = jazzChangesIter.next(); - protected Pattern startChangesetPattern; - protected Pattern filePattern; - protected Pattern workItemPattern; + //String author = jazzChange.getString("author"); + String rev = jazzChange.getString("uuid"); - public JsonAcceptOutputParser(String startChangesetPattern, String filePattern, String workItemPattern) { - this.workItemPattern = Pattern.compile(workItemPattern); - this.startChangesetPattern = Pattern.compile(startChangesetPattern); - this.filePattern = Pattern.compile(filePattern); - } + changeSet = new JazzChangeSet(); + changeSet.setRev(rev); - public Map parse(BufferedReader reader) throws ParseException, IOException { - Map result = new HashMap(); + // Iterate through the changes under the changes (stupid stupid JSON) and add to the changeSet + JSONArray jazzChangeChanges = jazzChange.getJSONArray("changes"); + for (Iterator jazzChangeChangesIter = jazzChangeChanges.iterator(); jazzChangeChangesIter.hasNext(); ) { + JSONObject jazzChangeChange = jazzChangeChangesIter.next(); - String line; - JazzChangeSet changeSet = null; - Matcher matcher; - - while ((line = reader.readLine()) != null) { - if ((matcher = startChangesetPattern.matcher(line)).matches()) { - if (changeSet != null) { - result.put(changeSet.getRev(), changeSet); - } - changeSet = new JazzChangeSet(); - changeSet.setRev(matcher.group(1)); - } else if ((matcher = filePattern.matcher(line)).matches()) { - assert changeSet != null; - String action = parseAction(matcher.group(1)); - String path = parsePath(matcher.group(2)); + String path = parsePath(jazzChangeChange.getString("path")); + String action = parseAction(jazzChangeChange.getJSONObject("state")); changeSet.addItem(path, action); - } else if ((matcher = workItemPattern.matcher(line)).matches()) { - assert changeSet != null; - changeSet.addWorkItem(parseWorkItem(matcher.group(2))); + } - } - if (changeSet != null) { - result.put(changeSet.getRev(), changeSet); + // Iterate through the workitems under the changes and add to the changeSet + JSONArray jazzChangeWorkitems = jazzChange.getJSONArray("workitems"); + for (Iterator jazzChangeWorkitemsIter = jazzChangeWorkitems.iterator(); jazzChangeWorkitemsIter.hasNext(); ) { + JSONObject jazzChangeWorkItem = jazzChangeWorkitemsIter.next(); + + String id = jazzChangeWorkItem.getString("id"); + String workitemLabel = jazzChangeWorkItem.getString("workitem-label"); + String workitem = parseWorkItem(id, workitemLabel); + + changeSet.addWorkItem(workitem); + } + + result.put(rev, changeSet); } return result; } - abstract protected String parseWorkItem(String string); + protected String parseWorkItem(String id, String workitemLabel) { + return id + " \"" + workitemLabel + "\""; + } - abstract protected String parseEditFlag(String string); + @Override + protected String parseWorkItem(String string) { + return string; + } + + @Override + protected String parseEditFlag(String string) { + return string; + } + @Override protected String parsePath(String string) { String path = string.replaceAll("\\\\", "/").trim(); if (path.startsWith("/")) { @@ -118,12 +102,13 @@ protected String parsePath(String string) { return path; } - protected String parseAction(String string) { - String flag = parseEditFlag(string); - String action = EditType.EDIT.getName(); - if ("a".equals(flag)) { + protected String parseAction(JSONObject state) { + String action = ""; + if (state.getBoolean("content_change")) { + action = EditType.EDIT.getName(); + } else if (state.getBoolean("add")) { action = EditType.ADD.getName(); - } else if ("d".equals(flag)) { + } else if (state.getBoolean("delete")) { action = EditType.DELETE.getName(); } return action; diff --git a/src/test/java/com/deluan/jenkins/plugins/rtc/commands/AcceptCommandTest.java b/src/test/java/com/deluan/jenkins/plugins/rtc/commands/AcceptCommandTest.java index 69ed64d..8100ab3 100644 --- a/src/test/java/com/deluan/jenkins/plugins/rtc/commands/AcceptCommandTest.java +++ b/src/test/java/com/deluan/jenkins/plugins/rtc/commands/AcceptCommandTest.java @@ -5,6 +5,7 @@ import org.junit.Test; import java.util.Arrays; +import java.util.HashMap; import java.util.Map; import static org.hamcrest.core.Is.is; @@ -38,6 +39,37 @@ public void createCommandForVersion_3_0_0() throws Exception { assertThat(cmd.oldFormat, is(false)); } + @Test + public void acceptCommandParseJson_3_1_0() throws Exception { + AcceptCommand cmd = new AcceptCommand(config, Arrays.asList(TEST_REVISIONS_3_1_0), "3.1.0-json"); + Map result = callParser(cmd, "scm-accept-json-3.1.0.txt", TEST_REVISIONS_3_1_0_JSON); + + HashMap hashMap = new HashMap(); + hashMap.put("1008", "_d2oMcUU4EeKJGJt6NdfIqg"); + hashMap.put("1010", "_etjOekOlEeKJEZt6NdfIqg"); + hashMap.put("1009", "_K4DX40SbEeKJFZt6NdfIqg"); + + JazzChangeSet changeSet = result.get(hashMap.get("1008")); + assertEquals("The number of files in the changesets was incorrect", 6, changeSet.getAffectedPaths().size()); + assertEquals("The number of work items in the changesets was incorrect", 2, changeSet.getWorkItems().size()); + + JazzChangeSet.Item item = changeSet.getItems().get(3); + assertTrue("The file is not the expected one", item.getPath().endsWith(".jazzignore")); + assertEquals("The edit type is not the expected one", EditType.ADD, item.getEditType()); + + + changeSet = result.get(hashMap.get("1010")); + item = changeSet.getItems().get(0); + assertTrue("The file is not the expected one", item.getPath().endsWith("MyThingAPI.C")); + assertEquals("The edit type is not the expected one", EditType.EDIT, item.getEditType()); + + + changeSet = result.get(hashMap.get("1009")); + item = changeSet.getItems().get(0); + assertTrue("The file is not the expected one", item.getPath().endsWith(".jazzignore")); + assertEquals("The edit type is not the expected one", EditType.DELETE, item.getEditType()); + } + @Test public void acceptCommandParse_3_1_0() throws Exception { AcceptCommand cmd = new AcceptCommand(config, Arrays.asList(TEST_REVISIONS_3_1_0), "3.1.0"); diff --git a/src/test/java/com/deluan/jenkins/plugins/rtc/commands/BaseCommandTest.java b/src/test/java/com/deluan/jenkins/plugins/rtc/commands/BaseCommandTest.java index 38d3ea8..15278c4 100644 --- a/src/test/java/com/deluan/jenkins/plugins/rtc/commands/BaseCommandTest.java +++ b/src/test/java/com/deluan/jenkins/plugins/rtc/commands/BaseCommandTest.java @@ -19,6 +19,8 @@ abstract public class BaseCommandTest { protected static final String[] TEST_REVISIONS_2_1_0 = new String[]{"1714", "1657", "1652", "1651", "1650", "1648", "1645", "1640", "1625"}; protected static final String[] TEST_REVISIONS_3_1_0 = new String[]{"1010", "1009", "1007", "1008", "1006", "1004"}; + protected static final String[] TEST_REVISIONS_3_1_0_JSON = new String[]{"_etjOekOlEeKJEZt6NdfIqg", "_K4DX40SbEeKJFZt6NdfIqg", "_r_6ZYUY3EeKJIJt6NdfIqg", "_d2oMcUU4EeKJGJt6NdfIqg", "_F9ue60Y7EeKJIJt6NdfIqg", "_RBKcUUiaEeKJLpt6NdfIqg"}; + protected JazzConfiguration config; @Before diff --git a/src/test/resources/com/deluan/jenkins/plugins/rtc/commands/scm-accept-json-3.1.0.txt b/src/test/resources/com/deluan/jenkins/plugins/rtc/commands/scm-accept-json-3.1.0.txt index 50e5444..34342ed 100644 --- a/src/test/resources/com/deluan/jenkins/plugins/rtc/commands/scm-accept-json-3.1.0.txt +++ b/src/test/resources/com/deluan/jenkins/plugins/rtc/commands/scm-accept-json-3.1.0.txt @@ -222,6 +222,11 @@ "url": "https:\/\/my-rtc.company.com:9443\/path\/", "uuid": "_d2oMcUU4EeKJGJt6NdfIqg", "workitems": [ + { + "id": 8111, + "uuid": "_MXLPLTXhEeKdbuKS2aCWjw", + "workitem-label": "A dummy workitem for 3.1.0 test case" + }, { "id": 8112, "uuid": "_PTlXoEOhEeKdbuKS2aCWjw",