mirror of
https://github.com/frida/frida-python
synced 2026-06-08 14:16:17 +00:00
Compare commits
44 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3aa122f4fd | |||
| ef315fc0ad | |||
| daf93eea54 | |||
| 5d02a36906 | |||
| ba8daa423d | |||
| afb27bfa7c | |||
| 93a201acf2 | |||
| ca1cdad96a | |||
| fbc83cc9bf | |||
| b838e1df9a | |||
| e2409be987 | |||
| b061ea43d2 | |||
| a50a62999a | |||
| 3a47d33ee8 | |||
| ea93d827bb | |||
| 8d4c05f664 | |||
| 2f78c96622 | |||
| 4b5aa28119 | |||
| 4f87afa0f1 | |||
| 82272945ac | |||
| bf496a81d9 | |||
| c2dcae3ff4 | |||
| 0cb42c47dc | |||
| 0e3a9fb551 | |||
| 4e16e5c667 | |||
| 09d6c7b044 | |||
| e11efce5c2 | |||
| e174be9998 | |||
| eae3d1dc65 | |||
| 2d26b94c7d | |||
| f396958dfe | |||
| 93fb33206f | |||
| aed3c1b7bf | |||
| 690da0652d | |||
| bec6221c02 | |||
| 53479e1814 | |||
| 68bc65ecd4 | |||
| 6492081c92 | |||
| 262b984e23 | |||
| 730ec03652 | |||
| 25f96f92d3 | |||
| dec23f9ef5 | |||
| 906d27bcb7 | |||
| b0018c9812 |
@@ -775,6 +775,20 @@ class Compiler(Object):
|
||||
...
|
||||
|
||||
class PackageManager(Object):
|
||||
@property
|
||||
def registry(self) -> str:
|
||||
"""
|
||||
The registry being used.
|
||||
"""
|
||||
...
|
||||
|
||||
@registry.setter
|
||||
def registry(self, value: str) -> None:
|
||||
"""
|
||||
Change the registry to use.
|
||||
"""
|
||||
...
|
||||
|
||||
def search(
|
||||
self,
|
||||
query: str,
|
||||
@@ -789,7 +803,9 @@ class PackageManager(Object):
|
||||
def install(
|
||||
self,
|
||||
project_root: Optional[str] = None,
|
||||
role: Optional[str] = None,
|
||||
specs: Optional[Sequence[str]] = None,
|
||||
omits: Optional[Sequence[str]] = None,
|
||||
) -> PackageInstallResult:
|
||||
"""
|
||||
Install one or more packages.
|
||||
|
||||
+217
-5
@@ -529,32 +529,42 @@ static gchar * frida_python_authentication_service_authenticate_finish (FridaAut
|
||||
static void frida_python_authentication_service_do_authenticate (GTask * task, FridaPythonAuthenticationService * self);
|
||||
|
||||
static int PyCompiler_init (PyCompiler * self, PyObject * args, PyObject * kw);
|
||||
static void PyCompiler_dealloc (PyCompiler * self);
|
||||
static PyObject * PyCompiler_build (PyCompiler * self, PyObject * args, PyObject * kw);
|
||||
static PyObject * PyCompiler_watch (PyCompiler * self, PyObject * args, PyObject * kw);
|
||||
static gboolean PyCompiler_set_options (FridaCompilerOptions * options, const gchar * project_root_value, const gchar * output_format_value,
|
||||
const gchar * bundle_format_value, const gchar * type_check_value, const gchar * source_maps_value, const gchar * compression_value);
|
||||
|
||||
static int PyPackageManager_init (PyPackageManager * self, PyObject * args, PyObject * kw);
|
||||
static void PyPackageManager_dealloc (PyPackageManager * self);
|
||||
static PyObject * PyPackageManager_repr (PyPackageManager * self);
|
||||
static PyObject * PyPackageManager_get_registry (PyPackageManager * self, void * closure);
|
||||
static int PyPackageManager_set_registry (PyPackageManager * self, PyObject * val, void * closure);
|
||||
static PyObject * PyPackageManager_search (PyPackageManager * self, PyObject * args, PyObject * kw);
|
||||
static PyObject * PyPackageManager_install (PyPackageManager * self, PyObject * args, PyObject * kw);
|
||||
static FridaPackageInstallOptions * PyPackageManager_parse_install_options (const gchar * project_root, PyObject * specs_value);
|
||||
static FridaPackageInstallOptions * PyPackageManager_parse_install_options (const gchar * project_root, const char * role_value,
|
||||
PyObject * specs_value, PyObject * omits_value);
|
||||
|
||||
static PyObject * PyPackage_new_take_handle (FridaPackage * handle);
|
||||
static int PyPackage_init (PyPackage * self, PyObject * args, PyObject * kw);
|
||||
static void PyPackage_init_from_handle (PyPackage * self, FridaPackage * handle);
|
||||
static void PyPackage_dealloc (PyPackage * self);
|
||||
static PyObject * PyPackage_repr (PyPackage * self);
|
||||
|
||||
static PyObject * PyPackageSearchResult_new_take_handle (FridaPackageSearchResult * handle);
|
||||
static int PyPackageSearchResult_init (PyPackageSearchResult * self, PyObject * args, PyObject * kw);
|
||||
static void PyPackageSearchResult_init_from_handle (PyPackageSearchResult * self, FridaPackageSearchResult * handle);
|
||||
static void PyPackageSearchResult_dealloc (PyPackageSearchResult * self);
|
||||
static PyObject * PyPackageSearchResult_repr (PyPackageSearchResult * self);
|
||||
|
||||
static PyObject * PyPackageInstallResult_new_take_handle (FridaPackageInstallResult * handle);
|
||||
static int PyPackageInstallResult_init (PyPackageInstallResult * self, PyObject * args, PyObject * kw);
|
||||
static void PyPackageInstallResult_init_from_handle (PyPackageInstallResult * self, FridaPackageInstallResult * handle);
|
||||
static void PyPackageInstallResult_dealloc (PyPackageInstallResult * self);
|
||||
static PyObject * PyPackageInstallResult_repr (PyPackageInstallResult * self);
|
||||
|
||||
static int PyFileMonitor_init (PyFileMonitor * self, PyObject * args, PyObject * kw);
|
||||
static void PyFileMonitor_dealloc (PyFileMonitor * self);
|
||||
static PyObject * PyFileMonitor_enable (PyFileMonitor * self);
|
||||
static PyObject * PyFileMonitor_disable (PyFileMonitor * self);
|
||||
|
||||
@@ -776,6 +786,12 @@ static PyMethodDef PyCompiler_methods[] =
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static PyGetSetDef PyPackageManager_getset[] =
|
||||
{
|
||||
{ "registry", (getter) PyPackageManager_get_registry, (setter) PyPackageManager_set_registry, "The registry to use.", NULL },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static PyMethodDef PyPackageManager_methods[] =
|
||||
{
|
||||
{ "search", (PyCFunction) PyPackageManager_search, METH_VARARGS | METH_KEYWORDS, "Search for packages to install." },
|
||||
@@ -953,12 +969,16 @@ PYFRIDA_DEFINE_TYPE ("_frida.EndpointParameters", EndpointParameters, GObject, N
|
||||
PYFRIDA_DEFINE_TYPE ("_frida.Compiler", Compiler, GObject, NULL, frida_unref,
|
||||
{ Py_tp_doc, "Frida Compiler" },
|
||||
{ Py_tp_init, PyCompiler_init },
|
||||
{ Py_tp_dealloc, PyCompiler_dealloc },
|
||||
{ Py_tp_methods, PyCompiler_methods },
|
||||
);
|
||||
|
||||
PYFRIDA_DEFINE_TYPE ("_frida.PackageManager", PackageManager, GObject, NULL, frida_unref,
|
||||
{ Py_tp_doc, "Frida Package Manager" },
|
||||
{ Py_tp_init, PyPackageManager_init },
|
||||
{ Py_tp_dealloc, PyPackageManager_dealloc },
|
||||
{ Py_tp_repr, PyPackageManager_repr },
|
||||
{ Py_tp_getset, PyPackageManager_getset },
|
||||
{ Py_tp_methods, PyPackageManager_methods },
|
||||
);
|
||||
|
||||
@@ -966,6 +986,7 @@ PYFRIDA_DEFINE_TYPE ("_frida.Package", Package, GObject, PyPackage_init_from_han
|
||||
{ Py_tp_doc, "Frida Package" },
|
||||
{ Py_tp_init, PyPackage_init },
|
||||
{ Py_tp_dealloc, PyPackage_dealloc },
|
||||
{ Py_tp_repr, PyPackage_repr },
|
||||
{ Py_tp_members, PyPackage_members },
|
||||
);
|
||||
|
||||
@@ -973,6 +994,7 @@ PYFRIDA_DEFINE_TYPE ("_frida.PackageSearchResult", PackageSearchResult, GObject,
|
||||
{ Py_tp_doc, "Frida Package Search Result" },
|
||||
{ Py_tp_init, PyPackageSearchResult_init },
|
||||
{ Py_tp_dealloc, PyPackageSearchResult_dealloc },
|
||||
{ Py_tp_repr, PyPackageSearchResult_repr },
|
||||
{ Py_tp_members, PyPackageSearchResult_members },
|
||||
);
|
||||
|
||||
@@ -980,12 +1002,14 @@ PYFRIDA_DEFINE_TYPE ("_frida.PackageInstallResult", PackageInstallResult, GObjec
|
||||
{ Py_tp_doc, "Frida Package Install Result" },
|
||||
{ Py_tp_init, PyPackageInstallResult_init },
|
||||
{ Py_tp_dealloc, PyPackageInstallResult_dealloc },
|
||||
{ Py_tp_repr, PyPackageInstallResult_repr },
|
||||
{ Py_tp_members, PyPackageInstallResult_members },
|
||||
);
|
||||
|
||||
PYFRIDA_DEFINE_TYPE ("_frida.FileMonitor", FileMonitor, GObject, NULL, frida_unref,
|
||||
{ Py_tp_doc, "Frida File Monitor" },
|
||||
{ Py_tp_init, PyFileMonitor_init },
|
||||
{ Py_tp_dealloc, PyFileMonitor_dealloc },
|
||||
{ Py_tp_methods, PyFileMonitor_methods },
|
||||
);
|
||||
|
||||
@@ -4861,11 +4885,21 @@ PyCompiler_init (PyCompiler * self, PyObject * args, PyObject * kw)
|
||||
if (PyGObject_tp_init ((PyObject *) self, args, kw) < 0)
|
||||
return -1;
|
||||
|
||||
g_atomic_int_inc (&toplevel_objects_alive);
|
||||
|
||||
PyGObject_take_handle (&self->parent, frida_compiler_new (NULL), PYFRIDA_TYPE (Compiler));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
PyCompiler_dealloc (PyCompiler * self)
|
||||
{
|
||||
g_atomic_int_dec_and_test (&toplevel_objects_alive);
|
||||
|
||||
PyGObject_tp_dealloc ((PyObject *) self);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
PyCompiler_build (PyCompiler * self, PyObject * args, PyObject * kw)
|
||||
{
|
||||
@@ -5022,11 +5056,53 @@ PyPackageManager_init (PyPackageManager * self, PyObject * args, PyObject * kw)
|
||||
if (PyGObject_tp_init ((PyObject *) self, args, kw) < 0)
|
||||
return -1;
|
||||
|
||||
g_atomic_int_inc (&toplevel_objects_alive);
|
||||
|
||||
PyGObject_take_handle (&self->parent, frida_package_manager_new (), PYFRIDA_TYPE (PackageManager));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
PyPackageManager_dealloc (PyPackageManager * self)
|
||||
{
|
||||
g_atomic_int_dec_and_test (&toplevel_objects_alive);
|
||||
|
||||
PyGObject_tp_dealloc ((PyObject *) self);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
PyPackageManager_repr (PyPackageManager * self)
|
||||
{
|
||||
PyObject * result;
|
||||
gchar * repr;
|
||||
|
||||
repr = g_strdup_printf ("PackageManager(registry=\"%s\")", frida_package_manager_get_registry (PY_GOBJECT_HANDLE (self)));
|
||||
result = PyUnicode_FromString (repr);
|
||||
g_free (repr);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
PyPackageManager_get_registry (PyPackageManager * self, void * closure)
|
||||
{
|
||||
return PyUnicode_FromString (frida_package_manager_get_registry (PY_GOBJECT_HANDLE (self)));
|
||||
}
|
||||
|
||||
static int
|
||||
PyPackageManager_set_registry (PyPackageManager * self, PyObject * val, void * closure)
|
||||
{
|
||||
gchar * registry;
|
||||
|
||||
if (!PyGObject_unmarshal_string (val, ®istry))
|
||||
return -1;
|
||||
frida_package_manager_set_registry (PY_GOBJECT_HANDLE (self), registry);
|
||||
g_free (registry);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
PyPackageManager_search (PyPackageManager * self, PyObject * args, PyObject * kw)
|
||||
{
|
||||
@@ -5065,16 +5141,18 @@ static PyObject *
|
||||
PyPackageManager_install (PyPackageManager * self, PyObject * args, PyObject * kw)
|
||||
{
|
||||
FridaPackageInstallResult * result;
|
||||
static char * keywords[] = { "project_root", "specs", NULL };
|
||||
static char * keywords[] = { "project_root", "role", "specs", "omits", NULL };
|
||||
const char * project_root = NULL;
|
||||
const char * role_value = NULL;
|
||||
PyObject * specs = NULL;
|
||||
PyObject * omits = NULL;
|
||||
FridaPackageInstallOptions * options;
|
||||
GError * error = NULL;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords (args, kw, "|sO", keywords, &project_root, &specs))
|
||||
if (!PyArg_ParseTupleAndKeywords (args, kw, "|ssOO", keywords, &project_root, &role_value, &specs, &omits))
|
||||
return NULL;
|
||||
|
||||
options = PyPackageManager_parse_install_options (project_root, specs);
|
||||
options = PyPackageManager_parse_install_options (project_root, role_value, specs, omits);
|
||||
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
result = frida_package_manager_install_sync (PY_GOBJECT_HANDLE (self), options, g_cancellable_get_current (), &error);
|
||||
@@ -5089,7 +5167,7 @@ PyPackageManager_install (PyPackageManager * self, PyObject * args, PyObject * k
|
||||
}
|
||||
|
||||
static FridaPackageInstallOptions *
|
||||
PyPackageManager_parse_install_options (const gchar * project_root, PyObject * specs_value)
|
||||
PyPackageManager_parse_install_options (const gchar * project_root, const char * role_value, PyObject * specs_value, PyObject * omits_value)
|
||||
{
|
||||
FridaPackageInstallOptions * options;
|
||||
|
||||
@@ -5098,6 +5176,16 @@ PyPackageManager_parse_install_options (const gchar * project_root, PyObject * s
|
||||
if (project_root != NULL)
|
||||
frida_package_install_options_set_project_root (options, project_root);
|
||||
|
||||
if (role_value != NULL)
|
||||
{
|
||||
FridaPackageRole role;
|
||||
|
||||
if (!PyGObject_unmarshal_enum (role_value, FRIDA_TYPE_PACKAGE_ROLE, &role))
|
||||
goto propagate_error;
|
||||
|
||||
frida_package_install_options_set_role (options, role);
|
||||
}
|
||||
|
||||
if (specs_value != NULL)
|
||||
{
|
||||
gint n, i;
|
||||
@@ -5123,6 +5211,35 @@ PyPackageManager_parse_install_options (const gchar * project_root, PyObject * s
|
||||
}
|
||||
}
|
||||
|
||||
if (omits_value != NULL)
|
||||
{
|
||||
gint n, i;
|
||||
|
||||
n = PySequence_Size (omits_value);
|
||||
if (n == -1)
|
||||
goto propagate_error;
|
||||
|
||||
for (i = 0; i != n; i++)
|
||||
{
|
||||
PyObject * element;
|
||||
gchar * str = NULL;
|
||||
FridaPackageRole role;
|
||||
|
||||
element = PySequence_GetItem (omits_value, i);
|
||||
if (element == NULL)
|
||||
goto propagate_error;
|
||||
PyGObject_unmarshal_string (element, &str);
|
||||
Py_DecRef (element);
|
||||
if (str == NULL)
|
||||
goto propagate_error;
|
||||
|
||||
if (!PyGObject_unmarshal_enum (str, FRIDA_TYPE_PACKAGE_ROLE, &role))
|
||||
goto propagate_error;
|
||||
|
||||
frida_package_install_options_add_omit (options, role);
|
||||
}
|
||||
}
|
||||
|
||||
return options;
|
||||
|
||||
propagate_error:
|
||||
@@ -5174,6 +5291,43 @@ PyPackage_dealloc (PyPackage * self)
|
||||
PyGObject_tp_dealloc ((PyObject *) self);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
PyPackage_repr (PyPackage * self)
|
||||
{
|
||||
PyObject * result;
|
||||
FridaPackage * handle;
|
||||
GString * repr;
|
||||
const gchar * description, * url;
|
||||
|
||||
handle = PY_GOBJECT_HANDLE (self);
|
||||
|
||||
repr = g_string_sized_new (256);
|
||||
|
||||
g_string_append_printf (repr, "Package(name=\"%s\", version=\"%s\"",
|
||||
frida_package_get_name (handle),
|
||||
frida_package_get_version (handle));
|
||||
|
||||
description = frida_package_get_description (handle);
|
||||
if (description != NULL)
|
||||
{
|
||||
gchar * escaped = g_strescape (description, NULL);
|
||||
g_string_append_printf (repr, ", description=\"%s\"", escaped);
|
||||
g_free (escaped);
|
||||
}
|
||||
|
||||
url = frida_package_get_url (handle);
|
||||
if (url != NULL)
|
||||
g_string_append_printf (repr, ", url=\"%s\"", url);
|
||||
|
||||
g_string_append (repr, ")");
|
||||
|
||||
result = PyUnicode_FromString (repr->str);
|
||||
|
||||
g_string_free (repr, TRUE);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static PyObject *
|
||||
PyPackageList_marshal (FridaPackageList * list)
|
||||
@@ -5223,6 +5377,30 @@ PyPackageSearchResult_dealloc (PyPackageSearchResult * self)
|
||||
PyGObject_tp_dealloc ((PyObject *) self);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
PyPackageSearchResult_repr (PyPackageSearchResult * self)
|
||||
{
|
||||
PyObject * result;
|
||||
GString * repr;
|
||||
gint num_packages;
|
||||
|
||||
repr = g_string_new ("PackageSearchResult(packages=");
|
||||
|
||||
num_packages = frida_package_list_size (frida_package_search_result_get_packages (PY_GOBJECT_HANDLE (self)));
|
||||
if (num_packages != 0)
|
||||
g_string_append_printf (repr, "[<%u package%s>]", num_packages, (num_packages == 1) ? "" : "s");
|
||||
else
|
||||
g_string_append (repr, "[]");
|
||||
|
||||
g_string_append_printf (repr, ", total=%u)", self->total);
|
||||
|
||||
result = PyUnicode_FromString (repr->str);
|
||||
|
||||
g_string_free (repr, TRUE);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static PyObject *
|
||||
PyPackageInstallResult_new_take_handle (FridaPackageInstallResult * handle)
|
||||
@@ -5255,6 +5433,30 @@ PyPackageInstallResult_dealloc (PyPackageInstallResult * self)
|
||||
PyGObject_tp_dealloc ((PyObject *) self);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
PyPackageInstallResult_repr (PyPackageInstallResult * self)
|
||||
{
|
||||
PyObject * result;
|
||||
GString * repr;
|
||||
gint num_packages;
|
||||
|
||||
repr = g_string_new ("PackageInstallResult(packages=");
|
||||
|
||||
num_packages = frida_package_list_size (frida_package_install_result_get_packages (PY_GOBJECT_HANDLE (self)));
|
||||
if (num_packages != 0)
|
||||
g_string_append_printf (repr, "[<%u package%s>]", num_packages, (num_packages == 1) ? "" : "s");
|
||||
else
|
||||
g_string_append (repr, "[]");
|
||||
|
||||
g_string_append (repr, ")");
|
||||
|
||||
result = PyUnicode_FromString (repr->str);
|
||||
|
||||
g_string_free (repr, TRUE);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
PyFileMonitor_init (PyFileMonitor * self, PyObject * args, PyObject * kw)
|
||||
@@ -5267,11 +5469,21 @@ PyFileMonitor_init (PyFileMonitor * self, PyObject * args, PyObject * kw)
|
||||
if (!PyArg_ParseTuple (args, "s", &path))
|
||||
return -1;
|
||||
|
||||
g_atomic_int_inc (&toplevel_objects_alive);
|
||||
|
||||
PyGObject_take_handle (&self->parent, frida_file_monitor_new (path), PYFRIDA_TYPE (FileMonitor));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
PyFileMonitor_dealloc (PyFileMonitor * self)
|
||||
{
|
||||
g_atomic_int_dec_and_test (&toplevel_objects_alive);
|
||||
|
||||
PyGObject_tp_dealloc ((PyObject *) self);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
PyFileMonitor_enable (PyFileMonitor * self)
|
||||
{
|
||||
|
||||
+14
-5
@@ -1649,16 +1649,11 @@ PackageManagerInstallProgressCallback = Callable[
|
||||
"initializing",
|
||||
"preparing-dependencies",
|
||||
"resolving-package",
|
||||
"using-lockfile-data",
|
||||
"metadata-fetched",
|
||||
"fetching-resource",
|
||||
"package-already-installed",
|
||||
"downloading-package",
|
||||
"package-installed",
|
||||
"resolving-and-installing-all",
|
||||
"awaiting-completion",
|
||||
"dependencies-processed",
|
||||
"finalizing-manifests",
|
||||
"complete",
|
||||
],
|
||||
float,
|
||||
@@ -1667,6 +1662,8 @@ PackageManagerInstallProgressCallback = Callable[
|
||||
None,
|
||||
]
|
||||
|
||||
PackageRole = Literal["runtime", "development", "optional", "peer"]
|
||||
|
||||
|
||||
class PackageManager:
|
||||
def __init__(self) -> None:
|
||||
@@ -1675,6 +1672,14 @@ class PackageManager:
|
||||
def __repr__(self) -> str:
|
||||
return repr(self._impl)
|
||||
|
||||
@property
|
||||
def registry(self):
|
||||
return self._impl.registry
|
||||
|
||||
@registry.setter
|
||||
def registry(self, value):
|
||||
self._impl.registry = value
|
||||
|
||||
@cancellable
|
||||
def search(
|
||||
self,
|
||||
@@ -1693,11 +1698,15 @@ class PackageManager:
|
||||
def install(
|
||||
self,
|
||||
project_root: Optional[str] = None,
|
||||
role: Optional[PackageRole] = None,
|
||||
specs: Optional[Sequence[str]] = None,
|
||||
omits: Optional[Sequence[PackageRole]] = None,
|
||||
) -> _frida.PackageInstallResult:
|
||||
kwargs: Dict[str, Any] = {
|
||||
"project_root": project_root,
|
||||
"role": role,
|
||||
"specs": specs,
|
||||
"omits": omits,
|
||||
}
|
||||
_filter_missing_kwargs(kwargs)
|
||||
return self._impl.install(**kwargs)
|
||||
|
||||
+1
-1
Submodule releng updated: e10baa39a2...2b34e1c008
@@ -1,6 +1,6 @@
|
||||
[wrap-git]
|
||||
url = https://github.com/frida/frida-core.git
|
||||
revision = 17.2.0
|
||||
revision = 17.2.15
|
||||
depth = 1
|
||||
|
||||
[provide]
|
||||
|
||||
Reference in New Issue
Block a user