lennybot 1.0.22__py3-none-any.whl → 1.0.31__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,8 +1,9 @@
1
- from .download_resources import DownloadResourcesAction
1
+ from .download_resources import DownloadResourceAction
2
2
  from .iaction import IAction
3
3
  from .remove_checksums import RemoveChecksumsAction
4
4
  from .update_dockerfile import UpdateDockerfileAction
5
5
  from .update_image_tag import UpdateImageTagAction
6
+ from .update_json import UpdateJsonAction
6
7
  from .update_yaml import UpdateYamlAction
7
8
 
8
9
 
@@ -10,8 +11,10 @@ def create_action(name, source_version, latest_version, config) -> IAction:
10
11
  action_type = config.type
11
12
  if action_type == "image-tag-update":
12
13
  return UpdateImageTagAction(name, source_version, latest_version, config)
13
- if action_type == "download-resources":
14
- return DownloadResourcesAction(name, source_version, latest_version, config)
14
+ if action_type in ["download-resource", "download-resources"]:
15
+ return DownloadResourceAction(name, source_version, latest_version, config)
16
+ if action_type == "update-json":
17
+ return UpdateJsonAction(name, source_version, latest_version, config)
15
18
  if action_type == "update-yaml":
16
19
  return UpdateYamlAction(name, source_version, latest_version, config)
17
20
  if action_type == "update-dockerfile":
@@ -1,11 +1,13 @@
1
1
  import requests
2
+ import logging
2
3
 
3
4
  from ..config.config import LennyBotActionConfig
4
5
  from .iaction import IAction
5
6
 
6
7
 
7
- class DownloadResourcesAction(IAction):
8
+ class DownloadResourceAction(IAction):
8
9
  def __init__(self, name, source_version, target_version, config: LennyBotActionConfig) -> None:
10
+ self._log = logging.getLogger(self.__class__.__name__)
9
11
  self._name = name
10
12
  self._source_version = source_version
11
13
  self._target_version = target_version
@@ -30,8 +32,14 @@ class DownloadResourcesAction(IAction):
30
32
 
31
33
  def run(self):
32
34
  download_url = self._url.replace("{{version}}", self._target_version)
35
+ self._log.debug("Downloading resource from %s to %s", download_url, self._target_path)
33
36
  response = requests.get(download_url)
34
37
  if response.status_code != 200:
35
- raise Exception("Unable to download resources")
38
+ self._log.error(
39
+ "Unable to download resource, received status code: %d\n%s", response.status_code, response.text
40
+ )
41
+ raise Exception("Unable to download resource, received status code: " + str(response.status_code))
42
+ self._log.debug("Downloaded resources successfully")
36
43
  with open(self._target_path, "w", encoding="utf-8") as file_ptr:
37
44
  file_ptr.write(response.text)
45
+ self._log.debug("Saved resource to %s", self._target_path)
@@ -1,14 +1,14 @@
1
1
  class IAction:
2
2
  @property
3
- def application(self) -> str: # pyright: ignore [reportGeneralTypeIssues]
3
+ def application(self) -> str: # pyright: ignore [reportGeneralTypeIssues, reportReturnType]
4
4
  pass
5
5
 
6
6
  @property
7
- def source_version(self) -> str: # pyright: ignore [reportGeneralTypeIssues]
7
+ def source_version(self) -> str: # pyright: ignore [reportGeneralTypeIssues, reportReturnType]
8
8
  pass
9
9
 
10
10
  @property
11
- def target_version(self) -> str: # pyright: ignore [reportGeneralTypeIssues]
11
+ def target_version(self) -> str: # pyright: ignore [reportGeneralTypeIssues, reportReturnType]
12
12
  pass
13
13
 
14
14
  def run(self):
@@ -0,0 +1,48 @@
1
+ from types import SimpleNamespace
2
+
3
+ import json
4
+ from jsonpath_ng import parse, jsonpath
5
+ from ..config.config import LennyBotActionConfig
6
+ from .iaction import IAction
7
+
8
+
9
+ class UpdateJsonAction(IAction):
10
+ def __init__(self, name, source_version, target_version, config: LennyBotActionConfig) -> None:
11
+ self._name = name
12
+ self._source_version = source_version
13
+ self._target_version = target_version
14
+ if config.target_file is None:
15
+ raise Exception("Target file is not set for application " + name)
16
+ self._target_file = config.target_file
17
+ if config.json_path is None:
18
+ raise Exception("JSON Path is not set for application " + name)
19
+ self._json_path = parse(config.json_path)
20
+ if config.value_pattern is not None:
21
+ self._value_pattern = config.value_pattern
22
+ else:
23
+ self._value_pattern = "{{version}}"
24
+
25
+ @property
26
+ def application(self) -> str:
27
+ return self._name
28
+
29
+ @property
30
+ def source_version(self) -> str:
31
+ return self._source_version
32
+
33
+ @property
34
+ def target_version(self) -> str:
35
+ return self._target_version
36
+
37
+ def run(self):
38
+ # Read the JSON data from the file
39
+ with open(self._target_file, "r", encoding="utf-8") as file_ptr:
40
+ json_data = json.load(file_ptr)
41
+ # Update the value in the JSON data
42
+ self._json_path.update(json_data, self._create_value())
43
+ # Write the updated JSON data back to the file
44
+ with open(self._target_file, "w", encoding="utf-8") as file_ptr:
45
+ json.dump(json_data, fp=file_ptr, indent=4)
46
+
47
+ def _create_value(self):
48
+ return self._value_pattern.replace("{{version}}", self._target_version)
@@ -1,4 +1,4 @@
1
- from lennybot.config.config import LennyBotConfig
1
+ from ..config.config import LennyBotConfig
2
2
 
3
3
  from .docker_image_available import DockerImageAvailableCheck
4
4
  from .icheck import ICheck
@@ -103,7 +103,11 @@ class DockerImageAvailableCheck(ICheck):
103
103
  + image_tag
104
104
  )
105
105
  return DockerImage(match.group(4), match.group(5) + "/" + match.group(6), image_tag)
106
- return DockerImage(match.group(7), match.group(8) + "/" + match.group(9) + "/" + match.group(10), image_tag)
106
+ return DockerImage(
107
+ match.group(7),
108
+ match.group(8) + "/" + match.group(9) + "/" + match.group(10),
109
+ image_tag,
110
+ )
107
111
 
108
112
  def _authenticate_on_registry(self, registry: str, authentication_header: WwwAuthenticateHeader) -> str:
109
113
  params = {
@@ -143,11 +147,19 @@ class DockerImageAvailableCheck(ICheck):
143
147
  return str(access_token)
144
148
 
145
149
  if response.status_code == 401:
146
- logging.error("Authentication failed: %d with %s", response.status_code, response.headers)
150
+ logging.error(
151
+ "Authentication failed: %d with %s",
152
+ response.status_code,
153
+ response.headers,
154
+ )
147
155
  raise Exception("Error occurred: Unauthenticated: ", response.status_code)
148
156
 
149
157
  if response.status_code == 403:
150
- logging.error("Authorization failed: %d with %s", response.status_code, response.headers)
158
+ logging.error(
159
+ "Authorization failed: %d with %s",
160
+ response.status_code,
161
+ response.headers,
162
+ )
151
163
  raise Exception("Error occurred: Unauthorization: ", response.status_code)
152
164
 
153
165
  if response.status_code == 404:
@@ -180,11 +192,14 @@ class DockerImageAvailableCheck(ICheck):
180
192
 
181
193
  request_url = f"https://{image._registry}/v2/{image._name}/manifests/{image._tag}"
182
194
 
195
+ # depending on the registry it my helps adding the write accept header :)
196
+ # https://github.com/goharbor/harbor/issues/16075
197
+ headers = {
198
+ "Accept": "application/vnd.oci.image.index.v1+json, application/vnd.docker.distribution.manifest.list.v2+json",
199
+ }
183
200
  if access_token is not None:
184
- headers = {"Authorization": f"Bearer {access_token}"}
185
- response = requests.get(request_url, headers=headers)
186
- else:
187
- response = requests.get(request_url)
201
+ headers["Authorization"] = f"Bearer {access_token}"
202
+ response = requests.get(request_url, headers=headers)
188
203
 
189
204
  if response.status_code == 401 and access_token is None:
190
205
  registry = image._registry
lennybot/check/icheck.py CHANGED
@@ -1,15 +1,15 @@
1
1
  class ICheck:
2
2
  @property
3
- def application(self) -> str: # pyright: ignore [reportGeneralTypeIssues]
3
+ def application(self) -> str: # pyright: ignore [reportGeneralTypeIssues, reportReturnType]
4
4
  pass
5
5
 
6
6
  @property
7
- def source_version(self) -> str: # pyright: ignore [reportGeneralTypeIssues]
7
+ def source_version(self) -> str: # pyright: ignore [reportGeneralTypeIssues, reportReturnType]
8
8
  pass
9
9
 
10
10
  @property
11
- def target_version(self) -> str: # pyright: ignore [reportGeneralTypeIssues]
11
+ def target_version(self) -> str: # pyright: ignore [reportGeneralTypeIssues, reportReturnType]
12
12
  pass
13
13
 
14
- def check(self) -> bool: # pyright: ignore [reportGeneralTypeIssues]
14
+ def check(self) -> bool: # pyright: ignore [reportGeneralTypeIssues, reportReturnType]
15
15
  pass
lennybot/config/config.py CHANGED
@@ -26,7 +26,13 @@ CONFIGURATION_OPTIONS = {
26
26
  },
27
27
  "logging": {
28
28
  "type": "object",
29
- "properties": {"level": {"type": "string", "required": False, "attribute": "_logging_level"}},
29
+ "properties": {
30
+ "level": {
31
+ "type": "string",
32
+ "required": False,
33
+ "attribute": "_logging_level",
34
+ }
35
+ },
30
36
  },
31
37
  "container": {
32
38
  "type": "object",
@@ -56,7 +62,11 @@ CONFIGURATION_OPTIONS = {
56
62
  "attribute": "_source",
57
63
  "properties": {
58
64
  "type": {"type": "string", "required": True, "attribute": "_type"},
59
- "repository": {"type": "string", "required": True, "attribute": "_repository"},
65
+ "repository": {
66
+ "type": "string",
67
+ "required": True,
68
+ "attribute": "_repository",
69
+ },
60
70
  "regex": {"type": "string", "attribute": "_regex"},
61
71
  },
62
72
  },
@@ -133,6 +143,7 @@ class LennyBotActionConfig:
133
143
  self._url = None
134
144
  self._target_file = None
135
145
  self._yaml_path = None
146
+ self._json_path = None
136
147
  self._value_pattern = None
137
148
 
138
149
  @property
@@ -163,6 +174,10 @@ class LennyBotActionConfig:
163
174
  def target_file(self) -> str | None:
164
175
  return self._target_file
165
176
 
177
+ @property
178
+ def json_path(self) -> str | None:
179
+ return self._json_path
180
+
166
181
  @property
167
182
  def yaml_path(self) -> str | None:
168
183
  return self._yaml_path
@@ -259,7 +274,10 @@ class LennyBotConfig:
259
274
 
260
275
  def _configure_logging(self):
261
276
  logging_level = logging._nameToLevel.get(self._logging_level, logging.DEBUG)
262
- logging.basicConfig(level=logging_level, format="%(asctime)s [%(levelname)s] %(name)s: %(message)s")
277
+ logging.basicConfig(
278
+ level=logging_level,
279
+ format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
280
+ )
263
281
  self._log = logging.getLogger(self.__class__.__name__)
264
282
  self._log.debug("Logging was configured")
265
283
 
@@ -4,5 +4,5 @@ def semver_2_vc(version):
4
4
  parts = version.split(".")
5
5
  version_code = 0
6
6
  for part in parts:
7
- version_code = version_code * 100 + int(part)
7
+ version_code = version_code * 1000 + int(part)
8
8
  return version_code
@@ -34,7 +34,9 @@ class GitHubService:
34
34
  if self._github is None:
35
35
  raise Exception("GitHub is not configured")
36
36
  repo = self._github.get_repo(self._config.github_pr.repository)
37
- new_pull = repo.create_pull(repo.default_branch, branch_name, title=title, body=body)
37
+ new_pull = repo.create_pull(
38
+ repo.default_branch, branch_name, title=title, body=body
39
+ ) # pyright: ignore [reportCallIssue]
38
40
  labels = self._get_or_create_labels(repo)
39
41
  new_pull.add_to_labels(*labels)
40
42
  pulls = self._find_own_pulls()
lennybot/service/plan.py CHANGED
@@ -1,7 +1,7 @@
1
1
  import logging
2
2
  from typing import List
3
3
 
4
- from lennybot.check import create_check
4
+ from ..check import create_check
5
5
 
6
6
  from ..actions import IAction, create_action
7
7
  from ..config import LennyBotAppConfig, LennyBotConfig
@@ -31,7 +31,13 @@ class LennyBotApplication:
31
31
  self._current_version = state.current_version(self._name)
32
32
  self._latest_version = self._source.latest_version()
33
33
  for config in self._config._checks:
34
- check = create_check(self.name, self._current_version, self._latest_version, config, self._global_config)
34
+ check = create_check(
35
+ self.name,
36
+ self._current_version,
37
+ self._latest_version,
38
+ config,
39
+ self._global_config,
40
+ )
35
41
  self._checks.append(check)
36
42
 
37
43
  def should_update(self) -> bool:
@@ -47,7 +53,13 @@ class LennyBotApplication:
47
53
 
48
54
  for check in self._checks:
49
55
  if not check.check():
50
- self._log.info("Check '%s' failed for application '%s'", check.__class__.__name__, self.name)
56
+ self._log.warning(
57
+ "Check '%s' failed for application '%s' with current version '%s' and latest version '%s'",
58
+ check.__class__.__name__,
59
+ self.name,
60
+ self._current_version,
61
+ self._latest_version,
62
+ )
51
63
  return False
52
64
  return True
53
65
 
@@ -1,7 +1,7 @@
1
1
  class ISource:
2
2
  @property
3
- def application(self) -> str: # pyright: ignore [reportGeneralTypeIssues]
3
+ def application(self) -> str: # pyright: ignore [reportGeneralTypeIssues, reportReturnType]
4
4
  pass
5
5
 
6
- def latest_version(self) -> str: # pyright: ignore [reportGeneralTypeIssues]
6
+ def latest_version(self) -> str: # pyright: ignore [reportGeneralTypeIssues, reportReturnType]
7
7
  pass
@@ -31,7 +31,13 @@ The lennybot allows to define multiple applications.
31
31
  Each application has to have a version source, which can be queried to determine the latest version.
32
32
  If a newer version is available, the lennybot executes multiple pre defined actions per application.
33
33
  E.g. Update Docker Image Tags.
34
- The applications, sources and actions can be configured in the `config.yml` file.
34
+ Sometimes there are conditions which need to be fulfilled before the action can be executed.
35
+ These conditions can be specified as checks.
36
+ E.g. Check if the docker image is available in the registry, because sometimes a new version of an applications gets released, but the docker image is not available yet.
37
+
38
+ ![A graph showing the process of updating applications by the lennybot](./docs/LennyBot-Execution.drawio.png)
39
+
40
+ The applications, sources, checks and actions can be configured in the `config.yml` file.
35
41
  For more information see below.
36
42
 
37
43
  ## Configuration
@@ -52,19 +58,16 @@ Each section represents a configuration object.
52
58
 
53
59
  | Path | Description |
54
60
  |--------------------------------------------|------------------------------------------------------------------------|
55
- | state.file | The state file which is used to store the version of each application |
56
61
  | state.pr.enabled | Toggle PR creation in CI mode. Has to be either true or false |
57
62
  | state.pr.repository | The name of the repository in github on which the PR should be created |
58
63
  | state.pr.branchPrefix | Prefix for the branch name which should be used to create the PRs |
59
64
 
60
65
  ### Applications
61
66
 
62
- | Path | Description |
67
+ | Property | Description |
63
68
  |--------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------|
64
69
  | applications[*].name | The name of the application which should be updated |
65
- | applications[*].source.type | The source has to be either of the type "github" or of the type "github-query". See below for details. |
66
- | applications[*].source.repository | The GitHub Repository which should be used to determine the latest version |
67
- | applications[*].source.regex | The regex pattern which is used to extract the semver version code from the tag value |
70
+ | applications[*].source | The configuration for the source of the latest version. This is specific to the type of source, see below for the diffrent source types. |
68
71
  | applications[\*].actions[\*].type | The action has to be one of these types "image-tag-update", "download-resources" or "update-yaml". See below for details. |
69
72
  | applications[\*].actions[\*].url | |
70
73
  | applications[\*].actions[\*].target | |
@@ -75,21 +78,61 @@ Each section represents a configuration object.
75
78
  | applications[\*].actions[\*].yamlPath | |
76
79
  | applications[\*].actions[\*].valuePattern | |
77
80
 
81
+ ### Sources
82
+
78
83
  #### GitHub Source
84
+
79
85
  <TODO>
80
86
 
87
+ | Property | Description |
88
+ |----------------------|--------------------------------------------------------------------------------------------------------------------------------------------|
89
+ | .type | The source has to be either of the type "github" or of the type "github-query". See below for details. |
90
+ | .repository | The GitHub Repository which should be used to determine the latest version |
91
+ | .regex | The regex pattern which is used to extract the semver version code from the tag value |
92
+
93
+
81
94
  #### GitHub Query Source
95
+
96
+ <TODO>
97
+
98
+ | Property | Description |
99
+ |----------------------|--------------------------------------------------------------------------------------------------------------------------------------------|
100
+ | .type | The source has to be either of the type "github" or of the type "github-query". See below for details. |
101
+ | .repository | The GitHub Repository which should be used to determine the latest version |
102
+ | .regex | The regex pattern which is used to extract the semver version code from the tag value |
103
+
104
+
105
+ ### Checks
106
+
82
107
  <TODO>
83
108
 
109
+
110
+ ### Actions
111
+
84
112
  #### Image Tag Update Action
85
113
  <TODO>
86
114
 
115
+ | Property | Description |
116
+ |--------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------|
117
+ | .type | The action has to be one of these types "image-tag-update", "download-resources" or "update-yaml". See below for details. |
118
+ | .url | |
119
+ | .target | |
120
+ | .image | |
121
+ | .kustomizePath | |
122
+ | .tagPattern | |
123
+ | .targetFile | |
124
+ | .yamlPath | |
125
+ | .valuePattern | |
126
+
87
127
  #### Download Resource Action
88
128
  <TODO>
89
129
 
90
130
  #### Update YAML Action
91
131
  <TODO>
92
132
 
133
+ #### Update JSON Action
134
+ <TODO>
135
+
93
136
  #### Update Dockerfile Action
94
137
  <TODO>
95
138
 
@@ -2,4 +2,5 @@ pyyaml
2
2
  yamlpath
3
3
  requests
4
4
  GitPython
5
- PyGithub
5
+ PyGithub
6
+ jsonpath-ng
@@ -0,0 +1 @@
1
+ 1.0.31
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lennybot
3
- Version: 1.0.22
3
+ Version: 1.0.31
4
4
  Summary: Automatic Updates for Kustomize Resources
5
5
  Home-page: http://github.com/raynigon/lennybot
6
6
  Author: Simon Schneider
@@ -23,6 +23,7 @@ Requires-Dist: yamlpath
23
23
  Requires-Dist: requests
24
24
  Requires-Dist: GitPython
25
25
  Requires-Dist: PyGithub
26
+ Requires-Dist: jsonpath-ng
26
27
  Provides-Extra: dev
27
28
  Requires-Dist: setuptools ; extra == 'dev'
28
29
  Requires-Dist: wheel ; extra == 'dev'
@@ -64,7 +65,13 @@ The lennybot allows to define multiple applications.
64
65
  Each application has to have a version source, which can be queried to determine the latest version.
65
66
  If a newer version is available, the lennybot executes multiple pre defined actions per application.
66
67
  E.g. Update Docker Image Tags.
67
- The applications, sources and actions can be configured in the `config.yml` file.
68
+ Sometimes there are conditions which need to be fulfilled before the action can be executed.
69
+ These conditions can be specified as checks.
70
+ E.g. Check if the docker image is available in the registry, because sometimes a new version of an applications gets released, but the docker image is not available yet.
71
+
72
+ ![A graph showing the process of updating applications by the lennybot](./docs/LennyBot-Execution.drawio.png)
73
+
74
+ The applications, sources, checks and actions can be configured in the `config.yml` file.
68
75
  For more information see below.
69
76
 
70
77
  ## Configuration
@@ -85,19 +92,16 @@ Each section represents a configuration object.
85
92
 
86
93
  | Path | Description |
87
94
  |--------------------------------------------|------------------------------------------------------------------------|
88
- | state.file | The state file which is used to store the version of each application |
89
95
  | state.pr.enabled | Toggle PR creation in CI mode. Has to be either true or false |
90
96
  | state.pr.repository | The name of the repository in github on which the PR should be created |
91
97
  | state.pr.branchPrefix | Prefix for the branch name which should be used to create the PRs |
92
98
 
93
99
  ### Applications
94
100
 
95
- | Path | Description |
101
+ | Property | Description |
96
102
  |--------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------|
97
103
  | applications[*].name | The name of the application which should be updated |
98
- | applications[*].source.type | The source has to be either of the type "github" or of the type "github-query". See below for details. |
99
- | applications[*].source.repository | The GitHub Repository which should be used to determine the latest version |
100
- | applications[*].source.regex | The regex pattern which is used to extract the semver version code from the tag value |
104
+ | applications[*].source | The configuration for the source of the latest version. This is specific to the type of source, see below for the diffrent source types. |
101
105
  | applications[\*].actions[\*].type | The action has to be one of these types "image-tag-update", "download-resources" or "update-yaml". See below for details. |
102
106
  | applications[\*].actions[\*].url | |
103
107
  | applications[\*].actions[\*].target | |
@@ -108,21 +112,61 @@ Each section represents a configuration object.
108
112
  | applications[\*].actions[\*].yamlPath | |
109
113
  | applications[\*].actions[\*].valuePattern | |
110
114
 
115
+ ### Sources
116
+
111
117
  #### GitHub Source
118
+
112
119
  <TODO>
113
120
 
121
+ | Property | Description |
122
+ |----------------------|--------------------------------------------------------------------------------------------------------------------------------------------|
123
+ | .type | The source has to be either of the type "github" or of the type "github-query". See below for details. |
124
+ | .repository | The GitHub Repository which should be used to determine the latest version |
125
+ | .regex | The regex pattern which is used to extract the semver version code from the tag value |
126
+
127
+
114
128
  #### GitHub Query Source
129
+
130
+ <TODO>
131
+
132
+ | Property | Description |
133
+ |----------------------|--------------------------------------------------------------------------------------------------------------------------------------------|
134
+ | .type | The source has to be either of the type "github" or of the type "github-query". See below for details. |
135
+ | .repository | The GitHub Repository which should be used to determine the latest version |
136
+ | .regex | The regex pattern which is used to extract the semver version code from the tag value |
137
+
138
+
139
+ ### Checks
140
+
115
141
  <TODO>
116
142
 
143
+
144
+ ### Actions
145
+
117
146
  #### Image Tag Update Action
118
147
  <TODO>
119
148
 
149
+ | Property | Description |
150
+ |--------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------|
151
+ | .type | The action has to be one of these types "image-tag-update", "download-resources" or "update-yaml". See below for details. |
152
+ | .url | |
153
+ | .target | |
154
+ | .image | |
155
+ | .kustomizePath | |
156
+ | .tagPattern | |
157
+ | .targetFile | |
158
+ | .yamlPath | |
159
+ | .valuePattern | |
160
+
120
161
  #### Download Resource Action
121
162
  <TODO>
122
163
 
123
164
  #### Update YAML Action
124
165
  <TODO>
125
166
 
167
+ #### Update JSON Action
168
+ <TODO>
169
+
126
170
  #### Update Dockerfile Action
127
171
  <TODO>
128
172
 
@@ -0,0 +1,37 @@
1
+ lennybot/__init__.py,sha256=xlswzbdsh3hj2f3UxHKUW7sZhQkS_7ONEtUIV9QJEy8,2696
2
+ lennybot/__main__.py,sha256=iPpiz09xKqtAjrhONS99OYp6R2dQ6Anbhw1qPIN8ELo,80
3
+ lennybot/lennybot.py,sha256=6Sm1cvzDkopeqtNEf1RsB-i9CttB94oj4UneZEm3oD4,3790
4
+ lennybot/actions/__init__.py,sha256=3nR2DlivXdylqdTsccL9yvkHKqo0FO5JyczGvvKTXWI,1249
5
+ lennybot/actions/download_resources.py,sha256=AuZoMdqxdl0VngHBMT6zc5phBnuaWjjGIwJyIBGod6w,1767
6
+ lennybot/actions/iaction.py,sha256=KR2IkxSNYQc_bKsiKuJjxPr5VTj6dUfB7P1V_uA4yVI,428
7
+ lennybot/actions/remove_checksums.py,sha256=3GMo_6vDdeBYTG5AYlYHB0iEiqa9tMD4PfIOxOXZ3cE,1797
8
+ lennybot/actions/update_dockerfile.py,sha256=zkQEmKaIWpECmIwb27moonLJ_7Jr-BBnc6LMrGWo6Rk,1699
9
+ lennybot/actions/update_image_tag.py,sha256=1XQ40Ls47qDNDair2qyuRWtRYzSNV5tkHGC_yPKY40E,1689
10
+ lennybot/actions/update_json.py,sha256=_aRO7fxxFjck5I9Z_j4pPDvGDjMtCS_yjqn9G_sbcqc,1740
11
+ lennybot/actions/update_yaml.py,sha256=o7qywAVvDgLcBCYCL4MirmYKduELNemkil7TLxon-BY,1919
12
+ lennybot/check/__init__.py,sha256=BurwXJzk8CQcAiEZh7BeHum2N0WbRCTpZbeE2ZbhdaI,486
13
+ lennybot/check/docker_image_available.py,sha256=Op2-n6U3Fkk0UOOaz3Koo21lqdErmItD-S01RBNLqV8,8397
14
+ lennybot/check/icheck.py,sha256=sCMy1y_rrjVNrKh4vAiHH2QpiZIaUWaF06qkGnyC-N8,500
15
+ lennybot/config/__init__.py,sha256=L85iDCHQJ1zH6U3s8XJuY3bzpj_r8ZOLm_djv84pG-U,119
16
+ lennybot/config/config.py,sha256=hrFDP5NM59BPH60vFmYiQxgvrDmpka3v8i0VoazbYBY,11741
17
+ lennybot/helper/__init__.py,sha256=u_-EsBGjsXi5qXxEtFlMsRkh2ocxH17w3RfPH2j2QWU,221
18
+ lennybot/model/__init__.py,sha256=e_P6FXQooilrRoSKFdewkEUWL8x6k_45lH97yxL1rks,64
19
+ lennybot/model/plan.py,sha256=KwITeVucCSxjM_SyetyUtGSw8hCXfZqO4yrY-330ba4,1096
20
+ lennybot/model/state.py,sha256=UK9ALA3O5tGYQW5WCxQpybHeXrrwrQMgtvoZ4W_N9ok,1453
21
+ lennybot/service/__init__.py,sha256=jU103QJj6LHYY6-R7wYEdu1oiwRT0FfwLG4wgZYbMAo,96
22
+ lennybot/service/apply.py,sha256=P-Nkp5zsGRIEt7vkYkNJ_QuBgoN463XvABd5mRUDM0o,695
23
+ lennybot/service/github.py,sha256=6BHQiu30aRVKPe6Rc6O2ZWMPAvZTRW7rJZw_f9AhGLE,2973
24
+ lennybot/service/plan.py,sha256=GclYDy3bqdEsS_KDWUgDF4125uTUuOSDJh2sUdQS6Z8,3435
25
+ lennybot/service/source/__init__.py,sha256=MX1dINBfsTIv7TDVbX-qbqiMsZN8XM6I4lhudcPnYlM,503
26
+ lennybot/service/source/isource.py,sha256=s7T95siVMyKvCX2Ta4O7Jarc5BFAoYWfN74ocyLQiRM,253
27
+ lennybot/service/source/source_github.py,sha256=z3xV4nH-opDagCGTgCKDjfeGHqbd4kdpmCvk0LCm04w,1073
28
+ lennybot/service/source/source_github_query.py,sha256=Dn764TBPw6PABhNa_A1JIGCfLoBhcvmScEBHHmCbEbI,1072
29
+ lennybot-1.0.31.data/data/generic/README.md,sha256=80AiUnPW9CnHB3Iwa8qGggGQl2XXUe5tVNtAny-_1nk,9831
30
+ lennybot-1.0.31.data/data/generic/requirements.txt,sha256=ehp2P57fAPHl3tX8r5t3vyyPmW6tflMIKBBB0vKpvws,55
31
+ lennybot-1.0.31.data/data/generic/version.txt,sha256=VmLTmBbOULW3noulizLqu_B8fqxN0ySSfEW-8f3y1Sk,6
32
+ lennybot-1.0.31.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
33
+ lennybot-1.0.31.dist-info/METADATA,sha256=_g63wg36lPVDPBn0doLjDH2nsojkzt67YHIum9cZFmw,11017
34
+ lennybot-1.0.31.dist-info/WHEEL,sha256=UvcQYKBHoFqaQd6LKyqHw9fxEolWLQnlzP0h_LgJAfI,91
35
+ lennybot-1.0.31.dist-info/entry_points.txt,sha256=TOjzBcHTJaiBU2arbNIMVr7_clYPAYjBZf5WqiZ8Uhw,43
36
+ lennybot-1.0.31.dist-info/top_level.txt,sha256=Hrq9FY_KliVyEMH7LEA9rhCumLFTpKOHdSaZqzfHxhw,9
37
+ lennybot-1.0.31.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.41.3)
2
+ Generator: setuptools (74.0.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1 +0,0 @@
1
- 1.0.22
@@ -1,36 +0,0 @@
1
- lennybot/__init__.py,sha256=xlswzbdsh3hj2f3UxHKUW7sZhQkS_7ONEtUIV9QJEy8,2696
2
- lennybot/__main__.py,sha256=iPpiz09xKqtAjrhONS99OYp6R2dQ6Anbhw1qPIN8ELo,80
3
- lennybot/lennybot.py,sha256=6Sm1cvzDkopeqtNEf1RsB-i9CttB94oj4UneZEm3oD4,3790
4
- lennybot/actions/__init__.py,sha256=uXIFOBIrTgVF5wIqHIgEgs9l9JrU5gzjdRUQWKsZpGI,1071
5
- lennybot/actions/download_resources.py,sha256=tdoidM07SWKRhr3f7yFL7NPtmBS7eDiQvmcIjdCr190,1260
6
- lennybot/actions/iaction.py,sha256=DFj58sGyfVPlBUHdH5P9P6m450MntftHectNQK2qoMI,374
7
- lennybot/actions/remove_checksums.py,sha256=3GMo_6vDdeBYTG5AYlYHB0iEiqa9tMD4PfIOxOXZ3cE,1797
8
- lennybot/actions/update_dockerfile.py,sha256=zkQEmKaIWpECmIwb27moonLJ_7Jr-BBnc6LMrGWo6Rk,1699
9
- lennybot/actions/update_image_tag.py,sha256=1XQ40Ls47qDNDair2qyuRWtRYzSNV5tkHGC_yPKY40E,1689
10
- lennybot/actions/update_yaml.py,sha256=o7qywAVvDgLcBCYCL4MirmYKduELNemkil7TLxon-BY,1919
11
- lennybot/check/__init__.py,sha256=I5Q6bb2zeOX9TDTczsnnFUlQbV5Us5l18LybbNPxhXw,493
12
- lennybot/check/docker_image_available.py,sha256=8jr866x202Gh2urPn9oIoau_FmkHC1wr5EnSoEoiKnI,7999
13
- lennybot/check/icheck.py,sha256=lsHMeZFGNrSM7v-OIOuqn_22osKife62YSp1mRQrGjE,428
14
- lennybot/config/__init__.py,sha256=L85iDCHQJ1zH6U3s8XJuY3bzpj_r8ZOLm_djv84pG-U,119
15
- lennybot/config/config.py,sha256=Z-D_YML-Go3MmcZGN8ij6vdTSPGTNgwCYcK0esGJcLw,11410
16
- lennybot/helper/__init__.py,sha256=UxQeNPPeaZm26vc0JPPBhOfXbT1QZysLP_3HLZq8QPs,220
17
- lennybot/model/__init__.py,sha256=e_P6FXQooilrRoSKFdewkEUWL8x6k_45lH97yxL1rks,64
18
- lennybot/model/plan.py,sha256=KwITeVucCSxjM_SyetyUtGSw8hCXfZqO4yrY-330ba4,1096
19
- lennybot/model/state.py,sha256=UK9ALA3O5tGYQW5WCxQpybHeXrrwrQMgtvoZ4W_N9ok,1453
20
- lennybot/service/__init__.py,sha256=jU103QJj6LHYY6-R7wYEdu1oiwRT0FfwLG4wgZYbMAo,96
21
- lennybot/service/apply.py,sha256=P-Nkp5zsGRIEt7vkYkNJ_QuBgoN463XvABd5mRUDM0o,695
22
- lennybot/service/github.py,sha256=bWBUq02_dgDMVXpU9h28-teylNuTf4Ae28EHJ3kByxs,2914
23
- lennybot/service/plan.py,sha256=hFmHVGh6AmVE1bWLSwTASPeN-NAgE9TkBmEG5MKDChY,3130
24
- lennybot/service/source/__init__.py,sha256=MX1dINBfsTIv7TDVbX-qbqiMsZN8XM6I4lhudcPnYlM,503
25
- lennybot/service/source/isource.py,sha256=3-34UdP5TZVrcLN85q2RynqVxYVHyL1Wr2BjNaYHj3A,217
26
- lennybot/service/source/source_github.py,sha256=z3xV4nH-opDagCGTgCKDjfeGHqbd4kdpmCvk0LCm04w,1073
27
- lennybot/service/source/source_github_query.py,sha256=Dn764TBPw6PABhNa_A1JIGCfLoBhcvmScEBHHmCbEbI,1072
28
- lennybot-1.0.22.data/data/generic/README.md,sha256=uNfqoDP3AAZD3AD01JlQ4xje60Se1DgxSFhfJvWHbT0,6228
29
- lennybot-1.0.22.data/data/generic/requirements.txt,sha256=YChJFa4_Okg8UWzn6EPKeMl5gISIZ_k_9sgZSSLycXY,43
30
- lennybot-1.0.22.data/data/generic/version.txt,sha256=nGcluXlTHrvs97eLbAXe8stF-b2xLSFBQz0glFlFVPQ,6
31
- lennybot-1.0.22.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
32
- lennybot-1.0.22.dist-info/METADATA,sha256=blKEJyL1EqfbclHLyymhVrv7u_igjxDANT-uZOR9ETM,7387
33
- lennybot-1.0.22.dist-info/WHEEL,sha256=Xo9-1PvkuimrydujYJAjF7pCkriuXBpUPEjma1nZyJ0,92
34
- lennybot-1.0.22.dist-info/entry_points.txt,sha256=TOjzBcHTJaiBU2arbNIMVr7_clYPAYjBZf5WqiZ8Uhw,43
35
- lennybot-1.0.22.dist-info/top_level.txt,sha256=Hrq9FY_KliVyEMH7LEA9rhCumLFTpKOHdSaZqzfHxhw,9
36
- lennybot-1.0.22.dist-info/RECORD,,