Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/haxelib/SiteApi.hx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
package haxelib;

import haxelib.MetaData;
import haxelib.Data.Dependencies;
import haxe.ds.*;

interface SiteApi {
Expand All @@ -34,6 +35,7 @@ interface SiteApi {
public function checkDeveloper( prj : String, user : String ) : Void;
public function checkPassword( user : String, pass : String ) : Bool;
public function getSubmitId() : String;
public function checkDependencies( dependencies : Dependencies) : Void;

public function processSubmit( id : String, user : String, pass : String ) : String;

Expand Down
19 changes: 6 additions & 13 deletions src/haxelib/api/Connection.hx
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ class Connection {
}
#end

static function retry<R>(func:Void->R) {
static function retry<R>(func:Void->R, errorPrefix = "Failed with error: ") {
var hasRetried = false;
var numTries = retries;

Expand All @@ -339,7 +339,7 @@ class Connection {
if (e == "std@host_resolve")
Util.rethrow(e);
if (e != "Blocked")
throw 'Failed with error: $e';
throw errorPrefix + e;
log("Failed. Triggering retry due to HTTP timeout");
hasRetried = true;
}
Expand Down Expand Up @@ -418,16 +418,6 @@ class Connection {
uploadAndSubmit(user, data, logUploadStatus);
}

static function checkDependencies(dependencies:Dependencies) {
for (name => versionString in dependencies) {
final versions:Array<String> = getVersions(ProjectName.ofString(name));
if (versionString == "")
continue;
if (!versions.contains(versionString))
throw "Library " + name + " does not have version " + versionString;
}
}

static function doesVersionExist(library:ProjectName, version:SemVer):Bool {
final versions = try getVersions(library) catch (_:Dynamic) return false;
return versions.contains(version);
Expand Down Expand Up @@ -537,11 +527,14 @@ class Connection {
return retry(data.site.checkPassword.bind(userName, password));

static function checkDeveloper(library:ProjectName, userName:String)
return retry(data.site.checkDeveloper.bind(library, userName));
return retry(data.site.checkDeveloper.bind(library, userName), "");

static function getSubmitId()
return retry(data.site.getSubmitId.bind());

static function processSubmit(id:String, userName:String, password:String)
return retry(data.site.processSubmit.bind(id, userName, password));

static function checkDependencies(dependencies:Dependencies)
return retry(data.site.checkDependencies.bind(dependencies), "");
}
28 changes: 28 additions & 0 deletions src/haxelib/server/Repo.hx
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,27 @@ class Repo implements SiteApi {
return Std.string(Std.random(100000000));
}

public function checkDependencies(dependencies:Dependencies) : Void {
for (dependency in dependencies.getNames()) {
var project = Project.manager.select($name == dependency);
if (project == null) {
throw 'Library $dependency does not exist';
}
var version = Reflect.field(dependencies, dependency);
if (version == '')
continue;
var hasVersion = false;
for (versionObject in Version.manager.search($project == project.id)) {
if (versionObject.name == version) {
hasVersion = true;
}
}
if (!hasVersion) {
throw 'Library $dependency does not have version $version';
}
}
}

public function processSubmit( id : String, user : String, pass : String ) : String {
neko.Web.logMessage("processSubmit " + id);
var tmpFile = Path.join([TMP_DIR_NAME, Std.parseInt(id)+".tmp"]);
Expand All @@ -170,6 +191,13 @@ class Repo implements SiteApi {
var infos = Data.readDataFromZip(zip,CheckData);
neko.Web.logMessage("processSubmit " + id + " readDataFromZip completed");

Data.checkClassPath(zip, infos);
Data.checkDocumentation(zip, infos);

neko.Web.logMessage("processSubmit " + id + " metadata validation completed");

checkDependencies(infos.dependencies);

Manager.cnx.startTransaction();

var u = User.manager.search({ name : user }).first();
Expand Down
13 changes: 13 additions & 0 deletions test/libraries/libMissingDep/haxelib.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "Foo",
"url" : "http://example.org",
"license": "GPL",
"tags": ["foo", "test"],
"description": "This project depends on a library that doesn't exist on the server",
"version": "1.0.0",
"releasenote": "",
"dependencies": {
"MissingDep": ""
},
"contributors": ["Foo"]
}
13 changes: 13 additions & 0 deletions test/libraries/libMissingDepVersion/haxelib.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "Foo",
"url" : "http://example.org",
"license": "GPL",
"tags": ["foo", "test"],
"description": "This project depends on a version of Bar that doesn't exist on the server",
"version": "1.0.0",
"releasenote": "",
"dependencies": {
"Bar": "2.0.0"
},
"contributors": ["Foo"]
}
34 changes: 34 additions & 0 deletions test/tests/integration/TestSubmit.hx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,40 @@ class TestSubmit extends IntegrationTests {
}
}

function testLibraryWithMissingDep() {
final r = haxelib(["register", foo.user, foo.email, foo.fullname, foo.pw, foo.pw]).result();
assertSuccess(r);

final r = haxelib(["submit", Path.join([IntegrationTests.projectRoot, "test/libraries/libMissingDep.zip"]), foo.pw]).result();
assertFail(r);
assertEquals("Error: Library MissingDep does not exist", r.err.trim());

final r = haxelib(["search", "Foo"]).result();
// did not get submitted
assertFalse(r.out.indexOf("Foo") >= 0);
}

function testLibraryWithMissingDepVersion() {
final r = haxelib(["register", bar.user, bar.email, bar.fullname, bar.pw, bar.pw]).result();
assertSuccess(r);

final r = haxelib(["submit", Path.join([IntegrationTests.projectRoot, "test/libraries/libBar.zip"]), bar.pw]).result();
assertSuccess(r);

final r = haxelib(["register", foo.user, foo.email, foo.fullname, foo.pw, foo.pw]).result();
assertSuccess(r);

final r = haxelib(["submit", Path.join([IntegrationTests.projectRoot, "test/libraries/libMissingDepVersion.zip"]), foo.pw]).result();
assertFail(r);
assertEquals("Error: Library Bar does not have version 2.0.0", r.err.trim());

trace("hello");

final r = haxelib(["search", "Foo"]).result();
// did not get submitted
assertFalse(r.out.indexOf("Foo") >= 0);
}

function testLibraryWithGitDep() {
// git deps should not be allowed in published versions
// https://github.com/HaxeFoundation/haxelib/pull/344#issuecomment-244006799
Expand Down