Skip to content

Commit

Permalink
g.copy: Report failed copy using an error message (#1086)
Browse files Browse the repository at this point in the history
Changes in behavior:

1. Non-zero return code (EXIT_FAILURE) has now also a corresponding
   error message (ERROR:) not just warning messages (from
   do_copy.c).
2. Skipping an input as ineligible for copying may now result in
   an error (fatal error with EXIT_FAILURE). The error newly occurs when
   all inputs are skipped or, most importantly, when only one input
   was provided and it was skipped.

The skipping (in main.c) is now consistently reported as skipping.
The warning messages also contain more details and the new error
messages point to them.

The M_do_copy function (do_copy.c) now starts with 'Copying' because
it is at the begining of the process instead of 'Copy' which is misleading
(is the user supposed to copy).

The user manual has now a new intro and newly describes the behavior on
error discussing the much simpler single input case separately.

Documentation mentions g.mapset -p and g.mapsets -p instead of mentioning
outdated `$MAPSET` and assuming that it is clear what mapset search path is.

Co-authored-by: Stefan Blumentrath <stefan.blumentrath@gmx.de>
  • Loading branch information
wenzeslaus and ninsbl committed Nov 17, 2020
1 parent 47e52ec commit 39868ea
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 7 deletions.
41 changes: 39 additions & 2 deletions general/g.copy/g.copy.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,50 @@
<h2>DESCRIPTION</h2>

The <em>g.copy</em> module creates a copy of existing raster maps,
vector maps, or other elements. The copy is always created in
the current mapset. The source data can be in the current mapset,
in an explicitly specified mapset, or in a mapset which is in the
current mapset search path (typically the PERMANENT mapset).

<p>
The maps and other elements to copy are specified in pairs
<b>from</b>,<b>to</b> according to their types.
Although typically only one map is copied in one module call,
multiple pairs can be provided for each type and multiple types
can be provided at the same time.

<h3>Relation to mapsets</h3>

A user may access data stored under the other mapsets listed in their
mapset search path. However, the user may only modify data stored
under their own current mapset. <em>g.copy</em> allows the user to copy
existing data files <b>from</b> other mapsets <b>to</b> the user's
current mapset ($MAPSET). The files to be copied must exist in the
user's current mapset search path and location; output is sent to the
current mapset (<code>g.mapset -p</code>). The files to be copied must exist in the
user's current mapset search path (<code>g.mapsets -p</code>) and location;
output is sent to the
relevant data element directory(ies) under the user's current mapset.

<h3>Behavior on error</h3>

Errors typically occur when a map or other element does not exist,
<b>from</b> and <b>to</b> are the same, <b>to</b> element
already exists and overwriting (e.g., by <b>--overwrite</b>) is not
enabled, or the <b>to</b> element has an illegal name.

When only one map or other element is requested to be copied and the copying
is not possible or fails, an error is reported.

<p>
If multiple maps or other elements are copied in one command,
<em>g.copy</em> attempts to copy as much as possible
even when problems occur with one of the elements.
In that case, copying of the element causing problems is skipped, and
<em>g.copy</em> proceeds with copying the remaining elements.

If nothing can be copied or an error occurred during one of the copy
operations, an error message is reported after other possible copy
operations were performed.

<h2>EXAMPLES</h2>

If the user wished to copy the existing raster
Expand Down
34 changes: 30 additions & 4 deletions general/g.copy/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ int main(int argc, char *argv[])
struct Option **parm;
char *from, *to;
int result = EXIT_SUCCESS;
int successful = 0;

G_gisinit(argv[0]);

Expand All @@ -40,6 +41,8 @@ int main(int argc, char *argv[])
module = G_define_module();
G_add_keyword(_("general"));
G_add_keyword(_("map management"));
G_add_keyword(_("copy"));
module->label = _("Creates copies of maps and other elements");
module->description =
_("Copies available data files in the current mapset "
"search path to the user's current mapset.");
Expand All @@ -63,29 +66,52 @@ int main(int argc, char *argv[])
to = parm[n]->answers[i++];
mapset = M_find(n, from, "");
if (!mapset) {
G_warning(_("<%s> not found"), from);
G_warning(_("<%s> does not exist. Skipping."), from);
continue;
}
if (G_strcasecmp(mapset, G_mapset()) == 0 &&
G_strcasecmp(from, to) == 0) {
G_warning(_("%s=%s,%s: files are the same, no copy required"),
G_warning(_("%s=%s,%s: files are the same, no copy required. Skipping."),
parm[n]->key, from, to);
continue;
}
if (M_find(n, to, G_mapset()) && !(module->overwrite)) {
G_warning(_("<%s> already exists. File not copied."), to);
G_warning(_("<%s> already exists and"
" overwrite is not enabled. Skipping."), to);
continue;
}
if (G_legal_filename(to) < 0) {
G_warning(_("<%s> is an illegal file name"), to);
G_warning(_("<%s> is an illegal file name. Skipping."), to);
continue;
}
if (M_do_copy(n, from, mapset, to) == 1) {
result = EXIT_FAILURE;
}
else {
successful += 1;
}
G_remove_misc("cell_misc", "reclassed_to", to);
}
}

if (successful == 0 && result != EXIT_FAILURE) {
/* No successful ones and no failures means all were skipped. */
G_fatal_error(_("All inputs had to be skipped. Nothing to copy."
" See the warning messages above for details."));
}
if (successful == 0 && result == EXIT_FAILURE) {
/* No successful ones and a failure means at least
* one errored, some possibly skipped. */
G_fatal_error(_("Nothing was copied."
" See the warning messages above for details."));
}
if (result == EXIT_FAILURE) {
/* Some successful ones and at least one failure means we are ending
* with an error regardless of skipped ones. */
G_fatal_error(_("Errors occurred during copying."
" See the warning messages above for details."));
}

/* This should be success only. */
exit(result);
}
2 changes: 1 addition & 1 deletion lib/manage/do_copy.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ int M_do_copy(int n, const char *old, const char *mapset, const char *new)

G_debug(3, "Copy %s", list[n].alias);

G_message(_("Copy %s <%s> to current mapset as <%s>"),
G_message(_("Copying %s <%s> to current mapset as <%s>"),
list[n].maindesc, G_fully_qualified_name(old, mapset), new);

M__hold_signals(1);
Expand Down

0 comments on commit 39868ea

Please sign in to comment.