Skip to content

Commit 977c454

Browse files
authored
merge output & output-dir flags (#157)
1 parent a2bab28 commit 977c454

File tree

2 files changed

+46
-76
lines changed

2 files changed

+46
-76
lines changed

dumper/app/src/main/java/com/google/edwmigration/dumper/application/dumper/ConnectorArguments.java

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -237,19 +237,12 @@ public class ConnectorArguments extends DefaultArguments {
237237
// specified)").withRequiredArg().describedAs("my_dbname").withValuesSeparatedBy(',');
238238
private final OptionSpec<File> optionOutput =
239239
parser
240-
.accepts("output", "Output file (cannot be used together with --output-dir)")
240+
.accepts(
241+
"output",
242+
"Output file or directory name. If the file name, along with the `.zip` extension, is not provided dumper will attempt to create the zip file with the default file name in the directory.")
241243
.withRequiredArg()
242244
.ofType(File.class)
243245
.describedAs("cw-dump.zip");
244-
private final OptionSpec<String> optionOutputDir =
245-
parser
246-
.accepts(
247-
"output-dir",
248-
"Output directory where the zip file with the default filename should be created (cannot be used together with --output option). If you want to specify the filename, use --output option instead.")
249-
.withRequiredArg()
250-
.ofType(String.class)
251-
.defaultsTo("")
252-
.describedAs("/home/user/my-dump-dir");
253246
private final OptionSpec<Void> optionOutputContinue =
254247
parser.accepts("continue", "Continues writing a previous output file.");
255248
// TODO: Make this be an ISO instant.
@@ -683,14 +676,8 @@ public List<String> getConfiguration() {
683676
return getOptions().valuesOf(optionConfiguration);
684677
}
685678

686-
@CheckForNull
687-
public File getOutputFile() {
688-
return getOptions().valueOf(optionOutput);
689-
}
690-
691-
@CheckForNull
692-
public String getOutputDirectory() {
693-
return getOptions().valueOf(optionOutputDir);
679+
public Optional<File> getOutputFile() {
680+
return optionAsOptional(optionOutput).filter(file -> !file.getName().isEmpty());
694681
}
695682

696683
public boolean isOutputContinue() {
@@ -854,7 +841,6 @@ public String toString() {
854841
.add("user", getUser())
855842
.add("configuration", getConfiguration())
856843
.add("output", getOutputFile())
857-
.add("output-dir", getOutputDirectory())
858844
.add("query-log-earliest-timestamp", getQueryLogEarliestTimestamp())
859845
.add("query-log-days", getQueryLogDays())
860846
.add("query-log-start", getQueryLogStart())

dumper/app/src/main/java/com/google/edwmigration/dumper/application/dumper/MetadataDumper.java

Lines changed: 41 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@
4444
import com.google.edwmigration.dumper.application.dumper.task.TaskState;
4545
import com.google.edwmigration.dumper.application.dumper.task.VersionTask;
4646
import java.io.File;
47-
import java.io.IOException;
4847
import java.net.URI;
4948
import java.nio.charset.StandardCharsets;
5049
import java.nio.file.FileSystem;
@@ -239,23 +238,8 @@ protected void run(@Nonnull Connector connector, @Nonnull ConnectorArguments arg
239238
// The default output file is based on the connector.
240239
// We had a customer request to base it on the database, but that isn't well-defined,
241240
// as there may be 0 or N databases in a single file.
242-
File outputFile = arguments.getOutputFile();
243-
String outputDirectory = arguments.getOutputDirectory();
244-
245-
boolean isDefaultPath = "".equals(outputDirectory);
246-
if (!isDefaultPath && outputFile != null) {
247-
System.out.println(
248-
"**********************************************************\n"
249-
+ "* ERROR: Using both --output and --output-dir flags is not allowed.\n"
250-
+ "* Please use --help for more information.\n"
251-
+ "**********************************************************");
252-
return;
253-
}
241+
File outputFile = getOutputFile(connector, arguments);
254242

255-
if (outputFile == null) {
256-
outputFile =
257-
new File(outputDirectory, connector.getDefaultFileName(arguments.isAssessment()));
258-
}
259243
if (arguments.isDryRun()) {
260244
String title = "Dry run: Printing task list for " + connector.getName();
261245
System.out.println(title);
@@ -271,48 +255,24 @@ protected void run(@Nonnull Connector connector, @Nonnull ConnectorArguments arg
271255
LOG.info("Using " + connector);
272256
try (Closer closer = Closer.create()) {
273257

274-
final OutputHandleFactory sinkFactory;
275-
if (StringUtils.endsWithIgnoreCase(outputFile.getName(), ".zip")) {
276-
if (outputFile.exists()) {
277-
// If it exists, it must be a file.
278-
if (!outputFile.isFile())
279-
throw new IllegalStateException("Cannot overwrite existing non-file with file.");
280-
if (!arguments.isOutputContinue())
281-
outputFile.delete(); // It's a simple file, and we were asked to overwrite it.
282-
} else {
283-
Files.createParentDirs(outputFile);
284-
}
285-
286-
URI outputUri = URI.create("jar:" + outputFile.toURI());
287-
// LOG.debug("Is a zip file: " + outputUri);
288-
Map<String, Object> fileSystemProperties =
289-
ImmutableMap.<String, Object>builder()
290-
.put("create", "true")
291-
.put("useTempFile", Boolean.TRUE)
292-
.build();
293-
FileSystem fileSystem =
294-
closer.register(FileSystems.newFileSystem(outputUri, fileSystemProperties));
295-
sinkFactory =
296-
new FileSystemOutputHandleFactory(fileSystem, "/"); // It's required to be "/"
258+
if (outputFile.exists()) {
259+
if (!arguments.isOutputContinue())
260+
outputFile.delete(); // It's a simple file, and we were asked to overwrite it.
297261
} else {
298-
if (outputFile.exists()) {
299-
// If it exists, it must be an empty directory, OR we must have specified --continue. We
300-
// never delete.
301-
if (!outputFile.isDirectory())
302-
throw new IllegalStateException(
303-
"Cannot overwrite existing non-directory with directory.");
304-
if (!arguments.isOutputContinue() && !isNullOrEmpty(outputFile.list()))
305-
throw new IllegalStateException(
306-
"Refusing to touch non-empty directory without --continue.");
307-
} else {
308-
// LOG.debug("Not a zip file: " + outputFile);
309-
outputFile.mkdirs();
310-
if (!outputFile.isDirectory())
311-
throw new IOException("Unable to create directory " + outputFile);
312-
}
313-
314-
sinkFactory = new FileSystemOutputHandleFactory(outputFile.toPath());
262+
Files.createParentDirs(outputFile);
315263
}
264+
265+
URI outputUri = URI.create("jar:" + outputFile.toURI());
266+
// LOG.debug("Is a zip file: " + outputUri);
267+
Map<String, Object> fileSystemProperties =
268+
ImmutableMap.<String, Object>builder()
269+
.put("create", "true")
270+
.put("useTempFile", Boolean.TRUE)
271+
.build();
272+
FileSystem fileSystem =
273+
closer.register(FileSystems.newFileSystem(outputUri, fileSystemProperties));
274+
OutputHandleFactory sinkFactory =
275+
new FileSystemOutputHandleFactory(fileSystem, "/"); // It's required to be "/"
316276
LOG.debug("Target filesystem is " + sinkFactory);
317277

318278
Handle handle = closer.register(connector.open(arguments));
@@ -348,6 +308,30 @@ public <T> T runChildTask(Task<T> task) throws MetadataDumperUsageException {
348308
}
349309
}
350310

311+
private File getOutputFile(Connector connector, ConnectorArguments arguments) {
312+
// The default output file is based on the connector.
313+
// We had a customer request to base it on the database, but that isn't well-defined,
314+
// as there may be 0 or N databases in a single file.
315+
String defaultFileName = connector.getDefaultFileName(arguments.isAssessment());
316+
return arguments
317+
.getOutputFile()
318+
.map(
319+
file -> {
320+
String fileName = file.getPath();
321+
if (StringUtils.endsWithIgnoreCase(fileName, ".zip")) return file;
322+
if (file.isFile()) {
323+
throw new IllegalStateException(
324+
String.format(
325+
"A file already exists at %1$s. "
326+
+ "If you want to create a directory, please provide the path to the directory. "
327+
+ "If you want to create %1$s.zip, please add the `.zip` extension manually.",
328+
fileName));
329+
}
330+
return new File(file, defaultFileName);
331+
})
332+
.orElseGet(() -> new File(defaultFileName));
333+
}
334+
351335
private void printDumperSummary(Connector connector, File outputFile) {
352336
if (connector instanceof MetadataConnector) {
353337
log("Metadata has been saved to " + outputFile);

0 commit comments

Comments
 (0)