Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions samcli/commands/build/build_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,8 +270,6 @@ def run(self):

for f in self.get_resources_to_build().functions:
EventTracker.track_event("BuildFunctionRuntime", f.runtime)
if f.metadata and f.metadata.get("BuildMethod", "") == "esbuild":
EventTracker.track_event("UsedFeature", "ESBuild")

click.secho("\nBuild Succeeded", fg="green")

Expand Down
102 changes: 17 additions & 85 deletions samcli/lib/build/workflow_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,95 +4,24 @@

import os
import logging
from collections import namedtuple
from typing import Dict, List, Optional, Tuple, Union, cast

LOG = logging.getLogger(__name__)

CONFIG = namedtuple(
"Capability",
["language", "dependency_manager", "application_framework", "manifest_name", "executable_search_paths"],
)

PYTHON_PIP_CONFIG = CONFIG(
language="python",
dependency_manager="pip",
application_framework=None,
manifest_name="requirements.txt",
executable_search_paths=None,
)

NODEJS_NPM_CONFIG = CONFIG(
language="nodejs",
dependency_manager="npm",
application_framework=None,
manifest_name="package.json",
executable_search_paths=None,
)

RUBY_BUNDLER_CONFIG = CONFIG(
language="ruby",
dependency_manager="bundler",
application_framework=None,
manifest_name="Gemfile",
executable_search_paths=None,
)

JAVA_GRADLE_CONFIG = CONFIG(
language="java",
dependency_manager="gradle",
application_framework=None,
manifest_name="build.gradle",
executable_search_paths=None,
)

JAVA_KOTLIN_GRADLE_CONFIG = CONFIG(
language="java",
dependency_manager="gradle",
application_framework=None,
manifest_name="build.gradle.kts",
executable_search_paths=None,
from samcli.lib.build.workflows import (
CONFIG,
PYTHON_PIP_CONFIG,
NODEJS_NPM_CONFIG,
RUBY_BUNDLER_CONFIG,
JAVA_GRADLE_CONFIG,
JAVA_KOTLIN_GRADLE_CONFIG,
JAVA_MAVEN_CONFIG,
DOTNET_CLIPACKAGE_CONFIG,
GO_MOD_CONFIG,
PROVIDED_MAKE_CONFIG,
NODEJS_NPM_ESBUILD_CONFIG,
)
from samcli.lib.telemetry.event import EventTracker

JAVA_MAVEN_CONFIG = CONFIG(
language="java",
dependency_manager="maven",
application_framework=None,
manifest_name="pom.xml",
executable_search_paths=None,
)

DOTNET_CLIPACKAGE_CONFIG = CONFIG(
language="dotnet",
dependency_manager="cli-package",
application_framework=None,
manifest_name=".csproj",
executable_search_paths=None,
)

GO_MOD_CONFIG = CONFIG(
language="go",
dependency_manager="modules",
application_framework=None,
manifest_name="go.mod",
executable_search_paths=None,
)

PROVIDED_MAKE_CONFIG = CONFIG(
language="provided",
dependency_manager=None,
application_framework=None,
manifest_name="Makefile",
executable_search_paths=None,
)

NODEJS_NPM_ESBUILD_CONFIG = CONFIG(
language="nodejs",
dependency_manager="npm-esbuild",
application_framework=None,
manifest_name="package.json",
executable_search_paths=None,
)
LOG = logging.getLogger(__name__)


class UnsupportedRuntimeException(Exception):
Expand Down Expand Up @@ -278,6 +207,9 @@ def get_workflow_config(

# Identify workflow configuration from the workflow selector.
config = cast(WorkFlowSelector, selector).get_config(code_dir, project_dir)

EventTracker.track_event("BuildWorkflowUsed", f"{config.language}-{config.dependency_manager}")

return config
except ValueError as ex:
raise UnsupportedRuntimeException(
Expand Down
102 changes: 102 additions & 0 deletions samcli/lib/build/workflows.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
"""Module for storing information about existing workflows."""

from collections import namedtuple
from typing import List

CONFIG = namedtuple(
"Capability",
["language", "dependency_manager", "application_framework", "manifest_name", "executable_search_paths"],
)

PYTHON_PIP_CONFIG = CONFIG(
language="python",
dependency_manager="pip",
application_framework=None,
manifest_name="requirements.txt",
executable_search_paths=None,
)

NODEJS_NPM_CONFIG = CONFIG(
language="nodejs",
dependency_manager="npm",
application_framework=None,
manifest_name="package.json",
executable_search_paths=None,
)

RUBY_BUNDLER_CONFIG = CONFIG(
language="ruby",
dependency_manager="bundler",
application_framework=None,
manifest_name="Gemfile",
executable_search_paths=None,
)

JAVA_GRADLE_CONFIG = CONFIG(
language="java",
dependency_manager="gradle",
application_framework=None,
manifest_name="build.gradle",
executable_search_paths=None,
)

JAVA_KOTLIN_GRADLE_CONFIG = CONFIG(
language="java",
dependency_manager="gradle",
application_framework=None,
manifest_name="build.gradle.kts",
executable_search_paths=None,
)

JAVA_MAVEN_CONFIG = CONFIG(
language="java",
dependency_manager="maven",
application_framework=None,
manifest_name="pom.xml",
executable_search_paths=None,
)

DOTNET_CLIPACKAGE_CONFIG = CONFIG(
language="dotnet",
dependency_manager="cli-package",
application_framework=None,
manifest_name=".csproj",
executable_search_paths=None,
)

GO_MOD_CONFIG = CONFIG(
language="go",
dependency_manager="modules",
application_framework=None,
manifest_name="go.mod",
executable_search_paths=None,
)

PROVIDED_MAKE_CONFIG = CONFIG(
language="provided",
dependency_manager=None,
application_framework=None,
manifest_name="Makefile",
executable_search_paths=None,
)

NODEJS_NPM_ESBUILD_CONFIG = CONFIG(
language="nodejs",
dependency_manager="npm-esbuild",
application_framework=None,
manifest_name="package.json",
executable_search_paths=None,
)

ALL_CONFIGS: List[CONFIG] = [
PYTHON_PIP_CONFIG,
NODEJS_NPM_CONFIG,
RUBY_BUNDLER_CONFIG,
JAVA_GRADLE_CONFIG,
JAVA_KOTLIN_GRADLE_CONFIG,
JAVA_MAVEN_CONFIG,
DOTNET_CLIPACKAGE_CONFIG,
GO_MOD_CONFIG,
PROVIDED_MAKE_CONFIG,
NODEJS_NPM_ESBUILD_CONFIG,
]
12 changes: 4 additions & 8 deletions samcli/lib/telemetry/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import threading
from typing import List

from samcli.lib.build.workflows import ALL_CONFIGS
from samcli.lib.telemetry.telemetry import Telemetry
from samcli.local.common.runtime_template import INIT_RUNTIMES

Expand All @@ -19,11 +20,11 @@ class EventName(Enum):
"""Enum for the names of available events to track."""

USED_FEATURE = "UsedFeature"
DEPLOY = "Deploy"
BUILD_FUNCTION_RUNTIME = "BuildFunctionRuntime"
SYNC_USED = "SyncUsed"
SYNC_FLOW_START = "SyncFlowStart"
SYNC_FLOW_END = "SyncFlowEnd"
BUILD_WORKFLOW_USED = "BuildWorkflowUsed"


class EventType:
Expand All @@ -43,25 +44,20 @@ class EventType:
"StepFunctionsSyncFlow",
"ZipFunctionSyncFlow",
]
_WORKFLOWS = [f"{config.language}-{config.dependency_manager}" for config in ALL_CONFIGS]
_events = {
EventName.USED_FEATURE: [
"ESBuild",
"Accelerate",
"CDK",
],
EventName.DEPLOY: [
"CreateChangeSetStart",
"CreateChangeSetInProgress",
"CreateChangeSetFailed",
"CreateChangeSetSuccess",
],
EventName.BUILD_FUNCTION_RUNTIME: INIT_RUNTIMES,
EventName.SYNC_USED: [
"Start",
"End",
],
EventName.SYNC_FLOW_START: _SYNC_FLOWS,
EventName.SYNC_FLOW_END: _SYNC_FLOWS,
EventName.BUILD_WORKFLOW_USED: _WORKFLOWS,
}

@staticmethod
Expand Down
17 changes: 17 additions & 0 deletions tests/unit/lib/build_module/test_workflow_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@
UnsupportedRuntimeException,
UnsupportedBuilderException,
)
from samcli.lib.telemetry.event import Event, EventTracker


class Test_get_workflow_config(TestCase):
def setUp(self):
self.code_dir = ""
self.project_dir = ""
EventTracker.clear_trackers()

@parameterized.expand([("python3.6",), ("python3.7",), ("python3.8",)])
def test_must_work_for_python(self, runtime):
Expand All @@ -23,6 +25,8 @@ def test_must_work_for_python(self, runtime):
self.assertEqual(result.application_framework, None)
self.assertEqual(result.manifest_name, "requirements.txt")
self.assertIsNone(result.executable_search_paths)
self.assertEqual(len(EventTracker.get_tracked_events()), 1)
self.assertIn(Event("BuildWorkflowUsed", "python-pip"), EventTracker.get_tracked_events())

@parameterized.expand([("nodejs12.x",), ("nodejs14.x",), ("nodejs16.x",)])
def test_must_work_for_nodejs(self, runtime):
Expand All @@ -33,6 +37,8 @@ def test_must_work_for_nodejs(self, runtime):
self.assertEqual(result.application_framework, None)
self.assertEqual(result.manifest_name, "package.json")
self.assertIsNone(result.executable_search_paths)
self.assertEqual(len(EventTracker.get_tracked_events()), 1)
self.assertIn(Event("BuildWorkflowUsed", "nodejs-npm"), EventTracker.get_tracked_events())

@parameterized.expand([("provided",)])
def test_must_work_for_provided(self, runtime):
Expand All @@ -42,6 +48,8 @@ def test_must_work_for_provided(self, runtime):
self.assertEqual(result.application_framework, None)
self.assertEqual(result.manifest_name, "Makefile")
self.assertIsNone(result.executable_search_paths)
self.assertEqual(len(EventTracker.get_tracked_events()), 1)
self.assertIn(Event("BuildWorkflowUsed", "provided-None"), EventTracker.get_tracked_events())

@parameterized.expand([("provided",)])
def test_must_work_for_provided_with_no_specified_workflow(self, runtime):
Expand All @@ -52,6 +60,8 @@ def test_must_work_for_provided_with_no_specified_workflow(self, runtime):
self.assertEqual(result.application_framework, None)
self.assertEqual(result.manifest_name, "Makefile")
self.assertIsNone(result.executable_search_paths)
self.assertEqual(len(EventTracker.get_tracked_events()), 1)
self.assertIn(Event("BuildWorkflowUsed", "provided-None"), EventTracker.get_tracked_events())

@parameterized.expand([("provided",)])
def test_raise_exception_for_bad_specified_workflow(self, runtime):
Expand All @@ -66,6 +76,8 @@ def test_must_work_for_ruby(self, runtime):
self.assertEqual(result.application_framework, None)
self.assertEqual(result.manifest_name, "Gemfile")
self.assertIsNone(result.executable_search_paths)
self.assertEqual(len(EventTracker.get_tracked_events()), 1)
self.assertIn(Event("BuildWorkflowUsed", "ruby-bundler"), EventTracker.get_tracked_events())

@parameterized.expand(
[("java8", "build.gradle", "gradle"), ("java8", "build.gradle.kts", "gradle"), ("java8", "pom.xml", "maven")]
Expand All @@ -80,11 +92,14 @@ def test_must_work_for_java(self, runtime, build_file, dep_manager, os_mock):
self.assertEqual(result.dependency_manager, dep_manager)
self.assertEqual(result.application_framework, None)
self.assertEqual(result.manifest_name, build_file)
self.assertEqual(len(EventTracker.get_tracked_events()), 1)

if dep_manager == "gradle":
self.assertEqual(result.executable_search_paths, [self.code_dir, self.project_dir])
self.assertIn(Event("BuildWorkflowUsed", "java-gradle"), EventTracker.get_tracked_events())
else:
self.assertIsNone(result.executable_search_paths)
self.assertIn(Event("BuildWorkflowUsed", "java-maven"), EventTracker.get_tracked_events())

def test_must_get_workflow_for_esbuild(self):
runtime = "nodejs12.x"
Expand All @@ -94,6 +109,8 @@ def test_must_get_workflow_for_esbuild(self):
self.assertEqual(result.application_framework, None)
self.assertEqual(result.manifest_name, "package.json")
self.assertIsNone(result.executable_search_paths)
self.assertEqual(len(EventTracker.get_tracked_events()), 1)
self.assertIn(Event("BuildWorkflowUsed", "nodejs-npm-esbuild"), EventTracker.get_tracked_events())

@parameterized.expand([("java8", "unknown.manifest")])
@patch("samcli.lib.build.workflow_config.os")
Expand Down
3 changes: 3 additions & 0 deletions tests/unit/lib/telemetry/test_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ def test_event_to_json(self, name_mock, type_mock, verify_mock):


class TestEventTracker(TestCase):
def setUp(self):
EventTracker.clear_trackers()

@patch("samcli.lib.telemetry.event.EventTracker._event_lock")
@patch("samcli.lib.telemetry.event.Event")
def test_track_event(self, event_mock, lock_mock):
Expand Down