mirror of https://github.com/apache/cloudstack.git
Merge pull request #1658 from swill/api_diff_gen
Added an additional JSON diff output to the ApiXmlDocReaderThe original TXT diff format is very hard to work with if you are trying to programmatically use the output to generate documentation. Previously, @pdion891 spent a lot of time trying to manually reformat this output in order for it to be represented in the Release Notes. This pull request adds JSON as an output format as well as the existing TXT to simplify the ability for parsers and generators to use the output. This new JSON format was used to generate the 4.9.0 release notes (that code will be contributed separately). Old manually formatted output: http://docs.cloudstack.apache.org/projects/cloudstack-release-notes/en/4.7.0/api-changes.html New auto-formatted output using this new JSON output: http://docs.cloudstack.apache.org/projects/cloudstack-release-notes/en/4.9.0/api-changes.html I have included the output of the `diff.txt` as well as the `diff.json` to this PR so you can see the resulting output of both file formats (diff between 4.8 and 4.9). [diff.txt.zip](https://github.com/apache/cloudstack/files/432983/diff.txt.zip) [diff.json.zip](https://github.com/apache/cloudstack/files/432982/diff.json.zip) * pr/1658: Added JSON diff output to the ApiXmlDocReader in additon TXT for parsability Signed-off-by: Will Stevens <williamstevens@gmail.com>
This commit is contained in:
commit
6b9cd2832b
|
|
@ -30,6 +30,7 @@ import java.util.Iterator;
|
|||
import java.util.List;
|
||||
import java.util.Arrays;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
import com.thoughtworks.xstream.XStream;
|
||||
import com.thoughtworks.xstream.io.xml.DomDriver;
|
||||
|
|
@ -45,6 +46,8 @@ public class ApiXmlDocReader {
|
|||
ArrayList<Command> addedCommands = new ArrayList<Command>();
|
||||
ArrayList<Command> removedCommands = new ArrayList<Command>();
|
||||
HashMap<String, Command> stableCommands = new HashMap<String, Command>();
|
||||
HashMap<String, Object> jsonOut = new HashMap<String, Object>();
|
||||
Gson gson = new Gson();
|
||||
|
||||
XStream xs = new XStream(new DomDriver());
|
||||
xs.alias("command", Command.class);
|
||||
|
|
@ -108,49 +111,69 @@ public class ApiXmlDocReader {
|
|||
}
|
||||
|
||||
try (FileWriter fstream = new FileWriter(dirName + "/diff.txt");
|
||||
BufferedWriter out = new BufferedWriter(fstream);){
|
||||
BufferedWriter out = new BufferedWriter(fstream);
|
||||
FileWriter jfstream = new FileWriter(dirName + "/diff.json");
|
||||
BufferedWriter json = new BufferedWriter(jfstream);){
|
||||
// Print added commands
|
||||
out.write("Added commands:\n");
|
||||
ArrayList<HashMap<String, Object>> addedCmds = new ArrayList<HashMap<String, Object>>();
|
||||
for (Command c : addedCommands) {
|
||||
HashMap<String, Object> addedCmd = new HashMap<String, Object>();
|
||||
if (c.getDescription() != null && !c.getDescription().isEmpty()) {
|
||||
out.write("\n " + c.getName() + " (" + c.getDescription() + ")\n");
|
||||
addedCmd.put("description", c.getDescription());
|
||||
} else {
|
||||
out.write("\n " + c.getName() + "\n");
|
||||
}
|
||||
|
||||
addedCmd.put("name", c.getName());
|
||||
addedCmds.add(addedCmd);
|
||||
}
|
||||
jsonOut.put("commands_added", addedCmds);
|
||||
|
||||
// Print removed commands
|
||||
out.write("\nRemoved commands:\n");
|
||||
ArrayList<HashMap<String, Object>> removedCmds = new ArrayList<HashMap<String, Object>>();
|
||||
for (Command c : removedCommands) {
|
||||
HashMap<String, Object> removedCmd = new HashMap<String, Object>();
|
||||
if (c.getDescription() != null && !c.getDescription().isEmpty()) {
|
||||
out.write("\n\t" + c.getName() + " (" + c.getDescription() + ")\n");
|
||||
removedCmd.put("description", c.getDescription());
|
||||
} else {
|
||||
out.write("\n\t" + c.getName() + "\n");
|
||||
}
|
||||
|
||||
removedCmd.put("name", c.getName());
|
||||
removedCmds.add(removedCmd);
|
||||
}
|
||||
jsonOut.put("commands_removed", removedCmds);
|
||||
|
||||
out.write("\nChanges in command type (sync versus async)\n");
|
||||
ArrayList<HashMap<String, Object>> syncChangeCmds = new ArrayList<HashMap<String, Object>>();
|
||||
// Verify if the command was sync and became async and vice versa
|
||||
for (Map.Entry<String,Command>entry : stableCommands.entrySet()) {
|
||||
if (commands.get(entry.getKey()).isAsync() != oldCommands.get(entry.getKey()).isAsync()) {
|
||||
HashMap<String, Object> syncChangeCmd = new HashMap<String, Object>();
|
||||
String type = "Sync";
|
||||
if (commands.get(entry.getKey()).isAsync()) {
|
||||
type = "Async";
|
||||
}
|
||||
syncChangeCmd.put("name", entry.getValue().getName());
|
||||
syncChangeCmd.put("sync_type", type);
|
||||
syncChangeCmds.add(syncChangeCmd);
|
||||
out.write("\n\t" + entry.getValue().getName() + " became " + type);
|
||||
}
|
||||
}
|
||||
jsonOut.put("commands_sync_changed", syncChangeCmds);
|
||||
|
||||
// Print differences between commands arguments
|
||||
out.write("\n\nChanges in commands arguments:\n");
|
||||
ArrayList<HashMap<String, Object>> argsChangeCmds = new ArrayList<HashMap<String, Object>>();
|
||||
for (String key : stableCommands.keySet()) {
|
||||
ArrayList<Argument> newReqArgs = new ArrayList<Argument>();
|
||||
ArrayList<Argument> removedReqArgs = new ArrayList<Argument>();
|
||||
HashMap<String, Argument> stableReqArgs = new HashMap<String, Argument>();
|
||||
ArrayList<Argument> newRespArgs = new ArrayList<Argument>();
|
||||
ArrayList<Argument> removedRespArgs = new ArrayList<Argument>();
|
||||
HashMap<String, Object> argsChangeCmd = new HashMap<String, Object>();
|
||||
|
||||
Command newCommand = commands.get(key);
|
||||
Command oldCommand = oldCommands.get(key);
|
||||
|
|
@ -208,22 +231,30 @@ public class ApiXmlDocReader {
|
|||
commandInfo.append("\n\t" + key);
|
||||
out.write(commandInfo.toString());
|
||||
out.write("\n");
|
||||
argsChangeCmd.put("name", key);
|
||||
|
||||
// Request
|
||||
if (newReqArgs.size() != 0 || removedReqArgs.size() != 0 || stableReqArgs.size() != 0) {
|
||||
HashMap<String, Object> requestChanges = new HashMap<String, Object>();
|
||||
StringBuffer request = new StringBuffer();
|
||||
request.append("\n\t\tRequest:\n");
|
||||
out.write(request.toString());
|
||||
if (newReqArgs.size() != 0) {
|
||||
StringBuffer newParameters = new StringBuffer();
|
||||
newParameters.append("\n\t\t\tNew parameters: ");
|
||||
ArrayList<HashMap<String, Object>> newRequestParams = new ArrayList<HashMap<String, Object>>();
|
||||
for (Argument newArg : newReqArgs) {
|
||||
HashMap<String, Object> newRequestParam = new HashMap<String, Object>();
|
||||
String isRequiredParam = "optional";
|
||||
if (newArg.isRequired()) {
|
||||
isRequiredParam = "required";
|
||||
}
|
||||
newRequestParam.put("name", newArg.getName());
|
||||
newRequestParam.put("required", newArg.isRequired());
|
||||
newRequestParams.add(newRequestParam);
|
||||
newParameters.append(newArg.getName() + " (" + isRequiredParam + "), ");
|
||||
}
|
||||
requestChanges.put("params_new", newRequestParams);
|
||||
newParameters.delete(newParameters.length() - 2, newParameters.length() - 1);
|
||||
out.write(newParameters.toString());
|
||||
out.write("\n");
|
||||
|
|
@ -231,9 +262,14 @@ public class ApiXmlDocReader {
|
|||
if (removedReqArgs.size() != 0) {
|
||||
StringBuffer removedParameters = new StringBuffer();
|
||||
removedParameters.append("\n\t\t\tRemoved parameters: ");
|
||||
ArrayList<HashMap<String, Object>> removedRequestParams = new ArrayList<HashMap<String, Object>>();
|
||||
for (Argument removedArg : removedReqArgs) {
|
||||
HashMap<String, Object> removedRequestParam = new HashMap<String, Object>();
|
||||
removedRequestParam.put("name", removedArg.getName());
|
||||
removedRequestParams.add(removedRequestParam);
|
||||
removedParameters.append(removedArg.getName() + ", ");
|
||||
}
|
||||
requestChanges.put("params_removed", removedRequestParams);
|
||||
removedParameters.delete(removedParameters.length() - 2, removedParameters.length() - 1);
|
||||
out.write(removedParameters.toString());
|
||||
out.write("\n");
|
||||
|
|
@ -242,52 +278,78 @@ public class ApiXmlDocReader {
|
|||
if (stableReqArgs.size() != 0) {
|
||||
StringBuffer changedParameters = new StringBuffer();
|
||||
changedParameters.append("\n\t\t\tChanged parameters: ");
|
||||
ArrayList<HashMap<String, Object>> changedRequestParams = new ArrayList<HashMap<String, Object>>();
|
||||
for (Argument stableArg : stableReqArgs.values()) {
|
||||
HashMap<String, Object> changedRequestParam = new HashMap<String, Object>();
|
||||
String newRequired = "optional";
|
||||
String oldRequired = "optional";
|
||||
if ((oldCommand.getReqArgByName(stableArg.getName()) != null) && (oldCommand.getReqArgByName(stableArg.getName()).isRequired() == true))
|
||||
changedRequestParam.put("required_old", false);
|
||||
changedRequestParam.put("required_new", false);
|
||||
if ((oldCommand.getReqArgByName(stableArg.getName()) != null) && (oldCommand.getReqArgByName(stableArg.getName()).isRequired() == true)) {
|
||||
oldRequired = "required";
|
||||
if ((newCommand.getReqArgByName(stableArg.getName()) != null) && (newCommand.getReqArgByName(stableArg.getName()).isRequired() == true))
|
||||
changedRequestParam.put("required_old", true);
|
||||
}
|
||||
if ((newCommand.getReqArgByName(stableArg.getName()) != null) && (newCommand.getReqArgByName(stableArg.getName()).isRequired() == true)) {
|
||||
newRequired = "required";
|
||||
changedRequestParam.put("required_new", true);
|
||||
}
|
||||
changedRequestParam.put("name", stableArg.getName());
|
||||
changedRequestParams.add(changedRequestParam);
|
||||
changedParameters.append(stableArg.getName() + " (old version - " + oldRequired + ", new version - " + newRequired + "), ");
|
||||
}
|
||||
requestChanges.put("params_changed", changedRequestParams);
|
||||
changedParameters.delete(changedParameters.length() - 2, changedParameters.length() - 1);
|
||||
out.write(changedParameters.toString());
|
||||
out.write("\n");
|
||||
}
|
||||
argsChangeCmd.put("request", requestChanges);
|
||||
}
|
||||
|
||||
// Response
|
||||
if (newRespArgs.size() != 0 || removedRespArgs.size() != 0) {
|
||||
HashMap<String, Object> responseChanges = new HashMap<String, Object>();
|
||||
StringBuffer changedResponseParams = new StringBuffer();
|
||||
changedResponseParams.append("\n\t\tResponse:\n");
|
||||
out.write(changedResponseParams.toString());
|
||||
if (newRespArgs.size() != 0) {
|
||||
ArrayList<HashMap<String, Object>> newResponseParams = new ArrayList<HashMap<String, Object>>();
|
||||
StringBuffer newRespParams = new StringBuffer();
|
||||
newRespParams.append("\n\t\t\tNew parameters: ");
|
||||
for (Argument newArg : newRespArgs) {
|
||||
HashMap<String, Object> newResponseParam = new HashMap<String, Object>();
|
||||
newResponseParam.put("name", newArg.getName());
|
||||
newResponseParams.add(newResponseParam);
|
||||
newRespParams.append(newArg.getName() + ", ");
|
||||
}
|
||||
responseChanges.put("params_new", newResponseParams);
|
||||
newRespParams.delete(newRespParams.length() - 2, newRespParams.length() - 1);
|
||||
out.write(newRespParams.toString());
|
||||
out.write("\n");
|
||||
}
|
||||
if (removedRespArgs.size() != 0) {
|
||||
ArrayList<HashMap<String, Object>> removedResponseParams = new ArrayList<HashMap<String, Object>>();
|
||||
StringBuffer removedRespParams = new StringBuffer();
|
||||
removedRespParams.append("\n\t\t\tRemoved parameters: ");
|
||||
for (Argument removedArg : removedRespArgs) {
|
||||
HashMap<String, Object> removedResponseParam = new HashMap<String, Object>();
|
||||
removedResponseParam.put("name", removedArg.getName());
|
||||
removedResponseParams.add(removedResponseParam);
|
||||
removedRespParams.append(removedArg.getName() + ", ");
|
||||
}
|
||||
responseChanges.put("params_removed", removedResponseParams);
|
||||
removedRespParams.delete(removedRespParams.length() - 2, removedRespParams.length() - 1);
|
||||
out.write(removedRespParams.toString());
|
||||
out.write("\n");
|
||||
}
|
||||
argsChangeCmd.put("response", responseChanges);
|
||||
}
|
||||
argsChangeCmds.add(argsChangeCmd);
|
||||
}
|
||||
}
|
||||
jsonOut.put("commands_args_changed", argsChangeCmds);
|
||||
json.write(gson.toJson(jsonOut));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue