Skip to content

Commit

Permalink
Use dataclass.
Browse files Browse the repository at this point in the history
Signed-off-by: dblock <dblock@amazon.com>
  • Loading branch information
dblock committed Aug 6, 2021
1 parent ac451d9 commit 1c594c9
Show file tree
Hide file tree
Showing 10 changed files with 208 additions and 176 deletions.
3 changes: 2 additions & 1 deletion tools/bundle-build/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
# intentionally left blank
# Copyright OpenSearch Contributors.
# SPDX-License-Identifier: Apache-2.0
23 changes: 14 additions & 9 deletions tools/bundle-build/build.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
# Copyright OpenSearch Contributors.
# SPDX-License-Identifier: Apache-2.0

import os
import sys
import tempfile
import urllib.request
from lib.manifest import BuildManifest
from lib.output import BuildOutput
from lib.build_manifest import BuildManifest
from lib.build_output import BuildOutput

if (len(sys.argv) < 2):
print("Build an OpenSearch Bundle")
Expand All @@ -12,17 +15,19 @@

with tempfile.TemporaryDirectory() as work_dir:
manifest = BuildManifest.from_file(sys.argv[1])
build = manifest.build()
build = manifest.build
output = BuildOutput()

print(f'Building {build.name()} ({output.arch()}) into {output.dest()}')
print(f'Building {build.name} ({output.arch}) into {output.dest} ...')

os.chdir(work_dir)

for component in manifest.components():
print(f'=== Building {component.name()} ...')
for component in manifest.components:
print(f'=== Building {component.name} ...')
component.checkout()
component.build(build.version(), output.arch())
component.export(output.dest())
component.build(build.version, output.arch)
component.export(output.dest)

manifest.save_to(os.path.join(output.dest(), 'manifest.yml'))
manifest_path = os.path.join(output.dest, 'manifest.yml')
manifest.save_to(manifest_path)
print(f'Done.')
4 changes: 4 additions & 0 deletions tools/bundle-build/build.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#!/bin/bash

# Copyright OpenSearch Contributors.
# SPDX-License-Identifier: Apache-2.0

set -e

DIR="$(dirname "$0")"
python3 "$DIR/build.py" $@
67 changes: 67 additions & 0 deletions tools/bundle-build/lib/build_manifest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Copyright OpenSearch Contributors.
# SPDX-License-Identifier: Apache-2.0

import yaml
import subprocess
from lib.component import Component
from dataclasses import dataclass
from typing import List

@dataclass
class Schema:
data: str
version: str = None

def __post_init__(self):
self.version = self.data['schema-version']
if self.version != 1:
raise ValueError(f'Unsupported schema version: {self.version}')

@dataclass
class Build:
data: str
name: str = None
version: str = None
dict: dict = None

def __post_init__(self):
self.name = self.data['name']
self.version = self.data['version']
self.__set_dict()

def __set_dict(self):
self.dict = {
'name': self.name,
'version': self.version
}

@dataclass
class BuildManifest:
data: str
schema: Schema = None
build: Build = None
components: List[Component] = None

@staticmethod
def from_file(path):
with open(path, 'r') as file:
return BuildManifest(yaml.safe_load(file))

def __post_init__(self):
self.schema = Schema(self.data)
self.build = Build(self.data['build'])
self.components = list(map(lambda entry: Component(
entry['name'],
entry['repository'],
entry['ref']
), self.data['components']))

def save_to(self, path):
with open(path, 'w') as file:
data = {
'schema-version' : 1.0,
'build': self.build.dict,
'components': list(map(lambda component: component.dict, self.components))
}
yaml.dump(data, file)
print(f'Written manifest to {path}.')
32 changes: 32 additions & 0 deletions tools/bundle-build/lib/build_output.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Copyright OpenSearch Contributors.
# SPDX-License-Identifier: Apache-2.0

import os
import subprocess
from dataclasses import dataclass

@dataclass
class BuildOutput:
dest: str = None
arch: str = None

def __post_init__(self):
self.dest = os.path.join(os.getcwd(), 'artifacts')
self.arch = BuildOutput.__get_arch()
self.__ensure_dest__()

def __ensure_dest__(self):
if os.path.exists(self.dest):
print(f'Directory exists: {self.dest}, aborting.')
exit(1)
os.makedirs(self.dest)

@staticmethod
def __get_arch():
arch = subprocess.check_output(['uname', '-m']).decode().strip()
if arch == 'x86_64':
return 'x64'
elif arch == 'aarch64' or arch == 'arm64':
return 'arm64'
else:
raise ValueError(f'Unsupported architecture: {arch}')
117 changes: 61 additions & 56 deletions tools/bundle-build/lib/component.py
Original file line number Diff line number Diff line change
@@ -1,88 +1,93 @@
# Copyright OpenSearch Contributors.
# SPDX-License-Identifier: Apache-2.0

import os
import tempfile
import subprocess
from lib.git import GitRepository
from lib.git_repository import GitRepository
from dataclasses import dataclass

@dataclass
class Component:
def __init__(self, data):
self._name = data['name']
self._repository = data['repository']
self._ref = data['ref']

def name(self):
return self._name

def repository(self):
return self._repository

def git_repository(self):
return self._git_repository

def ref(self):
return self._ref

def artifacts(self):
return self._artifacts
name: str
repository: str
ref: str
artifacts: dict = None
git_repository: GitRepository = None
dict: dict = None
artifacts_path: str = None
build_script: str = None
component_script_path: str = None
custom_component_script_path: str = None

def checkout(self):
self._git_repository = GitRepository(self.repository(), self.ref())
self.git_repository = GitRepository(self.repository, self.ref)
self.__set_custom_component_script_path()
self.__set_component_script_path()
self.__set_default_script_path()
self.__set_build_script()
self.__set_artifacts_path()

# script overridden in this repo
def custom_component_script_path(self):
def __set_custom_component_script_path(self):
dirname = os.path.dirname(os.path.abspath(__file__))
return os.path.realpath(os.path.join(dirname, '../../../scripts/bundle-build/components', self.name(), 'build.sh'))
self.custom_component_script_path = os.path.realpath(os.path.join(dirname, '../../../scripts/bundle-build/components', self.name, 'build.sh'))

# script inside the component repo
def component_script_path(self):
dirname = self.git_repository().dir()
return os.path.realpath(os.path.join(dirname, 'scripts/build.sh'))
def __set_component_script_path(self):
dirname = self.git_repository.dir.name
self.component_script_path = os.path.realpath(os.path.join(dirname, 'scripts/build.sh'))

# default gradle script
def default_script_path(self):
def __set_default_script_path(self):
dirname = os.path.dirname(os.path.abspath(__file__))
return os.path.realpath(os.path.join(dirname, '../../../scripts/bundle-build/standard-gradle-build/build.sh'))
self.default_script_path = os.path.realpath(os.path.join(dirname, '../../../scripts/bundle-build/standard-gradle-build/build.sh'))

def build_script(self):
paths = [self.component_script_path(), self.custom_component_script_path(), self.default_script_path()]
return next(filter(lambda path: os.path.exists(path), paths), None)
def __set_build_script(self):
paths = [self.component_script_path, self.custom_component_script_path, self.default_script_path]
self.build_script = next(filter(lambda path: os.path.exists(path), paths), None)

def build(self, version, arch):
build_script = f'{self.build_script()} {version} {arch}'
build_script = f'{self.build_script} {version} {arch}'
print(f'Running {build_script} ...')
self.git_repository().execute(build_script)
self.git_repository.execute(build_script)

def artifacts_path(self):
dirname = self.git_repository().dir()
return os.path.realpath(os.path.join(dirname, 'artifacts'))
def __set_artifacts_path(self):
dirname = self.git_repository.dir.name
self.artifacts_path = os.path.realpath(os.path.join(dirname, 'artifacts'))

def export(self, dest):
artifacts_path = self.artifacts_path()
if os.path.exists(artifacts_path):
print(f'Publishing artifacts from {artifacts_path} into {dest} ...')
self.git_repository().execute(f'cp -r "{artifacts_path}/"* "{dest}"')
self.set_artifacts()
if os.path.exists(self.artifacts_path):
print(f'Publishing artifacts from {self.artifacts_path} into {dest} ...')
self.git_repository.execute(f'cp -r "{self.artifacts_path}/"* "{dest}"')
else:
print(f'No artifacts found in {artifacts_path}, skipping.')

def set_artifacts(self):
self._artifacts = {key: self.file_paths(key) for key in ["maven", "plugins", "bundle", "libs"] if self.file_paths(key)}

def file_paths(self, dir_name):
artifacts_path = self.artifacts_path()
sub_dir = os.path.join(artifacts_path, dir_name)
self.__set_artifacts()
self.__set_dict()

def __set_artifacts(self):
artifacts = {}
for key in ["maven", "plugins", "bundle", "libs"]:
file_paths = self.__get_file_paths(key)
if file_paths:
artifacts[key] = file_paths
self.artifacts = artifacts

def __get_file_paths(self, dir_name):
sub_dir = os.path.join(self.artifacts_path, dir_name)
file_paths = []
if os.path.exists(sub_dir):
for dir, dirs, files in os.walk(sub_dir):
for file_name in files:
path = os.path.relpath(os.path.join(dir, file_name), artifacts_path)
path = os.path.relpath(os.path.join(dir, file_name), self.artifacts_path)
file_paths.append(path)
return file_paths

def dict(self):
return {
'name': self.name(),
'repository': self.repository(),
'ref': self.ref(),
'sha': self.git_repository().sha(),
'artifacts': self.artifacts()
def __set_dict(self):
self.dict = {
'name': self.name,
'repository': self.repository,
'ref': self.ref,
'sha': self.git_repository.sha,
'artifacts': self.artifacts
}
26 changes: 0 additions & 26 deletions tools/bundle-build/lib/git.py

This file was deleted.

28 changes: 28 additions & 0 deletions tools/bundle-build/lib/git_repository.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Copyright OpenSearch Contributors.
# SPDX-License-Identifier: Apache-2.0

import os
import tempfile
import subprocess
from dataclasses import dataclass

@dataclass
class GitRepository:
url: str
ref: str
sha: str = None
dir: tempfile.TemporaryDirectory = None

def __post_init__(self):
self.dir = tempfile.TemporaryDirectory()
self.execute(f'git init')
self.execute(f'git remote add origin {self.url}')
self.execute(f'git fetch --depth 1 origin {self.ref}')
self.execute(f'git checkout FETCH_HEAD')
self.sha = subprocess.check_output(['git', 'rev-parse', 'HEAD'], cwd = self.dir.name).decode().strip()
print(f'Checked out {self.url}@{self.ref} into {self.dir.name} at {self.sha}')

def execute(self, command):
print(f'Executing "{command}" in {self.dir.name}')
subprocess.check_call(command, cwd = self.dir.name, shell = True)

Loading

0 comments on commit 1c594c9

Please sign in to comment.