@ShellMethod(key = "fetch table schema", value = "Fetches latest table schema")
  public String fetchTableSchema(
      @ShellOption(value = {"--outputFilePath"}, defaultValue = ShellOption.NULL,
              help = "File path to write schema") final String outputFilePath) throws Exception {
    HoodieTableMetaClient client = HoodieCLI.getTableMetaClient();
    TableSchemaResolver tableSchemaResolver = new TableSchemaResolver(client);
    Schema schema = tableSchemaResolver.getTableAvroSchema();
    if (outputFilePath != null) {
      LOG.info("Latest table schema : " + schema.toString(true));
      writeToFile(outputFilePath, schema.toString(true));
      return String.format("Latest table schema written to %s", outputFilePath);
    } else {
      return String.format("Latest table schema %s", schema.toString(true));
    }
  }
@Test
  public void testFetchTableSchema() throws Exception {
    // Create table and connect
    HoodieCLI.conf = storageConf();
    new TableCommand().createTable(
        tablePath, tableName, HoodieTableType.COPY_ON_WRITE.name(),
        "", TimelineLayoutVersion.VERSION_1, "org.apache.hudi.common.model.HoodieAvroPayload");

    String schemaStr = "{\n"
        + "         \"type\" : \"record\",\n"
        + "         \"name\" : \"SchemaName\",\n"
        + "         \"namespace\" : \"SchemaNS\",\n"
        + "         \"fields\" : [ {\n"
        + "           \"name\" : \"key\",\n"
        + "           \"type\" : \"int\"\n"
        + "         }, {\n"
        + "           \"name\" : \"val\",\n"
        + "           \"type\" : [ \"null\", \"string\" ],\n"
        + "           \"default\" : null\n"
        + "         }]};";

    generateData(schemaStr);

    Object result = shell.evaluate(() -> "fetch table schema");
    assertTrue(ShellEvaluationResultUtil.isSuccess(result));

    String actualSchemaStr = result.toString().substring(result.toString().indexOf("{"));
    Schema actualSchema = new Schema.Parser().parse(actualSchemaStr);

    Schema expectedSchema = new Schema.Parser().parse(schemaStr);
    expectedSchema = HoodieAvroUtils.addMetadataFields(expectedSchema);
    assertEquals(actualSchema, expectedSchema);

    File file = File.createTempFile("temp", null);
    result = shell.evaluate(() -> "fetch table schema --outputFilePath " + file.getAbsolutePath());
    assertTrue(ShellEvaluationResultUtil.isSuccess(result));

    actualSchemaStr = getFileContent(file.getAbsolutePath());
    actualSchema = new Schema.Parser().parse(actualSchemaStr);
    assertEquals(actualSchema, expectedSchema);
  }