mirror of
https://github.com/Stone-Red-Code/dvc.git
synced 2026-11-08 23:09:48 +01:00
analytics: collect and send on daemon
This commit is contained in:
+5
-8
@@ -14,18 +14,18 @@ from dvc.lock import Lock, LockError
|
||||
from dvc.repo import Repo
|
||||
from dvc.scm import SCM
|
||||
from dvc.utils import env2bool, is_binary, makedirs
|
||||
from dvc.utils.compat import str, FileNotFoundError, fspath_py35
|
||||
from dvc.utils.compat import str, FileNotFoundError
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def collect(args=None, return_code=None):
|
||||
def collect(cmd_class=None, return_code=None):
|
||||
"""
|
||||
Query the system to fill a report.
|
||||
"""
|
||||
return {
|
||||
"cmd_class": args.func.__name__ if hasattr(args, "func") else None,
|
||||
"cmd_class": cmd_class,
|
||||
"cmd_return_code": return_code,
|
||||
"dvc_version": __version__,
|
||||
"is_binary": is_binary(),
|
||||
@@ -50,12 +50,9 @@ def is_enabled():
|
||||
return enabled
|
||||
|
||||
|
||||
def send(path):
|
||||
def send(report):
|
||||
url = "https://analytics.dvc.org"
|
||||
headers = {"content-type": "application/json"}
|
||||
|
||||
with open(fspath_py35(path)) as fobj:
|
||||
requests.post(url, data=fobj, headers=headers, timeout=5)
|
||||
requests.post(url, json=report, timeout=5)
|
||||
|
||||
|
||||
def scm_in_use():
|
||||
|
||||
+10
-4
@@ -25,10 +25,11 @@ class CmdDaemonUpdater(CmdDaemonBase):
|
||||
|
||||
class CmdDaemonAnalytics(CmdDaemonBase):
|
||||
def run(self):
|
||||
"""Collect and send analytics"""
|
||||
from dvc import analytics
|
||||
|
||||
analytics.send(self.args.target)
|
||||
os.remove(self.args.target)
|
||||
report = analytics.collect(self.args.cmd_class, self.args.ret)
|
||||
analytics.send(report)
|
||||
|
||||
return 0
|
||||
|
||||
@@ -57,12 +58,17 @@ def add_parser(subparsers, parent_parser):
|
||||
)
|
||||
daemon_updater_parser.set_defaults(func=CmdDaemonUpdater)
|
||||
|
||||
DAEMON_ANALYTICS_HELP = "Send dvc usage analytics."
|
||||
DAEMON_ANALYTICS_HELP = "Collect and send dvc usage analytics."
|
||||
daemon_analytics_parser = daemon_subparsers.add_parser(
|
||||
"analytics",
|
||||
parents=[parent_parser],
|
||||
description=DAEMON_ANALYTICS_HELP,
|
||||
help=DAEMON_ANALYTICS_HELP,
|
||||
)
|
||||
daemon_analytics_parser.add_argument("target", help="Analytics file.")
|
||||
daemon_analytics_parser.add_argument(
|
||||
"cmd_class", help="Class called through main"
|
||||
)
|
||||
daemon_analytics_parser.add_argument(
|
||||
"ret", help="Return code from running such class"
|
||||
)
|
||||
daemon_analytics_parser.set_defaults(func=CmdDaemonAnalytics)
|
||||
|
||||
+3
-9
@@ -1,9 +1,7 @@
|
||||
"""Main entry point for dvc CLI."""
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import json
|
||||
import logging
|
||||
import tempfile
|
||||
|
||||
from dvc import analytics
|
||||
from dvc.cli import parse_args
|
||||
@@ -85,12 +83,8 @@ def main(argv=None):
|
||||
logger.info(FOOTER)
|
||||
|
||||
if analytics.is_enabled():
|
||||
report = analytics.collect(args, ret)
|
||||
|
||||
# Use a temporary file to pass the report between the current and
|
||||
# detached process.
|
||||
with tempfile.NamedTemporaryFile(delete=False, mode="w") as fobj:
|
||||
json.dump(report, fobj)
|
||||
daemon(["analytics", fobj.name])
|
||||
# Include the command class and return code on the analytics report
|
||||
cmd_class = args.func.__name__ if hasattr(args, "func") else None
|
||||
daemon(["analytics", cmd_class, ret])
|
||||
|
||||
return ret
|
||||
|
||||
@@ -1,15 +1,9 @@
|
||||
import mock
|
||||
import json
|
||||
|
||||
from dvc.main import main
|
||||
from dvc.utils.compat import fspath
|
||||
|
||||
|
||||
@mock.patch("dvc.analytics.send")
|
||||
def test_daemon_analytics(mock_send, tmp_path):
|
||||
report = {"name": "dummy report"}
|
||||
fname = tmp_path / "report"
|
||||
fname.write_text(str(json.dumps(report)))
|
||||
|
||||
assert 0 == main(["daemon", "analytics", fspath(fname)])
|
||||
assert 0 == main(["daemon", "analytics", None, 0])
|
||||
assert mock_send.called
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import json
|
||||
import pytest
|
||||
import mock
|
||||
|
||||
@@ -40,12 +39,9 @@ def test_collect(tmp_global_config):
|
||||
def test_send(mock_post, tmp_path):
|
||||
url = "https://analytics.dvc.org"
|
||||
report = {"name": "dummy report"}
|
||||
fname = tmp_path / "report"
|
||||
|
||||
fname.write_text(str(json.dumps(report)))
|
||||
analytics.send(fname)
|
||||
assert mock_post.called
|
||||
assert mock_post.call_args.args[0] == url
|
||||
analytics.send(report)
|
||||
mock_post.assert_called_with(url, json=report, timeout=5)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
||||
Reference in New Issue
Block a user