Skip to content

Commit 68a2dff

Browse files
committed
feat: support for pipenv.lock file parsing
Signed-off-by: Paul Horton <[email protected]>
1 parent 2bf2711 commit 68a2dff

File tree

4 files changed

+120
-0
lines changed

4 files changed

+120
-0
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,14 @@ _Note: We refer throughout using XPath, but the same is true for both XML and JS
192192
<td>Y</td><td>Y</td><td>Y</td><td>Y</td>
193193
<td>&nbsp;</td>
194194
</tr>
195+
<tr>
196+
<td><code>./hashes</code></td>
197+
<td>Y</td><td>Y</td><td>Y</td><td>Y</td>
198+
<td>
199+
These are supported when programmatically creating a <code>Bom</code> - these will not currently be
200+
automatically populated when using a <code>Parser</code>.
201+
</td>
202+
</tr>
195203
</tbody>
196204
</table>
197205

cyclonedx/parser/pipenv.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# encoding: utf-8
2+
3+
# This file is part of CycloneDX Python Lib
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
# SPDX-License-Identifier: Apache-2.0
18+
# Copyright (c) OWASP Foundation. All Rights Reserved.
19+
import json
20+
21+
from . import BaseParser
22+
from ..model.component import Component
23+
24+
25+
class PipEnvParser(BaseParser):
26+
27+
def __init__(self, pipenv_contents: str):
28+
super().__init__()
29+
pipfile_lock_contents = json.loads(pipenv_contents)
30+
31+
for package_name in pipfile_lock_contents['default'].keys():
32+
print('Processing {}'.format(package_name))
33+
package_data = pipfile_lock_contents['default'][package_name]
34+
c = Component(
35+
name=package_name, version=str(package_data['version']).strip('='),
36+
)
37+
38+
# @todo: Add hashes
39+
40+
self._components.append(c)
41+
42+
43+
class PipEnvFileParser(PipEnvParser):
44+
45+
def __init__(self, pipenv_lock_filename: str):
46+
with open(pipenv_lock_filename) as r:
47+
super(PipEnvFileParser, self).__init__(pipenv_contents=r.read())
48+
r.close()
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"_meta": {
3+
"hash": {
4+
"sha256": "8ca3da46acf801a7780c6781bed1d6b7012664226203447640cda114b13aa8aa"
5+
},
6+
"pipfile-spec": 6,
7+
"requires": {
8+
"python_version": "3.9"
9+
},
10+
"sources": [
11+
{
12+
"name": "pypi",
13+
"url": "https://pypi.org/simple",
14+
"verify_ssl": true
15+
}
16+
]
17+
},
18+
"default": {
19+
"toml": {
20+
"hashes": [
21+
"sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b",
22+
"sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"
23+
],
24+
"index": "pypi",
25+
"version": "==0.10.2"
26+
}
27+
},
28+
"develop": {}
29+
}

tests/test_parser_pipenv.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# encoding: utf-8
2+
3+
# This file is part of CycloneDX Python Lib
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
# SPDX-License-Identifier: Apache-2.0
18+
# Copyright (c) OWASP Foundation. All Rights Reserved.
19+
20+
import os
21+
from unittest import TestCase
22+
23+
from cyclonedx.parser.pipenv import PipEnvFileParser
24+
25+
26+
class TestPipEnvParser(TestCase):
27+
28+
def test_simple(self):
29+
tests_pipfile_lock = os.path.join(os.path.dirname(__file__), 'fixtures/pipfile-lock-simple.txt')
30+
31+
parser = PipEnvFileParser(pipenv_lock_filename=tests_pipfile_lock)
32+
self.assertEqual(1, parser.component_count())
33+
components = parser.get_components()
34+
self.assertEqual('toml', components[0].get_name())
35+
self.assertEqual('0.10.2', components[0].get_version())

0 commit comments

Comments
 (0)