Skip to content

Commit

Permalink
Add command to create new integrations
Browse files Browse the repository at this point in the history
  • Loading branch information
ofek committed Aug 13, 2018
1 parent c3787b7 commit 6743846
Show file tree
Hide file tree
Showing 15 changed files with 662 additions and 0 deletions.
14 changes: 14 additions & 0 deletions datadog_checks_dev/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ and is available on Linux, macOS, and Windows, and supports Python 2.7/3.5+ and
- [Set](#set)
- [Show](#show)
- [Update](#update)
- [Create](#create)
- [Dep](#dep)
- [Freeze](#freeze)
- [Pin](#pin)
Expand Down Expand Up @@ -217,6 +218,19 @@ Options:
-h, --help Show this message and exit.
```

#### Create

```console
$ ddev create -h
Usage: ddev create [OPTIONS] NAME

Create a new integration.

Options:
-n, --dry-run Only show what would be created
-h, --help Show this message and exit.
```

#### Dep

```console
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# Licensed under a 3-clause BSD style license (see LICENSE)
from .clean import clean
from .config import config
from .create import create
from .dep import dep
from .manifest import manifest
from .release import release
Expand All @@ -11,6 +12,7 @@
ALL_COMMANDS = (
clean,
config,
create,
dep,
manifest,
release,
Expand Down
128 changes: 128 additions & 0 deletions datadog_checks_dev/datadog_checks/dev/tooling/commands/create.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# (C) Datadog, Inc. 2018
# All rights reserved
# Licensed under a 3-clause BSD style license (see LICENSE)
import os
from collections import defaultdict

import click

from .utils import CONTEXT_SETTINGS, abort, echo_info, echo_success
from ..constants import get_root
from ..files import CHECK_FILES
from ..utils import normalize_package_name

HYPHEN = b'\xe2\x94\x80\xe2\x94\x80'.decode('utf-8')
PIPE = b'\xe2\x94\x82'.decode('utf-8')
PIPE_MIDDLE = b'\xe2\x94\x9c'.decode('utf-8')
PIPE_END = b'\xe2\x94\x94'.decode('utf-8')


def tree():
return defaultdict(tree)


def construct_output_info(path, depth, last, is_dir=False):
if depth == 0:
return u'', path, is_dir
else:
if depth == 1:
return (
u'{}{} '.format(
PIPE_END if last else PIPE_MIDDLE, HYPHEN
),
path,
is_dir
)
else:
return (
u'{} {}{}'.format(
PIPE,
u' ' * 4 * (depth - 2),
u'{}{} '.format(PIPE_END if last or is_dir else PIPE_MIDDLE, HYPHEN)
),
path,
is_dir
)


def path_tree_output(path_tree, depth=0):
# Avoid possible imposed recursion limits by using a generator.
# See https://en.wikipedia.org/wiki/Trampoline_(computing)
dirs = []
files = []

for path in path_tree:
if len(path_tree[path]) > 0:
dirs.append(path)
else:
files.append(path)

dirs.sort()
length = len(dirs)

for i, path in enumerate(dirs, 1):
yield construct_output_info(path, depth, last=i == length and not files, is_dir=True)

for info in path_tree_output(path_tree[path], depth + 1):
yield info

files.sort()
length = len(files)

for i, path in enumerate(files, 1):
yield construct_output_info(path, depth, last=i == length)


def display_path_tree(path_tree):
for indent, path, is_dir in path_tree_output(path_tree):
if indent:
echo_info(indent, nl=False)

if is_dir:
echo_success(path)
else:
echo_info(path)


@click.command(context_settings=CONTEXT_SETTINGS, short_help='Create a new integration')
@click.argument('name')
@click.option('--dry-run', '-n', is_flag=True, help='Only show what would be created')
@click.pass_context
def create(ctx, name, dry_run):
"""Create a new integration."""
check_name = normalize_package_name(name)
root = get_root()
path_sep = os.path.sep

check_dir = os.path.join(root, check_name)
if os.path.exists(check_dir):
abort('Path `{}` already exists!'.format(check_dir))

config = {
'root': check_dir,
'check_name': check_name,
'check_name_cap': check_name.capitalize(),
'check_class': '{}Check'.format(''.join(part.capitalize() for part in check_name.split('_'))),
'repo_choice': ctx.obj['repo_choice'],
}

files = [file(config) for file in CHECK_FILES]
file_paths = [file.file_path.replace('{}{}'.format(root, path_sep), '', 1) for file in files]

path_tree = tree()
for file_path in file_paths:
branch = path_tree

for part in file_path.split(path_sep):
branch = branch[part]

if dry_run:
echo_info('Will create in `{}`:'.format(root))
display_path_tree(path_tree)
return

for file in files:
file.write()

echo_info('Created in `{}`:'.format(root))
display_path_tree(path_tree)
35 changes: 35 additions & 0 deletions datadog_checks_dev/datadog_checks/dev/tooling/files/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# (C) Datadog, Inc. 2018
# All rights reserved
# Licensed under a 3-clause BSD style license (see LICENSE)
from .changelog import Changelog
from .example import ExampleConf
from .manifest import ManifestIn, ManifestJson
from .metadata import MetadataCsv
from .package import PackageAbout, PackageCheck, PackageInit, PackageNamespace
from .readme import Readme
from .reqs import ReqsDevTxt, ReqsIn, ReqsTxt
from .setup import Setup
from .test import TestCheck, TestConf, TestInit
from .tox import Tox


CHECK_FILES = (
Changelog,
ExampleConf,
ManifestIn,
ManifestJson,
MetadataCsv,
PackageAbout,
PackageCheck,
PackageInit,
PackageNamespace,
Readme,
ReqsDevTxt,
ReqsIn,
ReqsTxt,
Setup,
TestCheck,
TestConf,
TestInit,
Tox,
)
21 changes: 21 additions & 0 deletions datadog_checks_dev/datadog_checks/dev/tooling/files/changelog.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# (C) Datadog, Inc. 2018
# All rights reserved
# Licensed under a 3-clause BSD style license (see LICENSE)
import os

from .utils import File

TEMPLATE = """\
# CHANGELOG - {check_name_cap}
"""


class Changelog(File):
def __init__(self, config):
super(Changelog, self).__init__(
os.path.join(config['root'], 'CHANGELOG.md'),
TEMPLATE.format(
check_name_cap=config['check_name_cap'],
)
)
21 changes: 21 additions & 0 deletions datadog_checks_dev/datadog_checks/dev/tooling/files/example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# (C) Datadog, Inc. 2018
# All rights reserved
# Licensed under a 3-clause BSD style license (see LICENSE)
import os

from .utils import File

TEMPLATE = """\
init_config:
instances:
- {}
"""


class ExampleConf(File):
def __init__(self, config):
super(ExampleConf, self).__init__(
os.path.join(config['root'], 'datadog_checks', config['check_name'], 'data', 'conf.yaml.example'),
TEMPLATE
)
78 changes: 78 additions & 0 deletions datadog_checks_dev/datadog_checks/dev/tooling/files/manifest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# (C) Datadog, Inc. 2018
# All rights reserved
# Licensed under a 3-clause BSD style license (see LICENSE)
import os
import uuid

from .utils import File

TEMPLATE_IN = """\
graft datadog_checks
graft tests
include MANIFEST.in
include README.md
include requirements.in
include requirements.txt
include requirements-dev.txt
include manifest.json
global-exclude *.py[cod] __pycache__
"""

TEMPLATE_JSON = """\
{{
"display_name": "{check_name_cap}",
"maintainer": "{maintainer}",
"manifest_version": "1.0.0",
"name": "{check_name}",
"metric_prefix": "{check_name}.",
"metric_to_check": "",
"creates_events": false,
"short_description": "",
"guid": "{guid}",
"support": "{support_type}",
"supported_os": [
"linux",
"mac_os",
"windows"
],
"public_title": "Datadog-{check_name_cap} Integration",
"categories": [
""
],
"type": "check",
"doc_link": "https://docs.datadoghq.com/integrations/{check_name}/",
"is_public": true,
"has_logo": true
}}
"""


class ManifestIn(File):
def __init__(self, config):
super(ManifestIn, self).__init__(
os.path.join(config['root'], 'MANIFEST.in'),
TEMPLATE_IN
)


class ManifestJson(File):
def __init__(self, config):
if config['repo_choice'] == 'core':
maintainer = 'help@datadoghq.com'
support_type = 'core'
else:
maintainer = ''
support_type = 'contrib'

super(ManifestJson, self).__init__(
os.path.join(config['root'], 'manifest.json'),
TEMPLATE_JSON.format(
check_name=config['check_name'],
check_name_cap=config['check_name_cap'],
maintainer=maintainer,
support_type=support_type,
guid=uuid.uuid4(),
)
)
18 changes: 18 additions & 0 deletions datadog_checks_dev/datadog_checks/dev/tooling/files/metadata.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# (C) Datadog, Inc. 2018
# All rights reserved
# Licensed under a 3-clause BSD style license (see LICENSE)
import os

from .utils import File

TEMPLATE = """\
metric_name,metric_type,interval,unit_name,per_unit_name,description,orientation,integration,short_name
"""


class MetadataCsv(File):
def __init__(self, config):
super(MetadataCsv, self).__init__(
os.path.join(config['root'], 'metadata.csv'),
TEMPLATE
)
Loading

0 comments on commit 6743846

Please sign in to comment.