Repository: vmware/tern (python)

Issue:
Add checksum as a Package property
**Describe the Feature**
Add `checksum` as a Package property.

**Use Cases**
Specifically, this is a property that SPDX documents use. More generally, This is a good way to check for any discrepancies even if the package manager has the same metadata and can detect some corner cases for diffs. See PR #182 conversations for more context.

**Implementation Changes**
1. Add the checksum property to Package class with a default value (empty string)
2. Find methods for each of the package manager supported to get this information


Pull request description:
Added Checksum as a Package Property
Resolves #183
Adds the checksum as a Package property with empty string as default
value. Changes are made in Package class where new attrribute, its
getter and setter are added. Tests are also added in test_class_pacakge
for value, getter, setter, fill, and equal functions.

Signed-off-by: Khayam Gondal <khayam.gondal@gmail.com>

Patch:
diff --git a/tern/classes/package.py b/tern/classes/package.py
index 1cce92a..a3cc6da 100644
--- a/tern/classes/package.py
+++ b/tern/classes/package.py
@@ -18,6 +18,7 @@ class Package:
         proj_url: package source url
         download_url: package download url
         origins: a list of NoticeOrigin objects
+        checksum: checksum as package property
 
     methods:
         to_dict: returns a dict representation of the instance
@@ -30,6 +31,7 @@ class Package:
         self.__copyright = ''
         self.__proj_url = ''
         self.__download_url = ''
+        self.__checksum = ''
         self.__origins = Origins()
 
     @property
@@ -80,6 +82,14 @@ class Package:
     def origins(self):
         return self.__origins
 
+    @property
+    def checksum(self):
+        return self.__checksum
+
+    @checksum.setter
+    def checksum(self, checksum):
+        self.__checksum = checksum;
+
     def to_dict(self, template=None):
         '''Return a dictionary version of the Package object
         If given an object which is a subclass of Template then map


Test patch:
diff --git a/tests/test_class_package.py b/tests/test_class_package.py
index b491030..314e455 100644
--- a/tests/test_class_package.py
+++ b/tests/test_class_package.py
@@ -19,6 +19,7 @@ class TestClassPackage(unittest.TestCase):
         self.p1.copyright = 'All Rights Reserved'
         self.p1.proj_url = 'github.com'
         self.p1.download_url = 'https://github.com'
+        self.p1.checksum = '123abc456'
 
         self.p2 = Package('p2')
 
@@ -33,6 +34,7 @@ class TestClassPackage(unittest.TestCase):
         self.assertFalse(self.p2.pkg_license)
         self.assertFalse(self.p2.copyright)
         self.assertFalse(self.p2.download_url)
+        self.assertFalse(self.p2.checksum)
 
     def testSetters(self):
         self.assertRaises(AttributeError, setattr, self.p2, 'name', 'y')
@@ -46,6 +48,8 @@ class TestClassPackage(unittest.TestCase):
         self.assertEqual(self.p2.proj_url, 'github.com')
         self.p2.download_url = 'https://github.com'
         self.assertEqual(self.p2.download_url, 'https://github.com')
+        self.p2.checksum = '123abc456'
+        self.assertEqual(self.p2.checksum, '123abc456')
 
     def testGetters(self):
         self.assertEqual(self.p1.name, 'p1')
@@ -54,6 +58,7 @@ class TestClassPackage(unittest.TestCase):
         self.assertEqual(self.p1.copyright, 'All Rights Reserved')
         self.assertEqual(self.p1.proj_url, 'github.com')
         self.assertEqual(self.p1.download_url, 'https://github.com')
+        self.assertEqual(self.p1.checksum, '123abc456')
 
     def testToDict(self):
         a_dict = self.p1.to_dict()
@@ -64,6 +69,7 @@ class TestClassPackage(unittest.TestCase):
         self.assertEqual(a_dict['proj_url'], 'github.com')
         self.assertEqual(a_dict['download_url'], 'https://github.com')
         self.assertFalse(a_dict['origins'])
+        self.assertEqual(a_dict['checksum'], '123abc456')
 
     def testToDictTemplate(self):
         template1 = TestTemplate1()
@@ -82,9 +88,11 @@ class TestClassPackage(unittest.TestCase):
         p.pkg_license = 'Testpkg_license'
         p.version = '1.0'
         p.proj_url = 'TestUrl'
+        p.checksum = 'abcdef'
         self.p2.pkg_license = 'Testpkg_license'
         self.p2.version = '2.0'
         self.p2.proj_url = 'TestUrl'
+        self.p2.checksum = 'abcdef'
         self.assertFalse(self.p2.is_equal(p))
         p.version = '2.0'
         self.assertTrue(self.p2.is_equal(p))
@@ -92,12 +100,14 @@ class TestClassPackage(unittest.TestCase):
     def testFill(self):
         p_dict = {'name': 'p1',
                   'version': '1.0',
-                  'pkg_license': 'Apache 2.0'}
+                  'pkg_license': 'Apache 2.0',
+                  'checksum': 'abcxyz'}
         p = Package('p1')
         p.fill(p_dict)
         self.assertEqual(p.name, 'p1')
         self.assertEqual(p.version, '1.0')
         self.assertEqual(p.pkg_license, 'Apache 2.0')
+        self.assertEqual(p.checksum, 'abcxyz')
         self.assertFalse(p.copyright)
         self.assertFalse(p.proj_url)
         self.assertEqual(len(p.origins.origins), 1)