mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-23 22:16:16 +01:00
Merge branch '3158-info-critical' into 'main'
gio-tool-info: Fix critical warning when --attributes are specified and add basic unit tests Closes #3158 See merge request GNOME/glib!3684
This commit is contained in:
commit
e87f8e9c5a
@ -177,7 +177,8 @@ show_info (GFile *file, GFileInfo *info)
|
||||
g_free (flatten);
|
||||
}
|
||||
|
||||
name = g_file_info_get_name (info);
|
||||
name = g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_NAME) ?
|
||||
g_file_info_get_name (info) : NULL;
|
||||
if (name)
|
||||
{
|
||||
escaped = escape_string (name);
|
||||
|
144
gio/gio-tool.c
144
gio/gio-tool.c
@ -219,35 +219,67 @@ handle_version (int argc, char *argv[], gboolean do_help)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
usage (void)
|
||||
typedef int (*HandleSubcommand) (int argc, char *argv[], gboolean do_help);
|
||||
|
||||
static const struct
|
||||
{
|
||||
g_printerr ("%s\n", _("Usage:"));
|
||||
g_printerr (" gio %s %s\n", _("COMMAND"), _("[ARGS…]"));
|
||||
g_printerr ("\n");
|
||||
g_printerr ("%s\n", _("Commands:"));
|
||||
g_printerr (" help %s\n", _("Print help"));
|
||||
g_printerr (" version %s\n", _("Print version"));
|
||||
g_printerr (" cat %s\n", _("Concatenate files to standard output"));
|
||||
g_printerr (" copy %s\n", _("Copy one or more files"));
|
||||
g_printerr (" info %s\n", _("Show information about locations"));
|
||||
g_printerr (" launch %s\n", _("Launch an application from a desktop file"));
|
||||
g_printerr (" list %s\n", _("List the contents of locations"));
|
||||
g_printerr (" mime %s\n", _("Get or set the handler for a mimetype"));
|
||||
g_printerr (" mkdir %s\n", _("Create directories"));
|
||||
g_printerr (" monitor %s\n", _("Monitor files and directories for changes"));
|
||||
g_printerr (" mount %s\n", _("Mount or unmount the locations"));
|
||||
g_printerr (" move %s\n", _("Move one or more files"));
|
||||
g_printerr (" open %s\n", _("Open files with the default application"));
|
||||
g_printerr (" rename %s\n", _("Rename a file"));
|
||||
g_printerr (" remove %s\n", _("Delete one or more files"));
|
||||
g_printerr (" save %s\n", _("Read from standard input and save"));
|
||||
g_printerr (" set %s\n", _("Set a file attribute"));
|
||||
g_printerr (" trash %s\n", _("Move files or directories to the trash"));
|
||||
g_printerr (" tree %s\n", _("Lists the contents of locations in a tree"));
|
||||
g_printerr ("\n");
|
||||
g_printerr (_("Use %s to get detailed help.\n"), "“gio help COMMAND”");
|
||||
exit (1);
|
||||
const char *name; /* as used on the command line */
|
||||
HandleSubcommand handle_func; /* (nullable) for "help" only */
|
||||
const char *description; /* translatable */
|
||||
} gio_subcommands[] = {
|
||||
{ "help", NULL, N_("Print help") },
|
||||
{ "version", handle_version, N_("Print version") },
|
||||
{ "cat", handle_cat, N_("Concatenate files to standard output") },
|
||||
{ "copy", handle_copy, N_("Copy one or more files") },
|
||||
{ "info", handle_info, N_("Show information about locations") },
|
||||
{ "launch", handle_launch, N_("Launch an application from a desktop file") },
|
||||
{ "list", handle_list, N_("List the contents of locations") },
|
||||
{ "mime", handle_mime, N_("Get or set the handler for a mimetype") },
|
||||
{ "mkdir", handle_mkdir, N_("Create directories") },
|
||||
{ "monitor", handle_monitor, N_("Monitor files and directories for changes") },
|
||||
{ "mount", handle_mount, N_("Mount or unmount the locations") },
|
||||
{ "move", handle_move, N_("Move one or more files") },
|
||||
{ "open", handle_open, N_("Open files with the default application") },
|
||||
{ "rename", handle_rename, N_("Rename a file") },
|
||||
{ "remove", handle_remove, N_("Delete one or more files") },
|
||||
{ "save", handle_save, N_("Read from standard input and save") },
|
||||
{ "set", handle_set, N_("Set a file attribute") },
|
||||
{ "trash", handle_trash, N_("Move files or directories to the trash") },
|
||||
{ "tree", handle_tree, N_("Lists the contents of locations in a tree") },
|
||||
};
|
||||
|
||||
static void
|
||||
usage (gboolean is_error)
|
||||
{
|
||||
GString *out = NULL;
|
||||
size_t name_width = 0;
|
||||
|
||||
out = g_string_new ("");
|
||||
g_string_append_printf (out, "%s\n", _("Usage:"));
|
||||
g_string_append_printf (out, " gio %s %s\n", _("COMMAND"), _("[ARGS…]"));
|
||||
g_string_append_c (out, '\n');
|
||||
g_string_append_printf (out, "%s\n", _("Commands:"));
|
||||
|
||||
/* Work out the maximum name length for column alignment. */
|
||||
for (size_t i = 0; i < G_N_ELEMENTS (gio_subcommands); i++)
|
||||
name_width = MAX (name_width, strlen (gio_subcommands[i].name));
|
||||
|
||||
for (size_t i = 0; i < G_N_ELEMENTS (gio_subcommands); i++)
|
||||
{
|
||||
g_string_append_printf (out, " %-*s %s\n",
|
||||
(int) name_width, gio_subcommands[i].name,
|
||||
_(gio_subcommands[i].description));
|
||||
}
|
||||
|
||||
g_string_append_c (out, '\n');
|
||||
g_string_append_printf (out, _("Use %s to get detailed help.\n"), "“gio help COMMAND”");
|
||||
|
||||
if (is_error)
|
||||
g_printerr ("%s", out->str);
|
||||
else
|
||||
g_print ("%s", out->str);
|
||||
|
||||
g_string_free (out, TRUE);
|
||||
}
|
||||
|
||||
int
|
||||
@ -277,7 +309,7 @@ main (int argc, char **argv)
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
usage ();
|
||||
usage (TRUE);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -290,7 +322,7 @@ main (int argc, char **argv)
|
||||
{
|
||||
if (argc == 1)
|
||||
{
|
||||
usage ();
|
||||
usage (FALSE);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
@ -301,50 +333,24 @@ main (int argc, char **argv)
|
||||
}
|
||||
else if (g_str_equal (command, "--help"))
|
||||
{
|
||||
usage ();
|
||||
usage (FALSE);
|
||||
return 0;
|
||||
}
|
||||
else if (g_str_equal (command, "--version"))
|
||||
command = "version";
|
||||
|
||||
if (g_str_equal (command, "version"))
|
||||
return handle_version (argc, argv, do_help);
|
||||
else if (g_str_equal (command, "cat"))
|
||||
return handle_cat (argc, argv, do_help);
|
||||
else if (g_str_equal (command, "copy"))
|
||||
return handle_copy (argc, argv, do_help);
|
||||
else if (g_str_equal (command, "info"))
|
||||
return handle_info (argc, argv, do_help);
|
||||
else if (g_str_equal (command, "launch"))
|
||||
return handle_launch (argc, argv, do_help);
|
||||
else if (g_str_equal (command, "list"))
|
||||
return handle_list (argc, argv, do_help);
|
||||
else if (g_str_equal (command, "mime"))
|
||||
return handle_mime (argc, argv, do_help);
|
||||
else if (g_str_equal (command, "mkdir"))
|
||||
return handle_mkdir (argc, argv, do_help);
|
||||
else if (g_str_equal (command, "monitor"))
|
||||
return handle_monitor (argc, argv, do_help);
|
||||
else if (g_str_equal (command, "mount"))
|
||||
return handle_mount (argc, argv, do_help);
|
||||
else if (g_str_equal (command, "move"))
|
||||
return handle_move (argc, argv, do_help);
|
||||
else if (g_str_equal (command, "open"))
|
||||
return handle_open (argc, argv, do_help);
|
||||
else if (g_str_equal (command, "rename"))
|
||||
return handle_rename (argc, argv, do_help);
|
||||
else if (g_str_equal (command, "remove"))
|
||||
return handle_remove (argc, argv, do_help);
|
||||
else if (g_str_equal (command, "save"))
|
||||
return handle_save (argc, argv, do_help);
|
||||
else if (g_str_equal (command, "set"))
|
||||
return handle_set (argc, argv, do_help);
|
||||
else if (g_str_equal (command, "trash"))
|
||||
return handle_trash (argc, argv, do_help);
|
||||
else if (g_str_equal (command, "tree"))
|
||||
return handle_tree (argc, argv, do_help);
|
||||
else
|
||||
usage ();
|
||||
/* Work out which subcommand it is. */
|
||||
for (size_t i = 0; i < G_N_ELEMENTS (gio_subcommands); i++)
|
||||
{
|
||||
if (g_str_equal (command, gio_subcommands[i].name))
|
||||
{
|
||||
g_assert (gio_subcommands[i].handle_func != NULL);
|
||||
return gio_subcommands[i].handle_func (argc, argv, do_help);
|
||||
}
|
||||
}
|
||||
|
||||
/* Unknown subcommand. */
|
||||
usage (TRUE);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -985,7 +985,7 @@ gio_tool_sources = [
|
||||
'gio-tool-tree.c',
|
||||
]
|
||||
|
||||
executable('gio', gio_tool_sources,
|
||||
gio_tool = executable('gio', gio_tool_sources,
|
||||
install : true,
|
||||
install_tag : 'bin',
|
||||
c_args : gio_c_args,
|
||||
|
@ -116,6 +116,7 @@ class TestCodegen(unittest.TestCase):
|
||||
|
||||
env = os.environ.copy()
|
||||
env["LC_ALL"] = "C.UTF-8"
|
||||
env["G_DEBUG"] = "fatal-warnings"
|
||||
print("Environment:", env)
|
||||
|
||||
# We want to ensure consistent line endings...
|
||||
|
132
gio/tests/gio-tool.py
Normal file
132
gio/tests/gio-tool.py
Normal file
@ -0,0 +1,132 @@
|
||||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright © 2018, 2019 Endless Mobile, Inc.
|
||||
# Copyright © 2023 Philip Withnall
|
||||
#
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
# MA 02110-1301 USA
|
||||
|
||||
"""Integration tests for the gio utility."""
|
||||
|
||||
import collections
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
import taptestrunner
|
||||
|
||||
|
||||
Result = collections.namedtuple("Result", ("info", "out", "err"))
|
||||
|
||||
|
||||
class TestGioTool(unittest.TestCase):
|
||||
"""Integration test for running the gio tool.
|
||||
|
||||
This can be run when installed or uninstalled. When uninstalled, it
|
||||
requires G_TEST_BUILDDIR and G_TEST_SRCDIR to be set.
|
||||
|
||||
The idea with this test harness is to test the gio utility, its
|
||||
handling of command line arguments, its exit statuses, and its actual
|
||||
effects on the file system.
|
||||
"""
|
||||
|
||||
# Track the cwd, we want to back out to that to clean up our tempdir
|
||||
cwd = ""
|
||||
|
||||
def setUp(self):
|
||||
self.timeout_seconds = 6 # seconds per test
|
||||
self.tmpdir = tempfile.TemporaryDirectory()
|
||||
self.cwd = os.getcwd()
|
||||
os.chdir(self.tmpdir.name)
|
||||
print("tmpdir:", self.tmpdir.name)
|
||||
|
||||
ext = ""
|
||||
if os.name == "nt":
|
||||
ext = ".exe"
|
||||
|
||||
if "G_TEST_BUILDDIR" in os.environ:
|
||||
self.__gio = os.path.join(
|
||||
os.environ["G_TEST_BUILDDIR"],
|
||||
"..",
|
||||
"gio" + ext,
|
||||
)
|
||||
else:
|
||||
self.__gio = shutil.which("gio" + ext)
|
||||
print("gio:", self.__gio)
|
||||
|
||||
def tearDown(self):
|
||||
os.chdir(self.cwd)
|
||||
self.tmpdir.cleanup()
|
||||
|
||||
def runGio(self, *args):
|
||||
argv = [self.__gio]
|
||||
argv.extend(args)
|
||||
print("Running:", argv)
|
||||
|
||||
env = os.environ.copy()
|
||||
env["LC_ALL"] = "C.UTF-8"
|
||||
env["G_DEBUG"] = "fatal-warnings"
|
||||
print("Environment:", env)
|
||||
|
||||
# We want to ensure consistent line endings...
|
||||
info = subprocess.run(
|
||||
argv,
|
||||
timeout=self.timeout_seconds,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
env=env,
|
||||
universal_newlines=True,
|
||||
)
|
||||
info.check_returncode()
|
||||
out = info.stdout.strip()
|
||||
err = info.stderr.strip()
|
||||
|
||||
result = Result(info, out, err)
|
||||
|
||||
print("Output:", result.out)
|
||||
return result
|
||||
|
||||
def test_help(self):
|
||||
"""Test the --help argument and help subcommand."""
|
||||
result = self.runGio("--help")
|
||||
result2 = self.runGio("help")
|
||||
|
||||
self.assertEqual(result.out, result2.out)
|
||||
self.assertEqual(result.err, result2.err)
|
||||
|
||||
self.assertIn("Usage:\n gio COMMAND", result.out)
|
||||
self.assertIn("List the contents of locations", result.out)
|
||||
|
||||
def test_no_args(self):
|
||||
"""Test running with no arguments at all."""
|
||||
with self.assertRaises(subprocess.CalledProcessError):
|
||||
self.runGio()
|
||||
|
||||
def test_info_non_default_attributes(self):
|
||||
"""Test running `gio info --attributes` with a non-default list."""
|
||||
with tempfile.NamedTemporaryFile(dir=self.tmpdir.name) as tmpfile:
|
||||
result = self.runGio(
|
||||
"info", "--attributes=standard::content-type", tmpfile.name
|
||||
)
|
||||
self.assertIn("standard::content-type: application/x-zerosize", result.out)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main(testRunner=taptestrunner.TAPTestRunner())
|
@ -181,6 +181,10 @@ python_tests = {
|
||||
'suite': ['gdbus-codegen', 'slow'],
|
||||
'timeout': 90,
|
||||
},
|
||||
'gio-tool.py' : {
|
||||
'depends' : gio_tool,
|
||||
'can_fail' : host_system == 'windows',
|
||||
},
|
||||
}
|
||||
|
||||
test_env = environment()
|
||||
@ -1074,6 +1078,7 @@ endforeach
|
||||
foreach test_name, extra_args : python_tests
|
||||
depends = [extra_args.get('depends', [])]
|
||||
suite = ['gio', 'no-valgrind'] + extra_args.get('suite', [])
|
||||
timeout = extra_args.get('timeout', test_timeout)
|
||||
|
||||
if extra_args.get('can_fail', false)
|
||||
suite += 'failing'
|
||||
@ -1090,7 +1095,7 @@ foreach test_name, extra_args : python_tests
|
||||
depends: depends,
|
||||
args: ['-B', files(test_name)],
|
||||
env: test_env,
|
||||
timeout: extra_args.get('timeout'),
|
||||
timeout: timeout,
|
||||
suite: suite,
|
||||
)
|
||||
|
||||
|
@ -63,6 +63,7 @@ class TestMessagesLowMemory(unittest.TestCase):
|
||||
|
||||
env = os.environ.copy()
|
||||
env["LC_ALL"] = "C.UTF-8"
|
||||
env["G_DEBUG"] = "fatal-warnings"
|
||||
print("Environment:", env)
|
||||
|
||||
# We want to ensure consistent line endings...
|
||||
|
@ -88,6 +88,7 @@ class TestGenmarshal(unittest.TestCase):
|
||||
|
||||
env = os.environ.copy()
|
||||
env["LC_ALL"] = "C.UTF-8"
|
||||
env["G_DEBUG"] = "fatal-warnings"
|
||||
print("Environment:", env)
|
||||
|
||||
# We want to ensure consistent line endings...
|
||||
|
@ -59,6 +59,7 @@ class TestGobjectQuery(unittest.TestCase):
|
||||
|
||||
env = os.environ.copy()
|
||||
env["LC_ALL"] = "C.UTF-8"
|
||||
env["G_DEBUG"] = "fatal-warnings"
|
||||
print("Environment:", env)
|
||||
|
||||
# We want to ensure consistent line endings...
|
||||
|
@ -100,6 +100,7 @@ class TestMkenums(unittest.TestCase):
|
||||
|
||||
env = os.environ.copy()
|
||||
env["LC_ALL"] = "C.UTF-8"
|
||||
env["G_DEBUG"] = "fatal-warnings"
|
||||
print("Environment:", env)
|
||||
|
||||
# We want to ensure consistent line endings...
|
||||
|
Loading…
Reference in New Issue
Block a user