public inbox for gentoo-portage-dev@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-portage-dev] [PATCH 1/4] tests: Stop using herds
  2016-04-16 18:06 [gentoo-portage-dev] [PATCH 0/4] GLEP 67 test cleanup & XML Schema for repoman Michał Górny
@ 2016-04-16 18:06 ` Michał Górny
  0 siblings, 0 replies; 7+ messages in thread
From: Michał Górny @ 2016-04-16 18:06 UTC (permalink / raw
  To: gentoo-portage-dev; +Cc: Michał Górny

---
 pym/portage/tests/emerge/test_simple.py          |  2 --
 pym/portage/tests/repoman/test_simple.py         |  3 ---
 pym/portage/tests/resolver/ResolverPlayground.py | 22 ----------------------
 3 files changed, 27 deletions(-)

diff --git a/pym/portage/tests/emerge/test_simple.py b/pym/portage/tests/emerge/test_simple.py
index 394ed43..e5ecd4b 100644
--- a/pym/portage/tests/emerge/test_simple.py
+++ b/pym/portage/tests/emerge/test_simple.py
@@ -153,14 +153,12 @@ pkg_preinst() {
 			(
 				"dev-libs/A",
 				{
-					"herd" : "base-system",
 					"flags" : "<flag name='flag'>Description of how USE='flag' affects this package</flag>",
 				},
 			),
 			(
 				"dev-libs/B",
 				{
-					"herd" : "no-herd",
 					"flags" : "<flag name='flag'>Description of how USE='flag' affects this package</flag>",
 				},
 			),
diff --git a/pym/portage/tests/repoman/test_simple.py b/pym/portage/tests/repoman/test_simple.py
index 98220c4..720560b 100644
--- a/pym/portage/tests/repoman/test_simple.py
+++ b/pym/portage/tests/repoman/test_simple.py
@@ -133,21 +133,18 @@ class SimpleRepomanTestCase(TestCase):
 			(
 				"dev-libs/A",
 				{
-					"herd" : "base-system",
 					"flags" : "<flag name='flag' restrict='&gt;=dev-libs/A-0'>Description of how USE='flag' affects this package</flag>",
 				},
 			),
 			(
 				"dev-libs/B",
 				{
-					"herd" : "no-herd",
 					"flags" : "<flag name='flag'>Description of how USE='flag' affects this package</flag>",
 				},
 			),
 			(
 				"dev-libs/C",
 				{
-					"herd" : "no-herd",
 					"flags" : "<flag name='flag'>Description of how USE='flag' affects this package</flag>",
 				},
 			),
diff --git a/pym/portage/tests/resolver/ResolverPlayground.py b/pym/portage/tests/resolver/ResolverPlayground.py
index 6bdf2c7..68e047a 100644
--- a/pym/portage/tests/resolver/ResolverPlayground.py
+++ b/pym/portage/tests/resolver/ResolverPlayground.py
@@ -47,7 +47,6 @@ class ResolverPlayground(object):
 	metadata_xml_template = """<?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE pkgmetadata SYSTEM "http://www.gentoo.org/dtd/metadata.dtd">
 <pkgmetadata>
-<herd>%(herd)s</herd>
 <maintainer>
 <email>maintainer-needed@gentoo.org</email>
 <description>Description of the maintainership</description>
@@ -381,27 +380,6 @@ class ResolverPlayground(object):
 				#Create profile symlink
 				os.symlink(sub_profile_dir, os.path.join(user_config_dir, "make.profile"))
 
-				#Create minimal herds.xml
-				herds_xml = """<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE herds SYSTEM "http://www.gentoo.org/dtd/herds.dtd">
-<?xml-stylesheet href="/xsl/herds.xsl" type="text/xsl" ?>
-<?xml-stylesheet href="/xsl/guide.xsl" type="text/xsl" ?>
-<herds>
-<herd>
-  <name>base-system</name>
-  <email>base-system@gentoo.org</email>
-  <description>Core system utilities and libraries.</description>
-  <maintainer>
-    <email>base-system@gentoo.orgg</email>
-    <name>Base System</name>
-    <role>Base System Maintainer</role>
-  </maintainer>
-</herd>
-</herds>
-"""
-				with open(os.path.join(metadata_dir, "metadata.xml"), 'w') as f:
-					f.write(herds_xml)
-
 		make_conf = {
 			"ACCEPT_KEYWORDS": "x86",
 			"CLEAN_DELAY": "0",
-- 
2.8.1



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [gentoo-portage-dev] [PATCH 0/4] GLEP 67 + XML Schema, rebased against repoman
@ 2016-04-17  8:06 Michał Górny
  2016-04-17  8:06 ` [gentoo-portage-dev] [PATCH 1/4] tests: Stop using herds Michał Górny
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: Michał Górny @ 2016-04-17  8:06 UTC (permalink / raw
  To: gentoo-portage-dev; +Cc: Michał Górny

Same as before, rebased on top of repoman branch. Tested on git-mirror
checkout (with metadata/xml-schema dir) and local git checkout
(fetching from www). Travis also seems happy.

Michał Górny (4):
  tests: Stop using herds
  tests: Add type="" to <maintainer/>
  repoman: Use XML Schema for metadata.xml validation
  tests: Include metadata.xsd for repoman tests

 .travis.yml                                      |   4 +-
 MANIFEST.in                                      |   2 +-
 cnf/metadata.dtd                                 | 102 -----
 cnf/metadata.xsd                                 | 547 +++++++++++++++++++++++
 pym/portage/tests/emerge/test_simple.py          |   2 -
 pym/portage/tests/repoman/test_simple.py         |  11 +-
 pym/portage/tests/resolver/ResolverPlayground.py |  24 +-
 pym/repoman/_xml.py                              |  16 +-
 pym/repoman/metadata.py                          |  39 +-
 pym/repoman/modules/scan/metadata/__init__.py    |   2 +-
 pym/repoman/modules/scan/metadata/pkgmetadata.py |   6 +-
 pym/repoman/scanner.py                           |   8 +-
 12 files changed, 591 insertions(+), 172 deletions(-)
 delete mode 100644 cnf/metadata.dtd
 create mode 100644 cnf/metadata.xsd

-- 
2.8.1



^ permalink raw reply	[flat|nested] 7+ messages in thread

* [gentoo-portage-dev] [PATCH 1/4] tests: Stop using herds
  2016-04-17  8:06 [gentoo-portage-dev] [PATCH 0/4] GLEP 67 + XML Schema, rebased against repoman Michał Górny
@ 2016-04-17  8:06 ` Michał Górny
  2016-04-17  8:06 ` [gentoo-portage-dev] [PATCH 2/4] tests: Add type="" to <maintainer/> Michał Górny
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Michał Górny @ 2016-04-17  8:06 UTC (permalink / raw
  To: gentoo-portage-dev; +Cc: Michał Górny

---
 pym/portage/tests/emerge/test_simple.py          |  2 --
 pym/portage/tests/repoman/test_simple.py         |  3 ---
 pym/portage/tests/resolver/ResolverPlayground.py | 22 ----------------------
 3 files changed, 27 deletions(-)

diff --git a/pym/portage/tests/emerge/test_simple.py b/pym/portage/tests/emerge/test_simple.py
index 394ed43..e5ecd4b 100644
--- a/pym/portage/tests/emerge/test_simple.py
+++ b/pym/portage/tests/emerge/test_simple.py
@@ -153,14 +153,12 @@ pkg_preinst() {
 			(
 				"dev-libs/A",
 				{
-					"herd" : "base-system",
 					"flags" : "<flag name='flag'>Description of how USE='flag' affects this package</flag>",
 				},
 			),
 			(
 				"dev-libs/B",
 				{
-					"herd" : "no-herd",
 					"flags" : "<flag name='flag'>Description of how USE='flag' affects this package</flag>",
 				},
 			),
diff --git a/pym/portage/tests/repoman/test_simple.py b/pym/portage/tests/repoman/test_simple.py
index 98220c4..720560b 100644
--- a/pym/portage/tests/repoman/test_simple.py
+++ b/pym/portage/tests/repoman/test_simple.py
@@ -133,21 +133,18 @@ class SimpleRepomanTestCase(TestCase):
 			(
 				"dev-libs/A",
 				{
-					"herd" : "base-system",
 					"flags" : "<flag name='flag' restrict='&gt;=dev-libs/A-0'>Description of how USE='flag' affects this package</flag>",
 				},
 			),
 			(
 				"dev-libs/B",
 				{
-					"herd" : "no-herd",
 					"flags" : "<flag name='flag'>Description of how USE='flag' affects this package</flag>",
 				},
 			),
 			(
 				"dev-libs/C",
 				{
-					"herd" : "no-herd",
 					"flags" : "<flag name='flag'>Description of how USE='flag' affects this package</flag>",
 				},
 			),
diff --git a/pym/portage/tests/resolver/ResolverPlayground.py b/pym/portage/tests/resolver/ResolverPlayground.py
index 6bdf2c7..68e047a 100644
--- a/pym/portage/tests/resolver/ResolverPlayground.py
+++ b/pym/portage/tests/resolver/ResolverPlayground.py
@@ -47,7 +47,6 @@ class ResolverPlayground(object):
 	metadata_xml_template = """<?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE pkgmetadata SYSTEM "http://www.gentoo.org/dtd/metadata.dtd">
 <pkgmetadata>
-<herd>%(herd)s</herd>
 <maintainer>
 <email>maintainer-needed@gentoo.org</email>
 <description>Description of the maintainership</description>
@@ -381,27 +380,6 @@ class ResolverPlayground(object):
 				#Create profile symlink
 				os.symlink(sub_profile_dir, os.path.join(user_config_dir, "make.profile"))
 
-				#Create minimal herds.xml
-				herds_xml = """<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE herds SYSTEM "http://www.gentoo.org/dtd/herds.dtd">
-<?xml-stylesheet href="/xsl/herds.xsl" type="text/xsl" ?>
-<?xml-stylesheet href="/xsl/guide.xsl" type="text/xsl" ?>
-<herds>
-<herd>
-  <name>base-system</name>
-  <email>base-system@gentoo.org</email>
-  <description>Core system utilities and libraries.</description>
-  <maintainer>
-    <email>base-system@gentoo.orgg</email>
-    <name>Base System</name>
-    <role>Base System Maintainer</role>
-  </maintainer>
-</herd>
-</herds>
-"""
-				with open(os.path.join(metadata_dir, "metadata.xml"), 'w') as f:
-					f.write(herds_xml)
-
 		make_conf = {
 			"ACCEPT_KEYWORDS": "x86",
 			"CLEAN_DELAY": "0",
-- 
2.8.1



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [gentoo-portage-dev] [PATCH 2/4] tests: Add type="" to <maintainer/>
  2016-04-17  8:06 [gentoo-portage-dev] [PATCH 0/4] GLEP 67 + XML Schema, rebased against repoman Michał Górny
  2016-04-17  8:06 ` [gentoo-portage-dev] [PATCH 1/4] tests: Stop using herds Michał Górny
@ 2016-04-17  8:06 ` Michał Górny
  2016-04-17  8:06 ` [gentoo-portage-dev] [PATCH 3/4] repoman: Use XML Schema for metadata.xml validation Michał Górny
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Michał Górny @ 2016-04-17  8:06 UTC (permalink / raw
  To: gentoo-portage-dev; +Cc: Michał Górny

---
 pym/portage/tests/resolver/ResolverPlayground.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pym/portage/tests/resolver/ResolverPlayground.py b/pym/portage/tests/resolver/ResolverPlayground.py
index 68e047a..d1434f7 100644
--- a/pym/portage/tests/resolver/ResolverPlayground.py
+++ b/pym/portage/tests/resolver/ResolverPlayground.py
@@ -47,7 +47,7 @@ class ResolverPlayground(object):
 	metadata_xml_template = """<?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE pkgmetadata SYSTEM "http://www.gentoo.org/dtd/metadata.dtd">
 <pkgmetadata>
-<maintainer>
+<maintainer type="person">
 <email>maintainer-needed@gentoo.org</email>
 <description>Description of the maintainership</description>
 </maintainer>
-- 
2.8.1



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [gentoo-portage-dev] [PATCH 3/4] repoman: Use XML Schema for metadata.xml validation
  2016-04-17  8:06 [gentoo-portage-dev] [PATCH 0/4] GLEP 67 + XML Schema, rebased against repoman Michał Górny
  2016-04-17  8:06 ` [gentoo-portage-dev] [PATCH 1/4] tests: Stop using herds Michał Górny
  2016-04-17  8:06 ` [gentoo-portage-dev] [PATCH 2/4] tests: Add type="" to <maintainer/> Michał Górny
@ 2016-04-17  8:06 ` Michał Górny
  2016-04-17  8:06 ` [gentoo-portage-dev] [PATCH 4/4] tests: Include metadata.xsd for repoman tests Michał Górny
  2016-04-17 14:06 ` [gentoo-portage-dev] [PATCH 0/4] GLEP 67 + XML Schema, rebased against repoman Brian Dolbec
  4 siblings, 0 replies; 7+ messages in thread
From: Michał Górny @ 2016-04-17  8:06 UTC (permalink / raw
  To: gentoo-portage-dev; +Cc: Michał Górny

---
 pym/repoman/_xml.py                              | 16 +++++-----
 pym/repoman/metadata.py                          | 39 ++++++++++++------------
 pym/repoman/modules/scan/metadata/__init__.py    |  2 +-
 pym/repoman/modules/scan/metadata/pkgmetadata.py |  6 ++--
 pym/repoman/scanner.py                           |  8 ++---
 5 files changed, 36 insertions(+), 35 deletions(-)

diff --git a/pym/repoman/_xml.py b/pym/repoman/_xml.py
index d55dda5..33a536a 100644
--- a/pym/repoman/_xml.py
+++ b/pym/repoman/_xml.py
@@ -12,7 +12,7 @@ from portage import os
 from portage.output import red
 from portage.process import find_binary
 
-from repoman.metadata import fetch_metadata_dtd
+from repoman.metadata import fetch_metadata_xsd
 from repoman._subprocess import repoman_getstatusoutput
 
 
@@ -53,12 +53,12 @@ class _MetadataTreeBuilder(xml.etree.ElementTree.TreeBuilder):
 
 class XmlLint(object):
 
-	def __init__(self, options, repoman_settings, metadata_dtd=None):
-		self.metadata_dtd = (metadata_dtd or
-			os.path.join(repoman_settings["DISTDIR"], 'metadata.dtd'))
+	def __init__(self, options, repoman_settings, metadata_xsd=None):
+		self.metadata_xsd = (metadata_xsd or
+			os.path.join(repoman_settings["DISTDIR"], 'metadata.xsd'))
 		self.options = options
 		self.repoman_settings = repoman_settings
-		self._is_capable = metadata_dtd is not None
+		self._is_capable = metadata_xsd is not None
 		self.binary = None
 		self._check_capable()
 
@@ -69,7 +69,7 @@ class XmlLint(object):
 		if not self.binary:
 			print(red("!!! xmllint not found. Can't check metadata.xml.\n"))
 		elif not self._is_capable:
-			if not fetch_metadata_dtd(self.metadata_dtd, self.repoman_settings):
+			if not fetch_metadata_xsd(self.metadata_xsd, self.repoman_settings):
 				sys.exit(1)
 			# this can be problematic if xmllint changes their output
 			self._is_capable = True
@@ -93,8 +93,8 @@ class XmlLint(object):
 		# xmlint can produce garbage output even on success, so only dump
 		# the ouput when it fails.
 		st, out = repoman_getstatusoutput(
-			self.binary + " --nonet --noout --dtdvalid %s %s" % (
-				portage._shell_quote(self.metadata_dtd),
+			self.binary + " --nonet --noout --schema %s %s" % (
+				portage._shell_quote(self.metadata_xsd),
 				portage._shell_quote(
 					os.path.join(checkdir, "metadata.xml"))))
 		if st != os.EX_OK:
diff --git a/pym/repoman/metadata.py b/pym/repoman/metadata.py
index e95ad41..7a514dc 100644
--- a/pym/repoman/metadata.py
+++ b/pym/repoman/metadata.py
@@ -33,8 +33,9 @@ metadata_xml_declaration = '<?xml version="1.0" encoding="%s"?>' \
 	% (metadata_xml_encoding,)
 metadata_doctype_name = 'pkgmetadata'
 metadata_dtd_uri = 'http://www.gentoo.org/dtd/metadata.dtd'
+metadata_xsd_uri = 'http://www.gentoo.org/xml-schema/metadata.xsd'
 # force refetch if the local copy creation time is older than this
-metadata_dtd_ctime_interval = 60 * 60 * 24 * 7  # 7 days
+metadata_xsd_ctime_interval = 60 * 60 * 24 * 7  # 7 days
 
 
 def parse_metadata_use(xml_tree):
@@ -86,36 +87,36 @@ def parse_metadata_use(xml_tree):
 	return uselist
 
 
-def fetch_metadata_dtd(metadata_dtd, repoman_settings):
+def fetch_metadata_xsd(metadata_xsd, repoman_settings):
 	"""
-	Fetch metadata.dtd if it doesn't exist or the ctime is older than
-	metadata_dtd_ctime_interval.
+	Fetch metadata.xsd if it doesn't exist or the ctime is older than
+	metadata_xsd_ctime_interval.
 	@rtype: bool
 	@return: True if successful, otherwise False
 	"""
 
 	must_fetch = True
-	metadata_dtd_st = None
+	metadata_xsd_st = None
 	current_time = int(time.time())
 	try:
-		metadata_dtd_st = os.stat(metadata_dtd)
+		metadata_xsd_st = os.stat(metadata_xsd)
 	except EnvironmentError as e:
 		if e.errno not in (errno.ENOENT, errno.ESTALE):
 			raise
 		del e
 	else:
-		# Trigger fetch if metadata.dtd mtime is old or clock is wrong.
-		if abs(current_time - metadata_dtd_st.st_ctime) \
-			< metadata_dtd_ctime_interval:
+		# Trigger fetch if metadata.xsd mtime is old or clock is wrong.
+		if abs(current_time - metadata_xsd_st.st_ctime) \
+			< metadata_xsd_ctime_interval:
 			must_fetch = False
 
 	if must_fetch:
 		print()
 		print(
-			"%s the local copy of metadata.dtd "
+			"%s the local copy of metadata.xsd "
 			"needs to be refetched, doing that now" % green("***"))
 		print()
-		parsed_url = urlparse(metadata_dtd_uri)
+		parsed_url = urlparse(metadata_xsd_uri)
 		setting = 'FETCHCOMMAND_' + parsed_url.scheme.upper()
 		fcmd = repoman_settings.get(setting)
 		if not fcmd:
@@ -125,29 +126,29 @@ def fetch_metadata_dtd(metadata_dtd, repoman_settings):
 				return False
 
 		destdir = repoman_settings["DISTDIR"]
-		fd, metadata_dtd_tmp = tempfile.mkstemp(
-			prefix='metadata.dtd.', dir=destdir)
+		fd, metadata_xsd_tmp = tempfile.mkstemp(
+			prefix='metadata.xsd.', dir=destdir)
 		os.close(fd)
 
 		try:
 			if not portage.getbinpkg.file_get(
-				metadata_dtd_uri, destdir, fcmd=fcmd,
-				filename=os.path.basename(metadata_dtd_tmp)):
+				metadata_xsd_uri, destdir, fcmd=fcmd,
+				filename=os.path.basename(metadata_xsd_tmp)):
 				logging.error(
-					"failed to fetch metadata.dtd from '%s'" % metadata_dtd_uri)
+					"failed to fetch metadata.xsd from '%s'" % metadata_xsd_uri)
 				return False
 
 			try:
 				portage.util.apply_secpass_permissions(
-					metadata_dtd_tmp,
+					metadata_xsd_tmp,
 					gid=portage.data.portage_gid, mode=0o664, mask=0o2)
 			except portage.exception.PortageException:
 				pass
 
-			shutil.move(metadata_dtd_tmp, metadata_dtd)
+			shutil.move(metadata_xsd_tmp, metadata_xsd)
 		finally:
 			try:
-				os.unlink(metadata_dtd_tmp)
+				os.unlink(metadata_xsd_tmp)
 			except OSError:
 				pass
 
diff --git a/pym/repoman/modules/scan/metadata/__init__.py b/pym/repoman/modules/scan/metadata/__init__.py
index 90981d8..b2463fc 100644
--- a/pym/repoman/modules/scan/metadata/__init__.py
+++ b/pym/repoman/modules/scan/metadata/__init__.py
@@ -18,7 +18,7 @@ module_spec = {
 			'functions': ['check'],
 			'func_desc': {
 			},
-			'mod_kwargs': ['repo_settings', 'qatracker', 'options', 'metadata_dtd',
+			'mod_kwargs': ['repo_settings', 'qatracker', 'options', 'metadata_xsd',
 			],
 			'func_kwargs': {
 			},
diff --git a/pym/repoman/modules/scan/metadata/pkgmetadata.py b/pym/repoman/modules/scan/metadata/pkgmetadata.py
index 030cbca..fa73bb5 100644
--- a/pym/repoman/modules/scan/metadata/pkgmetadata.py
+++ b/pym/repoman/modules/scan/metadata/pkgmetadata.py
@@ -46,17 +46,17 @@ class PkgMetadata(ScanBase):
 		@param repo_settings: settings instance
 		@param qatracker: QATracker instance
 		@param options: argparse options instance
-		@param metadata_dtd: path of metadata.dtd
+		@param metadata_xsd: path of metadata.xsd
 		'''
 		super(PkgMetadata, self).__init__(**kwargs)
 		repo_settings = kwargs.get('repo_settings')
 		self.qatracker = kwargs.get('qatracker')
 		self.options = kwargs.get('options')
-		metadata_dtd = kwargs.get('metadata_dtd')
+		metadata_xsd = kwargs.get('metadata_xsd')
 		self.repoman_settings = repo_settings.repoman_settings
 		self.musedict = {}
 		self.xmllint = XmlLint(self.options, self.repoman_settings,
-			metadata_dtd=metadata_dtd)
+			metadata_xsd=metadata_xsd)
 
 	def check(self, **kwargs):
 		'''Performs the checks on the metadata.xml for the package
diff --git a/pym/repoman/scanner.py b/pym/repoman/scanner.py
index e9a8e20..0d17f74 100644
--- a/pym/repoman/scanner.py
+++ b/pym/repoman/scanner.py
@@ -54,11 +54,11 @@ class Scanner(object):
 			portage.util.stack_lists([self.categories], incremental=1))
 		self.categories = self.repo_settings.repoman_settings.categories
 
-		metadata_dtd = None
+		metadata_xsd = None
 		for path in reversed(self.repo_settings.repo_config.eclass_db.porttrees):
-			path = os.path.join(path, 'metadata/dtd/metadata.dtd')
+			path = os.path.join(path, 'metadata/xml-schema/metadata.xsd')
 			if os.path.exists(path):
-				metadata_dtd = path
+				metadata_xsd = path
 				break
 
 		self.portdb = repo_settings.portdb
@@ -184,7 +184,7 @@ class Scanner(object):
 			"qatracker": self.qatracker,
 			"vcs_settings": self.vcs_settings,
 			"options": self.options,
-			"metadata_dtd": metadata_dtd,
+			"metadata_xsd": metadata_xsd,
 			"uselist": uselist,
 			"checks": self.checks,
 			"repo_metadata": self.repo_metadata,
-- 
2.8.1



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [gentoo-portage-dev] [PATCH 4/4] tests: Include metadata.xsd for repoman tests
  2016-04-17  8:06 [gentoo-portage-dev] [PATCH 0/4] GLEP 67 + XML Schema, rebased against repoman Michał Górny
                   ` (2 preceding siblings ...)
  2016-04-17  8:06 ` [gentoo-portage-dev] [PATCH 3/4] repoman: Use XML Schema for metadata.xml validation Michał Górny
@ 2016-04-17  8:06 ` Michał Górny
  2016-04-17 14:06 ` [gentoo-portage-dev] [PATCH 0/4] GLEP 67 + XML Schema, rebased against repoman Brian Dolbec
  4 siblings, 0 replies; 7+ messages in thread
From: Michał Górny @ 2016-04-17  8:06 UTC (permalink / raw
  To: gentoo-portage-dev; +Cc: Michał Górny

---
 .travis.yml                              |   4 +-
 MANIFEST.in                              |   2 +-
 cnf/metadata.dtd                         | 102 ------
 cnf/metadata.xsd                         | 547 +++++++++++++++++++++++++++++++
 pym/portage/tests/repoman/test_simple.py |   8 +-
 5 files changed, 554 insertions(+), 109 deletions(-)
 delete mode 100644 cnf/metadata.dtd
 create mode 100644 cnf/metadata.xsd

diff --git a/.travis.yml b/.travis.yml
index b662d94..5213fee 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -8,8 +8,8 @@ python:
 script:
     - ./setup.py test
     - ./setup.py install --root=/tmp/install-root
-    # prevent repoman tests from trying to fetch metadata.dtd
+    # prevent repoman tests from trying to fetch metadata.xsd
     - mkdir -p /tmp/install-root/usr/lib/portage/cnf
-    - cp cnf/metadata.dtd /tmp/install-root/usr/lib/portage/cnf/
+    - cp cnf/metadata.xsd /tmp/install-root/usr/lib/portage/cnf/
     - sudo rsync -a /tmp/install-root/. /
     - python -b -Wd -m portage.tests.runTests
diff --git a/MANIFEST.in b/MANIFEST.in
index d65c874..2178460 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -12,7 +12,7 @@ include cnf/make.conf.example.*
 
 # extra files for tests
 include .portage_not_installed
-include cnf/metadata.dtd
+include cnf/metadata.xsd
 
 # extra scripts
 include misc/*
diff --git a/cnf/metadata.dtd b/cnf/metadata.dtd
deleted file mode 100644
index ff2649c..0000000
--- a/cnf/metadata.dtd
+++ /dev/null
@@ -1,102 +0,0 @@
-<!ELEMENT packages ( pkgmetadata* )>
-
-<!-- Metadata for a category -->
-<!ELEMENT catmetadata ( (longdescription)* )>
-<!ATTLIST catmetadata pkgname CDATA "">
-
-<!-- Metadata for a package -->
-<!ELEMENT pkgmetadata ( (herd|maintainer|natural-name|longdescription|use|upstream)* )>
-<!ATTLIST pkgmetadata pkgname CDATA "">
-
-  <!-- One tag for each herd this package is assigned to. -->
-  <!ELEMENT herd (#PCDATA)>
-
-  <!-- One tag for each maintainer of a package, multiple allowed-->
-  <!ELEMENT maintainer ( email, (description| name)* )>
-
-  <!-- Natural name for package, example: LibreOffice (for app-office/libreoffice) -->
-  <!ELEMENT natural-name (#PCDATA) >
-
-  <!-- A long description of the package in freetext-->
-  <!ELEMENT longdescription (#PCDATA|pkg|cat)* >
-
-  <!-- The changelog of the package-->
-  <!-- Please note that #PCDATA is mentioned only for the upstream changelog
-    element, where the content is a URL. This is due to limitations of the DTD -->
-  <!ELEMENT changelog (#PCDATA|change)* >
-    <!-- The changelog contains various "changes"-->
-    <!ELEMENT change (date,(developer|version|description|file|contributor|bug)*) >
-      <!ELEMENT date (#PCDATA) >
-        <!-- The date of the change, in "YYYY-MM-DD" format -->
-      <!ELEMENT developer (name?,email) >
-        <!-- The developer that made the change. The email is required, name
-	   is optional-->
-      <!ELEMENT version (#PCDATA) >
-        <!--version of the packages involved (one tag per version)-->
-      <!ELEMENT file (#PCDATA) ><!-- one tag per file touched -->
-      <!ELEMENT contributor (name?,email?) >
-        <!-- A reference to a user that helped in causing this change. 
-          There should at least be a name or email address included. 
-          Email is preferred -->
-      <!ELEMENT bug (#PCDATA) >
-        <!-- bug-id of a bug fixed by this change, multiple allowed. The 
-          format of this is a number or alias for a bug. NOT including a 
-          # character -->
-
-  <!-- description of what this USE flag does for this package -->
-  <!ELEMENT use (flag)* >
-    <!ELEMENT flag (#PCDATA|pkg|cat)* >
-      <!-- name attribute holds the name of the USE flag -->
-      <!ATTLIST flag name CDATA #REQUIRED >
-
-  <!-- upstream metadata information (maintainers, upstream docs,..) -->
-  <!ELEMENT upstream (maintainer|changelog|doc|bugs-to|remote-id)* >
-    <!-- Due to the limitation of DTD this will also allow a status
-      attribute for the package maintainer element. Please note that
-      the usage of the status attribute is nevertheless _only_ allowed
-      in the upstream maintainer element. -->
-    <!ATTLIST maintainer status (active|inactive|unknown) "unknown" >
-    <!-- URL where the location of the upstream documentation can be found -->
-    <!ELEMENT doc (#PCDATA)>
-      <!ATTLIST doc lang CDATA "C" >
-    <!-- location where to report bugs
-      (may also be an email address prefixed with mailto:) -->
-    <!ELEMENT bugs-to (#PCDATA)>
-    <!-- specify a type of package identification tracker -->
-    <!ELEMENT remote-id (#PCDATA)>
-      <!ATTLIST remote-id type (bitbucket|cpan|cpan-module|cpe|cran|ctan|freecode|freshmeat|github|gitorious|google-code|launchpad|pear|pecl|pypi|rubyforge|rubygems|sourceforge|sourceforge-jp|vim) #REQUIRED>
-
-  <!-- category/package information for cross-linking in descriptions
-    and useflag descriptions -->
-  <!ELEMENT pkg (#PCDATA) >
-  <!ELEMENT cat (#PCDATA) >
-          
-<!-- Common attributes -->
-
-<!-- the lang attribute, specifies the language of this tag. This is 
-  only useful for descriptions of various kinds. If a tag with this 
-  attribute is included there must be a description in the default 
-  language "C" or "en", which is equivalent -->
-  <!ATTLIST description lang CDATA "C" >
-  <!ATTLIST longdescription lang CDATA "C" >
-  <!ATTLIST use lang CDATA "C" >
-
-<!-- The restrict attribute, this attribute specifies restrictions on 
-  the applicability of tags on versions. The format of this attribute is 
-  equal to the format of DEPEND lines in ebuilds. There is one special 
-  value though: restrict="*". A tag that specifies this only applies if 
-  there are no other tags that apply.
-  
-  For required tags, there must be either an unrestricted version, or a 
-  version that is default restricted. -->
-  <!ATTLIST herd restrict CDATA #IMPLIED >
-  <!ATTLIST maintainer restrict CDATA #IMPLIED >
-  <!ATTLIST longdescription restrict CDATA #IMPLIED >
-  <!ATTLIST flag restrict CDATA #IMPLIED >
-
-
-
-<!-- standard parts -->
-<!ELEMENT email (#PCDATA) ><!-- an email address -->
-<!ELEMENT name (#PCDATA) ><!-- the name of a person (maintainer, contributor)-->
-<!ELEMENT description (#PCDATA) ><!-- A description of a maintainer or change-->
diff --git a/cnf/metadata.xsd b/cnf/metadata.xsd
new file mode 100644
index 0000000..0ead09e
--- /dev/null
+++ b/cnf/metadata.xsd
@@ -0,0 +1,547 @@
+<?xml version='1.0' encoding='UTF-8'?>
+
+<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'>
+	<!-- top-level variants -->
+	<xs:element name='pkgmetadata' type='pkgMetadataType'>
+		<!-- note: restrict uniquity rules are simplified
+			 the spec says: one for each matched package
+			 we can only do: one for each restrict rule -->
+		<xs:unique name='longDescUniquityConstraint'>
+			<xs:selector xpath='longdescription'/>
+			<xs:field xpath='@lang'/>
+			<xs:field xpath='@restrict'/>
+		</xs:unique>
+		<xs:unique name='maintainerUniquityConstraint'>
+			<xs:selector xpath='maintainer'/>
+			<xs:field xpath='email'/>
+			<xs:field xpath='@restrict'/>
+		</xs:unique>
+		<xs:unique name='slotsUniquityConstraint'>
+			<xs:selector xpath='slots'/>
+			<xs:field xpath='@lang'/>
+		</xs:unique>
+		<xs:unique name='upstreamSingleConstraint'>
+			<xs:selector xpath='upstream'/>
+			<xs:field xpath='@fake-only-once'/>
+		</xs:unique>
+		<xs:unique name='useUniquityConstraint'>
+			<xs:selector xpath='use'/>
+			<xs:field xpath='@lang'/>
+		</xs:unique>
+	</xs:element>
+	<xs:element name='catmetadata' type='catMetadataType'>
+		<xs:unique name='catLongDescUniquityConstraint'>
+			<xs:selector xpath='longdescription'/>
+			<xs:field xpath='@lang'/>
+		</xs:unique>
+	</xs:element>
+
+	<!-- global elements -->
+	<xs:complexType name='pkgMetadataType'>
+		<xs:choice minOccurs='0' maxOccurs='unbounded'>
+			<xs:element name='longdescription' type='longDescType'/>
+			<xs:element name='maintainer' type='maintainerType'>
+				<xs:unique name='maintainerDescUniquityConstraint'>
+					<xs:selector xpath='description'/>
+					<xs:field xpath='@lang'/>
+				</xs:unique>
+			</xs:element>
+			<xs:element name='slots' type='slotsType'>
+				<xs:unique name='slotUniquityConstraint'>
+					<xs:selector xpath='slot'/>
+					<xs:field xpath='@name'/>
+				</xs:unique>
+				<xs:unique name='subslotsSingleConstraint'>
+					<xs:selector xpath='subslots'/>
+					<xs:field xpath='@fake-only-once'/>
+				</xs:unique>
+			</xs:element>
+			<xs:element name='upstream' type='upstreamType'>
+				<xs:unique name='bugsToSingleConstraint'>
+					<xs:selector xpath='bugs-to'/>
+					<xs:field xpath='@fake-only-once'/>
+				</xs:unique>
+				<xs:unique name='changelogSingleConstraint'>
+					<xs:selector xpath='changelog'/>
+					<xs:field xpath='@fake-only-once'/>
+				</xs:unique>
+				<!-- prevent accidentally repeating the same remote -->
+				<xs:unique name='upstreamRemoteIdRepetitionConstraint'>
+					<xs:selector xpath='remote-id'/>
+					<xs:field xpath='@type'/>
+					<xs:field xpath='.'/>
+				</xs:unique>
+				<xs:unique name='upstreamDocUniquityConstraint'>
+					<xs:selector xpath='doc'/>
+					<xs:field xpath='@lang'/>
+				</xs:unique>
+			</xs:element>
+			<xs:element name='use' type='useType'>
+				<xs:unique name='flagUniquityConstraint'>
+					<xs:selector xpath='flag'/>
+					<xs:field xpath='@name'/>
+					<xs:field xpath='@restrict'/>
+				</xs:unique>
+			</xs:element>
+		</xs:choice>
+	</xs:complexType>
+
+	<xs:complexType name='catMetadataType'>
+		<xs:choice minOccurs='0' maxOccurs='unbounded'>
+			<xs:element name='longdescription' type='catLongDescType'/>
+		</xs:choice>
+	</xs:complexType>
+
+	<!-- the huge <upstream/> structure -->
+	<xs:complexType name='upstreamType'>
+		<xs:choice minOccurs='0' maxOccurs='unbounded'>
+			<xs:element name='maintainer' type='upstreamMaintainerType'>
+				<xs:unique name='upstreamMaintainerUniquityConstraint'>
+					<xs:selector xpath='maintainer'/>
+					<xs:field xpath='name'/>
+				</xs:unique>
+			</xs:element>
+			<xs:element name='changelog' type='urlOnceType'/>
+			<xs:element name='doc' type='upstreamDocType'/>
+			<xs:element name='bugs-to' type='urlOnceType'/>
+			<xs:element name='remote-id' type='upstreamRemoteIdType'/>
+		</xs:choice>
+		<xs:attribute name='fake-only-once'
+			fixed='there can be at most one &lt;upstream/&gt; element'/>
+	</xs:complexType>
+
+	<!-- maintainer in two variants -->
+	<xs:complexType name='maintainerType'>
+		<xs:all>
+			<xs:element name='email' type='emailType'
+				minOccurs='1'/>
+			<xs:element name='name' type='xs:token'
+				minOccurs='0'/>
+			<xs:element name='description' type='maintainerDescType'
+				minOccurs='0'/>
+		</xs:all>
+		<xs:attribute name='type' type='maintainerTypeAttrType'
+			use='required'/>
+		<xs:attribute name='restrict' type='restrictAttrType'/>
+	</xs:complexType>
+
+	<xs:simpleType name='maintainerTypeAttrType'>
+		<xs:restriction base='xs:token'>
+			<xs:enumeration value='person'/>
+			<xs:enumeration value='project'/>
+		</xs:restriction>
+	</xs:simpleType>
+
+	<xs:complexType name='upstreamMaintainerType'>
+		<xs:all>
+			<xs:element name='email' type='emailType'
+				minOccurs='0'/>
+			<xs:element name='name' type='xs:token'
+				minOccurs='0'/>
+		</xs:all>
+		<xs:attribute name='status' type='upstreamMaintainerStatusAttrType'
+			default='unknown'/>
+	</xs:complexType>
+
+	<xs:simpleType name='upstreamMaintainerStatusAttrType'>
+		<xs:restriction base='xs:token'>
+			<xs:enumeration value='active'/>
+			<xs:enumeration value='inactive'/>
+			<xs:enumeration value='unknown'/>
+		</xs:restriction>
+	</xs:simpleType>
+
+	<xs:complexType name='maintainerDescType'>
+		<xs:simpleContent>
+			<xs:extension base="xs:token">
+				<xs:attribute name='lang' type='langAttrType' default='en'/>
+			</xs:extension>
+		</xs:simpleContent>
+	</xs:complexType>
+
+	<!-- long description -->
+	<xs:complexType name='longDescType' mixed='true'>
+		<xs:choice minOccurs='0' maxOccurs='unbounded'>
+			<xs:element name='pkg' type='pkgType'/>
+			<xs:element name='cat' type='catType'/>
+		</xs:choice>
+		<xs:attribute name='lang' type='langAttrType' default='en'/>
+		<xs:attribute name='restrict' type='restrictAttrType'/>
+	</xs:complexType>
+
+	<xs:complexType name='catLongDescType' mixed='true'>
+		<xs:choice minOccurs='0' maxOccurs='unbounded'>
+			<xs:element name='pkg' type='pkgType'/>
+			<xs:element name='cat' type='catType'/>
+		</xs:choice>
+		<xs:attribute name='lang' type='langAttrType' default='en'/>
+	</xs:complexType>
+
+	<!-- slots -->
+	<xs:complexType name='slotsType'>
+		<xs:choice minOccurs='0' maxOccurs='unbounded'>
+			<xs:element name='slot' type='slotType'/>
+			<xs:element name='subslots' type='tokenOnceType'/>
+		</xs:choice>
+		<xs:attribute name='lang' type='langAttrType' default='en'/>
+	</xs:complexType>
+
+	<xs:complexType name='slotType'>
+		<xs:simpleContent>
+			<xs:extension base="xs:token">
+				<xs:attribute name='name' type='slotNameAttrType'
+					use='required'/>
+			</xs:extension>
+		</xs:simpleContent>
+	</xs:complexType>
+
+	<xs:simpleType name='slotNameAttrType'>
+		<xs:restriction base='xs:token'>
+			<!-- PMS 3.1.3 Slot Names + special value '*' -->
+			<xs:pattern value="[A-Za-z0-9_][A-Za-z0-9+_.-]*|[*]"/>
+		</xs:restriction>
+	</xs:simpleType>
+
+	<!-- use flags -->
+	<xs:complexType name='useType'>
+		<xs:choice minOccurs='0' maxOccurs='unbounded'>
+			<xs:element name='flag' type='flagType'/>
+		</xs:choice>
+		<xs:attribute name='lang' type='langAttrType' default='en'/>
+	</xs:complexType>
+
+	<xs:complexType name='flagType' mixed='true'>
+		<xs:choice minOccurs='0' maxOccurs='unbounded'>
+			<xs:element name='cat' type='catType'/>
+			<xs:element name='pkg' type='pkgType'/>
+		</xs:choice>
+		<xs:attribute name='name' type='flagNameAttrType'
+			use='required'/>
+		<xs:attribute name='restrict' type='restrictAttrType'
+			default=''/>
+	</xs:complexType>
+
+	<xs:simpleType name='flagNameAttrType'>
+		<xs:restriction base='xs:token'>
+			<!-- PMS 3.1.4 USE Flag Names -->
+			<xs:pattern value="[A-Za-z0-9][A-Za-z0-9+_@-]*"/>
+		</xs:restriction>
+	</xs:simpleType>
+
+	<!-- upstream-specific types -->
+	<xs:complexType name='upstreamDocType'>
+		<xs:simpleContent>
+			<xs:extension base="urlType">
+				<xs:attribute name='lang' type='langAttrType' default='en'/>
+			</xs:extension>
+		</xs:simpleContent>
+	</xs:complexType>
+
+	<xs:complexType name='upstreamRemoteIdType'>
+		<xs:simpleContent>
+			<xs:extension base="xs:token">
+				<xs:attribute name='type' type='upstreamRemoteIdTypeAttrType'
+					use='required'/>
+			</xs:extension>
+		</xs:simpleContent>
+	</xs:complexType>
+
+	<xs:simpleType name='upstreamRemoteIdTypeAttrType'>
+		<xs:restriction base='xs:token'>
+			<xs:enumeration value='bitbucket'/>
+			<xs:enumeration value='cpan'/>
+			<xs:enumeration value='cpan-module'/>
+			<xs:enumeration value='cpe'/>
+			<xs:enumeration value='cran'/>
+			<xs:enumeration value='ctan'/>
+			<xs:enumeration value='freecode'/>
+			<xs:enumeration value='freshmeat'/>
+			<xs:enumeration value='github'/>
+			<xs:enumeration value='gitlab'/>
+			<xs:enumeration value='gitorious'/>
+			<xs:enumeration value='google-code'/>
+			<xs:enumeration value='launchpad'/>
+			<xs:enumeration value='pear'/>
+			<xs:enumeration value='pecl'/>
+			<xs:enumeration value='pypi'/>
+			<xs:enumeration value='rubyforge'/>
+			<xs:enumeration value='rubygems'/>
+			<xs:enumeration value='sourceforge'/>
+			<xs:enumeration value='sourceforge-jp'/>
+			<xs:enumeration value='vim'/>
+		</xs:restriction>
+	</xs:simpleType>
+
+	<!-- creepy mixed-text types -->
+	<xs:simpleType name='catType'>
+		<xs:restriction base='xs:token'>
+			<!-- PMS 3.1.1 Category Names -->
+			<xs:pattern value="[A-Za-z0-9_][A-Za-z0-9+_.-]*"/>
+		</xs:restriction>
+	</xs:simpleType>
+	<xs:simpleType name='pkgType'>
+		<xs:restriction base='xs:token'>
+			<!-- PMS 3.1.1 Category Names + 3.1.2 Package Names -->
+			<!-- note: this does not enforce the 'anything matching
+				 the version syntax' requirement -->
+			<xs:pattern
+				value="[A-Za-z0-9_][A-Za-z0-9+_.-]*/[A-Za-z0-9_][A-Za-z0-9+_-]*"/>
+		</xs:restriction>
+	</xs:simpleType>
+
+	<!-- common attributes -->
+	<xs:simpleType name='langAttrType'>
+		<xs:restriction base='xs:token'>
+			<!-- ISO 639-1 language codes -->
+			<xs:enumeration value='aa'/>
+			<xs:enumeration value='ab'/>
+			<xs:enumeration value='ae'/>
+			<xs:enumeration value='af'/>
+			<xs:enumeration value='ak'/>
+			<xs:enumeration value='am'/>
+			<xs:enumeration value='an'/>
+			<xs:enumeration value='ar'/>
+			<xs:enumeration value='as'/>
+			<xs:enumeration value='av'/>
+			<xs:enumeration value='ay'/>
+			<xs:enumeration value='az'/>
+			<xs:enumeration value='ba'/>
+			<xs:enumeration value='be'/>
+			<xs:enumeration value='bg'/>
+			<xs:enumeration value='bh'/>
+			<xs:enumeration value='bi'/>
+			<xs:enumeration value='bm'/>
+			<xs:enumeration value='bn'/>
+			<xs:enumeration value='bo'/>
+			<xs:enumeration value='bo'/>
+			<xs:enumeration value='br'/>
+			<xs:enumeration value='bs'/>
+			<xs:enumeration value='ca'/>
+			<xs:enumeration value='ce'/>
+			<xs:enumeration value='ch'/>
+			<xs:enumeration value='co'/>
+			<xs:enumeration value='cr'/>
+			<xs:enumeration value='cs'/>
+			<xs:enumeration value='cs'/>
+			<xs:enumeration value='cu'/>
+			<xs:enumeration value='cv'/>
+			<xs:enumeration value='cy'/>
+			<xs:enumeration value='cy'/>
+			<xs:enumeration value='da'/>
+			<xs:enumeration value='de'/>
+			<xs:enumeration value='de'/>
+			<xs:enumeration value='dv'/>
+			<xs:enumeration value='dz'/>
+			<xs:enumeration value='ee'/>
+			<xs:enumeration value='el'/>
+			<xs:enumeration value='el'/>
+			<xs:enumeration value='en'/>
+			<xs:enumeration value='eo'/>
+			<xs:enumeration value='es'/>
+			<xs:enumeration value='et'/>
+			<xs:enumeration value='eu'/>
+			<xs:enumeration value='eu'/>
+			<xs:enumeration value='fa'/>
+			<xs:enumeration value='fa'/>
+			<xs:enumeration value='ff'/>
+			<xs:enumeration value='fi'/>
+			<xs:enumeration value='fj'/>
+			<xs:enumeration value='fo'/>
+			<xs:enumeration value='fr'/>
+			<xs:enumeration value='fr'/>
+			<xs:enumeration value='fy'/>
+			<xs:enumeration value='ga'/>
+			<xs:enumeration value='ga'/>
+			<xs:enumeration value='Ga'/>
+			<xs:enumeration value='gd'/>
+			<xs:enumeration value='gl'/>
+			<xs:enumeration value='gn'/>
+			<xs:enumeration value='gu'/>
+			<xs:enumeration value='gv'/>
+			<xs:enumeration value='ha'/>
+			<xs:enumeration value='he'/>
+			<xs:enumeration value='hi'/>
+			<xs:enumeration value='ho'/>
+			<xs:enumeration value='hr'/>
+			<xs:enumeration value='ht'/>
+			<xs:enumeration value='hu'/>
+			<xs:enumeration value='hy'/>
+			<xs:enumeration value='hy'/>
+			<xs:enumeration value='hz'/>
+			<xs:enumeration value='ia'/>
+			<xs:enumeration value='id'/>
+			<xs:enumeration value='ie'/>
+			<xs:enumeration value='ig'/>
+			<xs:enumeration value='ii'/>
+			<xs:enumeration value='ik'/>
+			<xs:enumeration value='io'/>
+			<xs:enumeration value='is'/>
+			<xs:enumeration value='is'/>
+			<xs:enumeration value='it'/>
+			<xs:enumeration value='iu'/>
+			<xs:enumeration value='ja'/>
+			<xs:enumeration value='jv'/>
+			<xs:enumeration value='ka'/>
+			<xs:enumeration value='ka'/>
+			<xs:enumeration value='kg'/>
+			<xs:enumeration value='ki'/>
+			<xs:enumeration value='kj'/>
+			<xs:enumeration value='kk'/>
+			<xs:enumeration value='kl'/>
+			<xs:enumeration value='km'/>
+			<xs:enumeration value='kn'/>
+			<xs:enumeration value='ko'/>
+			<xs:enumeration value='kr'/>
+			<xs:enumeration value='ks'/>
+			<xs:enumeration value='ku'/>
+			<xs:enumeration value='kv'/>
+			<xs:enumeration value='kw'/>
+			<xs:enumeration value='ky'/>
+			<xs:enumeration value='la'/>
+			<xs:enumeration value='lb'/>
+			<xs:enumeration value='lg'/>
+			<xs:enumeration value='li'/>
+			<xs:enumeration value='ln'/>
+			<xs:enumeration value='lo'/>
+			<xs:enumeration value='lt'/>
+			<xs:enumeration value='lu'/>
+			<xs:enumeration value='lv'/>
+			<xs:enumeration value='mg'/>
+			<xs:enumeration value='mh'/>
+			<xs:enumeration value='mi'/>
+			<xs:enumeration value='mi'/>
+			<xs:enumeration value='mk'/>
+			<xs:enumeration value='mk'/>
+			<xs:enumeration value='ml'/>
+			<xs:enumeration value='mn'/>
+			<xs:enumeration value='mr'/>
+			<xs:enumeration value='ms'/>
+			<xs:enumeration value='ms'/>
+			<xs:enumeration value='mt'/>
+			<xs:enumeration value='my'/>
+			<xs:enumeration value='my'/>
+			<xs:enumeration value='na'/>
+			<xs:enumeration value='nb'/>
+			<xs:enumeration value='nd'/>
+			<xs:enumeration value='ne'/>
+			<xs:enumeration value='ng'/>
+			<xs:enumeration value='nl'/>
+			<xs:enumeration value='nl'/>
+			<xs:enumeration value='nn'/>
+			<xs:enumeration value='no'/>
+			<xs:enumeration value='nr'/>
+			<xs:enumeration value='nv'/>
+			<xs:enumeration value='ny'/>
+			<xs:enumeration value='oc'/>
+			<xs:enumeration value='oj'/>
+			<xs:enumeration value='om'/>
+			<xs:enumeration value='or'/>
+			<xs:enumeration value='os'/>
+			<xs:enumeration value='pa'/>
+			<xs:enumeration value='pi'/>
+			<xs:enumeration value='pl'/>
+			<xs:enumeration value='ps'/>
+			<xs:enumeration value='pt'/>
+			<xs:enumeration value='qu'/>
+			<xs:enumeration value='rm'/>
+			<xs:enumeration value='rn'/>
+			<xs:enumeration value='ro'/>
+			<xs:enumeration value='ro'/>
+			<xs:enumeration value='ru'/>
+			<xs:enumeration value='rw'/>
+			<xs:enumeration value='sa'/>
+			<xs:enumeration value='sc'/>
+			<xs:enumeration value='sd'/>
+			<xs:enumeration value='se'/>
+			<xs:enumeration value='sg'/>
+			<xs:enumeration value='si'/>
+			<xs:enumeration value='sk'/>
+			<xs:enumeration value='sk'/>
+			<xs:enumeration value='sl'/>
+			<xs:enumeration value='sm'/>
+			<xs:enumeration value='sn'/>
+			<xs:enumeration value='so'/>
+			<xs:enumeration value='sq'/>
+			<xs:enumeration value='sq'/>
+			<xs:enumeration value='sr'/>
+			<xs:enumeration value='ss'/>
+			<xs:enumeration value='st'/>
+			<xs:enumeration value='su'/>
+			<xs:enumeration value='sv'/>
+			<xs:enumeration value='sw'/>
+			<xs:enumeration value='ta'/>
+			<xs:enumeration value='te'/>
+			<xs:enumeration value='tg'/>
+			<xs:enumeration value='th'/>
+			<xs:enumeration value='ti'/>
+			<xs:enumeration value='tk'/>
+			<xs:enumeration value='tl'/>
+			<xs:enumeration value='tn'/>
+			<xs:enumeration value='to'/>
+			<xs:enumeration value='tr'/>
+			<xs:enumeration value='ts'/>
+			<xs:enumeration value='tt'/>
+			<xs:enumeration value='tw'/>
+			<xs:enumeration value='ty'/>
+			<xs:enumeration value='ug'/>
+			<xs:enumeration value='uk'/>
+			<xs:enumeration value='ur'/>
+			<xs:enumeration value='uz'/>
+			<xs:enumeration value='ve'/>
+			<xs:enumeration value='vi'/>
+			<xs:enumeration value='vo'/>
+			<xs:enumeration value='wa'/>
+			<xs:enumeration value='wo'/>
+			<xs:enumeration value='xh'/>
+			<xs:enumeration value='yi'/>
+			<xs:enumeration value='yo'/>
+			<xs:enumeration value='za'/>
+			<xs:enumeration value='zh'/>
+			<xs:enumeration value='zh'/>
+			<xs:enumeration value='zu'/>
+		</xs:restriction>
+	</xs:simpleType>
+
+	<xs:simpleType name='restrictAttrType'>
+		<xs:restriction base='xs:token'>
+			<!-- simplified package dependency syntax -->
+			<!-- note: 'pure' package atom is technically valid too
+				 but not really meaningful -->
+			<xs:pattern
+				value="(([&lt;&gt;]=?|[=~])[A-Za-z0-9_][A-Za-z0-9+_.-]*/[A-Za-z0-9_][A-Za-z0-9+_-]*-[0-9]+(\.[0-9]+)*[a-z]?((_alpha|_beta|_pre|_rc|_p)[0-9]*)*(-r[0-9]+)?\*?)?"/>
+		</xs:restriction>
+	</xs:simpleType>
+
+	<!-- generic types -->
+	<xs:simpleType name='emailType'>
+		<xs:restriction base='xs:token'>
+			<!-- minimal safe regex -->
+			<xs:pattern value="[^@]+@[^.]+\..+"/>
+		</xs:restriction>
+	</xs:simpleType>
+
+	<xs:complexType name='tokenOnceType'>
+		<xs:simpleContent>
+			<xs:extension base="xs:token">
+				<xs:attribute name='fake-only-once'
+					fixed='there can be at most one element of this type'/>
+			</xs:extension>
+		</xs:simpleContent>
+	</xs:complexType>
+
+	<xs:simpleType name='urlType'>
+		<xs:restriction base='xs:token'>
+			<!-- TODO: something better? -->
+			<xs:pattern value="(mailto:[^@]+@[^.]+\..+|https?://.+)"/>
+		</xs:restriction>
+	</xs:simpleType>
+
+	<xs:complexType name='urlOnceType'>
+		<xs:simpleContent>
+			<xs:extension base="urlType">
+				<xs:attribute name='fake-only-once'
+					fixed='there can be at most one element of this type'/>
+			</xs:extension>
+		</xs:simpleContent>
+	</xs:complexType>
+</xs:schema>
diff --git a/pym/portage/tests/repoman/test_simple.py b/pym/portage/tests/repoman/test_simple.py
index 720560b..6a79761 100644
--- a/pym/portage/tests/repoman/test_simple.py
+++ b/pym/portage/tests/repoman/test_simple.py
@@ -128,7 +128,7 @@ class SimpleRepomanTestCase(TestCase):
 		}
 		licenses = ["GPL-2"]
 		arch_list = ["x86"]
-		metadata_dtd = os.path.join(PORTAGE_BASE_PATH, "cnf/metadata.dtd")
+		metadata_xsd = os.path.join(PORTAGE_BASE_PATH, "cnf/metadata.xsd")
 		metadata_xml_files = (
 			(
 				"dev-libs/A",
@@ -269,9 +269,9 @@ class SimpleRepomanTestCase(TestCase):
 			# involving canonical vs. non-canonical paths.
 			test_repo_symlink = os.path.join(eroot, "test_repo_symlink")
 			os.symlink(test_repo_location, test_repo_symlink)
-			metadata_dtd_dest = os.path.join(test_repo_location, 'metadata/dtd/metadata.dtd')
-			os.makedirs(os.path.dirname(metadata_dtd_dest))
-			os.symlink(metadata_dtd, metadata_dtd_dest)
+			metadata_xsd_dest = os.path.join(test_repo_location, 'metadata/xml-schema/metadata.xsd')
+			os.makedirs(os.path.dirname(metadata_xsd_dest))
+			os.symlink(metadata_xsd, metadata_xsd_dest)
 
 			if debug:
 				# The subprocess inherits both stdout and stderr, for
-- 
2.8.1



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [gentoo-portage-dev] [PATCH 0/4] GLEP 67 + XML Schema, rebased against repoman
  2016-04-17  8:06 [gentoo-portage-dev] [PATCH 0/4] GLEP 67 + XML Schema, rebased against repoman Michał Górny
                   ` (3 preceding siblings ...)
  2016-04-17  8:06 ` [gentoo-portage-dev] [PATCH 4/4] tests: Include metadata.xsd for repoman tests Michał Górny
@ 2016-04-17 14:06 ` Brian Dolbec
  4 siblings, 0 replies; 7+ messages in thread
From: Brian Dolbec @ 2016-04-17 14:06 UTC (permalink / raw
  To: gentoo-portage-dev

On Sun, 17 Apr 2016 10:06:25 +0200
Michał Górny <mgorny@gentoo.org> wrote:

> Same as before, rebased on top of repoman branch. Tested on git-mirror
> checkout (with metadata/xml-schema dir) and local git checkout
> (fetching from www). Travis also seems happy.
> 
> Michał Górny (4):
>   tests: Stop using herds
>   tests: Add type="" to <maintainer/>
>   repoman: Use XML Schema for metadata.xml validation
>   tests: Include metadata.xsd for repoman tests
> 
>  .travis.yml                                      |   4 +-
>  MANIFEST.in                                      |   2 +-
>  cnf/metadata.dtd                                 | 102 -----
>  cnf/metadata.xsd                                 | 547
> +++++++++++++++++++++++
> pym/portage/tests/emerge/test_simple.py          |   2 -
> pym/portage/tests/repoman/test_simple.py         |  11 +-
> pym/portage/tests/resolver/ResolverPlayground.py |  24 +-
> pym/repoman/_xml.py                              |  16 +-
> pym/repoman/metadata.py                          |  39 +-
> pym/repoman/modules/scan/metadata/__init__.py    |   2 +-
> pym/repoman/modules/scan/metadata/pkgmetadata.py |   6 +-
> pym/repoman/scanner.py                           |   8 +- 12 files
> changed, 591 insertions(+), 172 deletions(-) delete mode 100644
> cnf/metadata.dtd create mode 100644 cnf/metadata.xsd
> 

Thank you

-- 
Brian Dolbec <dolsen>



^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2016-04-17 14:07 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-04-17  8:06 [gentoo-portage-dev] [PATCH 0/4] GLEP 67 + XML Schema, rebased against repoman Michał Górny
2016-04-17  8:06 ` [gentoo-portage-dev] [PATCH 1/4] tests: Stop using herds Michał Górny
2016-04-17  8:06 ` [gentoo-portage-dev] [PATCH 2/4] tests: Add type="" to <maintainer/> Michał Górny
2016-04-17  8:06 ` [gentoo-portage-dev] [PATCH 3/4] repoman: Use XML Schema for metadata.xml validation Michał Górny
2016-04-17  8:06 ` [gentoo-portage-dev] [PATCH 4/4] tests: Include metadata.xsd for repoman tests Michał Górny
2016-04-17 14:06 ` [gentoo-portage-dev] [PATCH 0/4] GLEP 67 + XML Schema, rebased against repoman Brian Dolbec
  -- strict thread matches above, loose matches on Subject: below --
2016-04-16 18:06 [gentoo-portage-dev] [PATCH 0/4] GLEP 67 test cleanup & XML Schema for repoman Michał Górny
2016-04-16 18:06 ` [gentoo-portage-dev] [PATCH 1/4] tests: Stop using herds Michał Górny

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox