Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor client code and extract repository/library methods into new modules #510

Merged
merged 69 commits into from
Apr 6, 2022
Merged
Show file tree
Hide file tree
Changes from 62 commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
286512a
Add hx3compat dependency
tobil4sk Apr 6, 2021
b3c8308
Move functions to FsUtils
tobil4sk Apr 6, 2021
5be6aa7
Extract repo management methods to new module
tobil4sk Apr 6, 2021
7b1d4b0
Add documentation to RepoManager module
tobil4sk Apr 6, 2021
7839122
Error if haxe version doesn't have haxe.Exception
tobil4sk Apr 6, 2021
77e8c5b
[tests] Add tests for RepoManager module
tobil4sk Apr 18, 2021
a83d3c9
[tests] Fix integration test
tobil4sk Apr 18, 2021
891a183
Refactor client initialization
tobil4sk Apr 13, 2021
3fcdce9
Show errors when too many arguments given
tobil4sk Apr 17, 2021
592f0d5
Show error if invalid switch is given
tobil4sk Aug 9, 2021
6ca47ec
[tests] Add unit tests for Args module
tobil4sk Apr 14, 2021
bfd2563
Move functions to Cli module and clean strings
tobil4sk Apr 21, 2021
29496d5
Refactor `run` command code
tobil4sk Aug 5, 2021
f6922cb
Refactor code for `path` and `libpath` commands
tobil4sk Aug 6, 2021
329aa19
Refactor `list` command code
tobil4sk Aug 6, 2021
42939db
Refactor the way settings are used by Cli and Vcs
tobil4sk Oct 2, 2021
1ece648
Show warnings to stderr
tobil4sk Jan 8, 2022
76c7969
Fix inconsistent an use of if and ternary operator
tobil4sk Aug 9, 2021
6ae5b17
Add TODO for adding `hg` dependency support
tobil4sk Aug 20, 2021
d936318
Rework install, set and update
tobil4sk Apr 13, 2021
fcdc5f0
Add workarounds for capitalisation inconsistencies
tobil4sk Oct 2, 2021
5985747
[docs] Update site documentation in line with changes
tobil4sk Aug 20, 2021
0e54121
Refactor code for `remove` command
tobil4sk Aug 26, 2021
59ad81d
Clean up in Vcs.hx
tobil4sk Oct 2, 2021
38d9fc8
Refactor installer user interface
tobil4sk Dec 20, 2021
8b54818
Refactor `submit` command
tobil4sk Oct 25, 2021
a717174
Refactor `dev` command
tobil4sk Oct 25, 2021
3125c6a
Refactor proxy command in minor way
tobil4sk Nov 14, 2021
cf3abe1
Use lowercase for library path
tobil4sk Nov 12, 2021
5e55d6a
Move reusable modules into `api` package
tobil4sk Apr 18, 2021
8daba0b
[tests] Adapt tests to new api
tobil4sk Oct 3, 2021
77aec45
Document the `haxelib.api` and `haxelib` packages
tobil4sk Oct 26, 2021
f60904b
[tests] Update installer test
tobil4sk Dec 21, 2021
f0ee079
Forward toLowerCase method to ProjectName
tobil4sk Dec 23, 2021
712afce
Fix `run` with older versions of haxe
tobil4sk Dec 23, 2021
6969dda
Remember capitalisation of library when installed
tobil4sk Dec 24, 2021
8cc06fa
[tests] Move a test folder
tobil4sk Jan 4, 2022
a8b3520
[tests] Adding testing for #529
tobil4sk Jan 5, 2022
6e95b82
[tests] Add test for ProjectName alias check
tobil4sk Jan 8, 2022
ee9e75e
[tests] Test for aliasing with `dev` and `git/hg`
tobil4sk Jan 5, 2022
488b96a
[tests] Add more testing for remove command
tobil4sk Jan 6, 2022
a936899
[tests] Add tests for multiple issues
tobil4sk Jan 6, 2022
0df427c
[tests] Enable a disabled check in TestDev
tobil4sk Jan 7, 2022
e7147a9
[tests] Add tests for Scope and Global Scope
tobil4sk Jan 8, 2022
21f07bc
Implement repository reformatting using `fixrepo`
tobil4sk Jan 9, 2022
3935fae
[tests] Add testing for RepoReformatter module
tobil4sk Jan 9, 2022
82c1c02
[tests] Add testing for `fixrepo` command
tobil4sk Jan 9, 2022
53ee4ba
Fix error to display library name correctly
tobil4sk Jan 10, 2022
b94ba75
Move ProjectName to separate file
tobil4sk Jan 10, 2022
ed7c0ef
Return ProjectName from ProjectName.toLowerCase
tobil4sk Jan 10, 2022
5bba820
Minor cleanup
tobil4sk Feb 14, 2022
1939584
Remove unnecessary argument for setVcsVersion
tobil4sk Feb 14, 2022
46323b1
Update repo version for empty repositories
tobil4sk Apr 3, 2022
1d5606b
[tests] Set git user data in integration test repo
tobil4sk Apr 3, 2022
64f00f8
[tests] Fix constructor issue for haxe non-nightly
tobil4sk Apr 3, 2022
4fc20fa
[tests] Renable test for updating up-to-date lib
tobil4sk Apr 4, 2022
f60ea15
Make reformatting more predictable
tobil4sk Apr 4, 2022
acb1634
Sort the correct array this time
tobil4sk Apr 4, 2022
7e4f8da
Install hxjava for --jvm target in hxml install
tobil4sk Apr 5, 2022
612c642
Remove .c check for hashlink library
tobil4sk Apr 5, 2022
8891ff6
Fix indentation oddities in function docs
tobil4sk Apr 5, 2022
7d1231b
Clean up messy switch
tobil4sk Apr 5, 2022
459c3c8
Rename VcsID.isVcs to VcsID.isValid and use it
tobil4sk Apr 5, 2022
cac1fae
Combine Vcs.runStrict and Vcs.run
tobil4sk Apr 5, 2022
ffbebc9
Give better name to method for vcs library name
tobil4sk Apr 5, 2022
38b0916
Remove Installer.installLatestFromHaxelib
tobil4sk Apr 5, 2022
677f9d9
Minor cleanup of install command code
tobil4sk Apr 5, 2022
18dbbb4
Fix installFromHxml on already installed libraries
tobil4sk Apr 5, 2022
1ad8f0b
Set all library versions when installing from hxml
tobil4sk Apr 5, 2022
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
5 changes: 4 additions & 1 deletion haxelib.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,8 @@
"classPath": "src",
"version": "4.0.2",
"releasenote": " * Fixed too strict requirements to haxelib.json data for private libs (#484)",
"contributors": ["HaxeFoundation", "back2dos", "ncannasse", "jason", "Simn", "nadako", "andyli"]
"contributors": ["HaxeFoundation", "back2dos", "ncannasse", "jason", "Simn", "nadako", "andyli"],
"dependencies":{
"hx3compat":"git:https://github.com/haxefoundation/hx3compat.git#f1f18201e5c0479cb5adf5f6028788b37f37b730"
}
}
106 changes: 32 additions & 74 deletions src/haxelib/Data.hx
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ abstract Dependencies(Dynamic<DependencyVersion>) from Dynamic<DependencyVersion

for (f in fields) {
var value:String = Reflect.field(this, f);

// TODO: Also do mercurial
var isGit = value != null && (value + "").startsWith("git:");

if ( !isGit ){
Expand Down Expand Up @@ -162,8 +162,28 @@ abstract Dependencies(Dynamic<DependencyVersion>) from Dynamic<DependencyVersion

return result;
}

public inline function iterator()
return toArray().iterator();

#if (haxe_ver >= 4.0)
public inline function keyValueIterator():KeyValueIterator<ProjectName, DependencyVersion> {
final fields = Reflect.fields(this);
var index = 0;
return {
next: function() {
final name = fields[index++];
return {key: ProjectName.ofString(name), value: Reflect.field(this, name)};
},
hasNext: function() return index < fields.length
}
}
#end

/** Returns an array of the names of the dependencies. **/
public inline function getNames():Array<ProjectName>
return [for(name in Reflect.fields(this)) ProjectName.ofString(name) ];

}

/** The type of a dependency version. **/
Expand Down Expand Up @@ -212,75 +232,6 @@ typedef Infos = {
var Apache = 'Apache';
}

/** A valid project name string. **/
abstract ProjectName(String) to String {
static var RESERVED_NAMES = ["haxe", "all"];
static var RESERVED_EXTENSIONS = ['.zip', '.hxml'];
inline function new(s:String)
this = s;

@:to function toValidatable():Validatable
return {
validate:
function ():Option<String> {
for (r in rules)
if (!r.check(this))
return Some(r.msg.replace('%VALUE', '`' + Json.stringify(this) + '`'));
return None;
}
}

static var rules = {//using an array because order might matter
var a = new Array<{ msg: String, check:String->Bool }>();

function add(m, r)
a.push( { msg: m, check: r } );

add("%VALUE is not a String",
#if (haxe_ver < 4.1)
Std.is.bind(_, String)
#else
Std.isOfType.bind(_, String)
#end
);
add("%VALUE is too short", function (s) return s.length >= 3);
add("%VALUE contains invalid characters", Data.alphanum.match);
add("%VALUE is a reserved name", function(s) return RESERVED_NAMES.indexOf(s.toLowerCase()) == -1);
add("%VALUE ends with a reserved suffix", function(s) {
s = s.toLowerCase();
for (ext in RESERVED_EXTENSIONS)
if (s.endsWith(ext)) return false;
return true;
});

a;
}

/**
Validates that the project name is valid.

If it is invalid, returns `Some(e)` where e is an error
detailing why the project name is invalid.

If it is valid, returns `None`.
**/
public function validate()
return toValidatable().validate();

/**
Returns `s` as a `ProjectName` if it is valid,
otherwise throws an error explaining why it is invalid.
**/
static public function ofString(s:String)
return switch new ProjectName(s) {
case _.toValidatable().validate() => Some(e): throw e;
case v: v;
}

/** Default project name **/
static public var DEFAULT(default, null) = new ProjectName('unknown');
}

/** Class providing functions for working with project information. **/
class Data {

Expand Down Expand Up @@ -399,15 +350,22 @@ class Data {
}
}

/** Extracts project information from `jsondata`, validating it according to `check`. **/
public static function readData( jsondata: String, check : CheckLevel ) : Infos {
/**
Extracts project information from `jsondata`, validating it according to `check`.

`defaultName` is the project name to use if it is empty when the check value allows it.
**/
public static function readData( jsondata: String, check : CheckLevel, ?defaultName:ProjectName ) : Infos {
Simn marked this conversation as resolved.
Show resolved Hide resolved
if (defaultName == null)
defaultName = ProjectName.DEFAULT;

var doc:Infos =
try Json.parse(jsondata)
catch ( e : Dynamic )
if (check >= CheckLevel.CheckSyntax)
throw 'JSON parse error: $e';
else {
name : ProjectName.DEFAULT,
name : defaultName,
url : '',
version : SemVer.DEFAULT,
releasenote: 'No haxelib.json found',
Expand Down Expand Up @@ -436,7 +394,7 @@ class Data {
doc.classPath = '';

if (doc.name.validate() != None)
doc.name = ProjectName.DEFAULT;
doc.name = defaultName;

if (doc.description == null)
doc.description = '';
Expand Down
82 changes: 82 additions & 0 deletions src/haxelib/ProjectName.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package haxelib;

import haxe.Json;
import haxe.ds.Option;

import haxelib.Validator;

using StringTools;

/** A valid project name string. **/
abstract ProjectName(String) to String {
static var RESERVED_NAMES = ["haxe", "all"];
static var RESERVED_EXTENSIONS = ['.zip', '.hxml'];

inline function new(s:String)
this = s;

@:to function toValidatable():Validatable
return {
validate: function():Option<String> {
for (r in rules)
if (!r.check(this))
return Some(r.msg.replace('%VALUE', '`' + Json.stringify(this) + '`'));
return None;
}
}

static var rules = { // using an array because order might matter
var a = new Array<{msg:String, check:String->Bool}>();
function add(m, r)
a.push({msg: m, check: r});
add("%VALUE is not a String", #if (haxe_ver < 4.1) Std.is .bind(_, String) #else Std.isOfType.bind(_, String) #end
);
add("%VALUE is too short", function(s) return s.length >= 3);
add("%VALUE contains invalid characters", Data.alphanum.match);
add("%VALUE is a reserved name", function(s) return RESERVED_NAMES.indexOf(s.toLowerCase()) == -1);
add("%VALUE ends with a reserved suffix", function(s) {
s = s.toLowerCase();
for (ext in RESERVED_EXTENSIONS)
if (s.endsWith(ext))
return false;
return true;
});
a;
}

/**
Validates that the project name is valid.

If it is invalid, returns `Some(e)` where e is an error
detailing why the project name is invalid.

If it is valid, returns `None`.
**/
public function validate()
return toValidatable().validate();

public function toLowerCase():ProjectName
return new ProjectName(this.toLowerCase());

/**
Returns `s` as a `ProjectName` if it is valid,
otherwise throws an error explaining why it is invalid.
**/
static public function ofString(s:String)
return switch new ProjectName(s) {
case _.toValidatable().validate() => Some(e): throw e;
case v: v;
}

/**
If `alias` is just a different capitalization of `correct`, returns `correct`.

If `alias` is completely different, returns `alias` instead.
**/
static public function getCorrectOrAlias(correct:ProjectName, alias:ProjectName) {
return if (correct.toLowerCase() == alias.toLowerCase()) correct else alias;
}

/** Default project name **/
static public var DEFAULT(default, null) = new ProjectName('unknown');
}
60 changes: 60 additions & 0 deletions src/haxelib/Util.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package haxelib;

#if macro
import haxe.macro.Expr;

using haxe.macro.Tools;
#end

using StringTools;

class Util {
macro static public function rethrow(e) {
return if (haxe.macro.Context.defined("neko"))
macro neko.Lib.rethrow(e);
else
macro throw e;
}

#if macro
static function readVersionFromHaxelibJson() {
return haxe.Json.parse(sys.io.File.getContent("haxelib.json")).version;
}
#end

macro static public function getHaxelibVersion() {
return macro $v{readVersionFromHaxelibJson()};
}

macro static public function getHaxelibVersionLong() {
var version:String = readVersionFromHaxelibJson();
var p;
try {
//check if the .git folder exist
//prevent getting the git info of a parent directory
if (!sys.FileSystem.isDirectory(".git"))
throw "Not a git repo.";
Simn marked this conversation as resolved.
Show resolved Hide resolved

//get commit sha
p = new sys.io.Process("git", ["rev-parse", "HEAD"]);
final sha = p.stdout.readAll().toString().trim();
p.close();

//check to see if there is changes, staged or not
p = new sys.io.Process("git", ["status", "--porcelain"]);
final changes = p.stdout.readAll().toString().trim();
p.close();

version += switch(changes) {
case "":
' ($sha)';
case _:
' ($sha - dirty)';
}
return macro $v{version};
} catch(e:Dynamic) {
if (p != null) p.close();
return macro $v{version};
}
}
}
Loading