diff --git a/run.n b/run.n index b338a05d..649c50a3 100644 Binary files a/run.n and b/run.n differ diff --git a/schema.json b/schema.json index 4faf9e65..c27d38c1 100644 --- a/schema.json +++ b/schema.json @@ -47,6 +47,21 @@ }, "additionalProperties": false }, + "documentation": { + "type": "object", + "description": "Project's documentation resources", + "properties": { + "defines": { + "type": "string", + "description": "Relative path to json file describing this project's custom defines" + }, + "metadata": { + "type": "string", + "description": "Relative path to json file describing this project's custom metadata" + } + }, + "additionalProperties": false + }, "releasenote": { "description": "Short description of changes made in this version", "type": "string" diff --git a/src/haxelib/Data.hx b/src/haxelib/Data.hx index e76670b2..6eff8f63 100644 --- a/src/haxelib/Data.hx +++ b/src/haxelib/Data.hx @@ -152,7 +152,35 @@ typedef Infos = { var contributors : Array; @:optional var tags : Array; @:optional var dependencies : Dependencies; - @:optional var main:String; + @:optional var main : String; + @:optional var documentation : LibraryDocumentation; +} + +/** Documentation data held in the `documentation` field of the `haxelib.json` file. **/ +typedef LibraryDocumentation = { + @:optional var defines : String; + @:optional var metadata : String; +} + +/** Metadata documentation data as should be declared in the json linked in the + * `documentation.metadata` field of the `haxelib.json` file. **/ +typedef MetadataDocumentation = { + var metadata : String; + var doc : String; + @:optional var platforms : Array; + @:optional var params : Array; + @:optional var targets : Array; + @:optional var links : Array; +} + +/** Define documentation data as should be declared in the json linked in the + * `documentation.defines` field of the `haxelib.json` file. **/ +typedef DefineDocumentation = { + var define : String; + var doc : String; + @:optional var platforms : Array; + @:optional var params : Array; + @:optional var links : Array; } /** An abstract enum representing the different Licenses a project can have. **/ @@ -263,6 +291,48 @@ class Data { } } + /** Throws an exception if files referenced in `documentation` field of an `infos` do not exist or are invalid **/ + public static function checkDocumentation( zip : List, infos : Infos ) { + if (infos.documentation == null) return; + + var hasDefines = infos.documentation.defines == null; + var hasMetadata = infos.documentation.metadata == null; + if (!hasDefines && !hasMetadata) return; + + var basePath = Data.locateBasePath(zip); + var definesPath = hasDefines ? null : basePath + infos.documentation.defines; + var metadataPath = hasMetadata ? null : basePath + infos.documentation.metadata; + var definesFound = false; + var metadataFound = false; + + for (f in zip) { + if (hasDefines && StringTools.startsWith(f.fileName, definesPath)) { + definesFound = true; + try { + var jsondata = Reader.unzip(f).toString(); + var defines:Array = Json.parse(jsondata); + Validator.validate(defines); + } catch (_:Dynamic) { + throw 'Defines documentation json file does not match expected format'; + } + } else if (hasMetadata && StringTools.startsWith(f.fileName, metadataPath)) { + metadataFound = true; + try { + var jsondata = Reader.unzip(f).toString(); + var metas:Array = Json.parse(jsondata); + Validator.validate(metas); + } catch (_:Dynamic) { + throw 'Metadata documentation json file does not match expected format'; + } + } + + if ((!hasDefines || definesFound) && (!hasMetadata || metadataFound)) break; + } + + if (hasDefines && !definesFound) throw 'Json file `${infos.documentation.defines}` not found'; + if (hasMetadata && !metadataFound) throw 'Json file `${infos.documentation.metadata}` not found'; + } + static function cleanDependencies(dependencies:Null):Void { if (dependencies == null) return; diff --git a/src/haxelib/api/Connection.hx b/src/haxelib/api/Connection.hx index f3c930b7..50a7439d 100644 --- a/src/haxelib/api/Connection.hx +++ b/src/haxelib/api/Connection.hx @@ -402,6 +402,7 @@ class Connection { final infos = Data.readDataFromZip(zip, CheckData); Data.checkClassPath(zip, infos); + Data.checkDocumentation(zip, infos); // ask user which contributor they are final user = login(infos.contributors); diff --git a/src/haxelib/api/GlobalScope.hx b/src/haxelib/api/GlobalScope.hx index e5b2c178..cb0567b1 100644 --- a/src/haxelib/api/GlobalScope.hx +++ b/src/haxelib/api/GlobalScope.hx @@ -185,6 +185,25 @@ class GlobalScope extends Scope { ); addLine('-D ${info.name}=${info.version}'); + if (info.documentation != null) { + var doc = info.documentation; + + // we'll have to change this to "4.3.0" after the release + if (resolveCompiler().version >= SemVer.ofString("4.3.0-rc.1")) { + // custom defines if defined + if (doc.defines != null && doc.defines != "") { + var path = Path.join([resolved.path, doc.defines]); + addLine('--macro registerDefinesDescriptionFile(\'$path\', \'${info.name}\')'); + } + + // custom metadatas if defined + if (doc.metadata != null && doc.metadata != "") { + var path = Path.join([resolved.path, doc.metadata]); + addLine('--macro registerMetadataDescriptionFile(\'$path\', \'${info.name}\')'); + } + } + } + // add dependencies to stack final dependencies = info.dependencies.extractDataArray(); diff --git a/test/libraries/libBadDefineJson/doc/defines.json b/test/libraries/libBadDefineJson/doc/defines.json new file mode 100644 index 00000000..75ef15e2 --- /dev/null +++ b/test/libraries/libBadDefineJson/doc/defines.json @@ -0,0 +1,5 @@ +[ + { + "name": "Malformed define" + } +] diff --git a/test/libraries/libBadDefineJson/haxelib.json b/test/libraries/libBadDefineJson/haxelib.json new file mode 100644 index 00000000..fb424b81 --- /dev/null +++ b/test/libraries/libBadDefineJson/haxelib.json @@ -0,0 +1,13 @@ +{ + "name": "BadDefineJson", + "url" : "http://example.org", + "license": "GPL", + "tags": ["bar", "test"], + "description": "This project is an example of an haxelib project", + "version": "1.0.0", + "releasenote": "Initial release, everything is working correctly", + "documentation": { + "defines": "doc/defines.json" + }, + "contributors": ["Bar"] +} diff --git a/test/libraries/libBadMetaJson/doc/meta.json b/test/libraries/libBadMetaJson/doc/meta.json new file mode 100644 index 00000000..ab7a2915 --- /dev/null +++ b/test/libraries/libBadMetaJson/doc/meta.json @@ -0,0 +1 @@ +This is not a json file diff --git a/test/libraries/libBadMetaJson/haxelib.json b/test/libraries/libBadMetaJson/haxelib.json new file mode 100644 index 00000000..743404a2 --- /dev/null +++ b/test/libraries/libBadMetaJson/haxelib.json @@ -0,0 +1,13 @@ +{ + "name": "BadMetaJson", + "url" : "http://example.org", + "license": "GPL", + "tags": ["bar", "test"], + "description": "This project is an example of an haxelib project", + "version": "1.0.0", + "releasenote": "Initial release, everything is working correctly", + "documentation": { + "metadata": "doc/meta.json" + }, + "contributors": ["Bar"] +} diff --git a/test/libraries/libBadMetaJson2/doc/meta.json b/test/libraries/libBadMetaJson2/doc/meta.json new file mode 100644 index 00000000..526dc73d --- /dev/null +++ b/test/libraries/libBadMetaJson2/doc/meta.json @@ -0,0 +1,5 @@ +[ + { + "name": "Malformed meta" + } +] diff --git a/test/libraries/libBadMetaJson2/haxelib.json b/test/libraries/libBadMetaJson2/haxelib.json new file mode 100644 index 00000000..cee33d03 --- /dev/null +++ b/test/libraries/libBadMetaJson2/haxelib.json @@ -0,0 +1,13 @@ +{ + "name": "BadMetaJson2", + "url" : "http://example.org", + "license": "GPL", + "tags": ["bar", "test"], + "description": "This project is an example of an haxelib project", + "version": "1.0.0", + "releasenote": "Initial release, everything is working correctly", + "documentation": { + "metadata": "doc/meta.json" + }, + "contributors": ["Bar"] +} diff --git a/test/libraries/libDocumentationFiles/doc/defines.json b/test/libraries/libDocumentationFiles/doc/defines.json new file mode 100644 index 00000000..63c26e08 --- /dev/null +++ b/test/libraries/libDocumentationFiles/doc/defines.json @@ -0,0 +1,13 @@ +[ + { + "define": "test", + "doc": "Test define" + }, + { + "define": "test2", + "doc": "Test define 2", + "platforms": ["eval"], + "params": ["foo"], + "links": ["https://example.com"] + } +] diff --git a/test/libraries/libDocumentationFiles/doc/meta.json b/test/libraries/libDocumentationFiles/doc/meta.json new file mode 100644 index 00000000..84bdcf32 --- /dev/null +++ b/test/libraries/libDocumentationFiles/doc/meta.json @@ -0,0 +1,14 @@ +[ + { + "metadata": ":test", + "doc": "Some test metadata" + }, + { + "metadata": ":test2", + "doc": "Some other test metadata", + "platforms": ["eval"], + "params": ["foo"], + "links": ["https://example.com"], + "targets": ["TClass", "TClassField"] + } +] diff --git a/test/libraries/libDocumentationFiles/haxelib.json b/test/libraries/libDocumentationFiles/haxelib.json new file mode 100644 index 00000000..d8aea90b --- /dev/null +++ b/test/libraries/libDocumentationFiles/haxelib.json @@ -0,0 +1,14 @@ +{ + "name": "DocumentationFiles", + "url" : "http://example.org", + "license": "GPL", + "tags": ["bar", "test"], + "description": "This project is an example of an haxelib project", + "version": "1.0.0", + "releasenote": "Initial release, everything is working correctly", + "documentation": { + "metadata": "doc/meta.json", + "defines": "doc/defines.json" + }, + "contributors": ["Bar"] +} diff --git a/test/libraries/libMissingMetaJson/haxelib.json b/test/libraries/libMissingMetaJson/haxelib.json new file mode 100644 index 00000000..9b17333d --- /dev/null +++ b/test/libraries/libMissingMetaJson/haxelib.json @@ -0,0 +1,13 @@ +{ + "name": "MissingMetaJson", + "url" : "http://example.org", + "license": "GPL", + "tags": ["bar", "test"], + "description": "This project is an example of an haxelib project", + "version": "1.0.0", + "releasenote": "Initial release, everything is working correctly", + "documentation": { + "metadata": "doc/meta.json" + }, + "contributors": ["Bar"] +} diff --git a/test/tests/TestData.hx b/test/tests/TestData.hx index b9e56fb9..527dfd72 100644 --- a/test/tests/TestData.hx +++ b/test/tests/TestData.hx @@ -104,6 +104,27 @@ class TestData extends TestBase { assertEquals( ok, true ); } + public function testCheckDocumentation() { + var results = [ + "DocumentationFiles" => true, + "BadMetaJson" => false, + "BadMetaJson2" => false, + "BadDefineJson" => false + ]; + + for (r in results.keys()) { + var zip = Reader.readZip(new BytesInput(File.getBytes('test/libraries/lib$r.zip'))); + var info = Data.readDataFromZip(zip, CheckData); + + try { + Data.checkDocumentation(zip,info); + assertTrue(results.get(r)); + } catch (e:Dynamic) { + assertFalse(results.get(r)); + } + } + } + public function testReadDataWithDataCheck() { assertFalse( readDataOkay("bad json") );