├── uf-content └── .gitignore ├── .gitattributes ├── bin └── .gitignore ├── terraform ├── .terraform-version ├── aws-ssm.tf ├── bitnami │ └── mysql │ │ ├── templates │ │ ├── extra-list.yaml │ │ ├── primary │ │ │ ├── initialization-configmap.yaml │ │ │ ├── configmap.yaml │ │ │ ├── svc-headless.yaml │ │ │ ├── pdb.yaml │ │ │ └── svc.yaml │ │ ├── secondary │ │ │ ├── configmap.yaml │ │ │ ├── svc-headless.yaml │ │ │ ├── pdb.yaml │ │ │ └── svc.yaml │ │ ├── role.yaml │ │ ├── rolebinding.yaml │ │ ├── serviceaccount.yaml │ │ ├── secrets.yaml │ │ ├── metrics-svc.yaml │ │ ├── networkpolicy.yaml │ │ └── servicemonitor.yaml │ │ ├── charts │ │ └── common │ │ │ ├── values.yaml │ │ │ ├── .helmignore │ │ │ ├── templates │ │ │ ├── _tplvalues.tpl │ │ │ ├── _warnings.tpl │ │ │ ├── _labels.tpl │ │ │ ├── _storage.tpl │ │ │ ├── _errors.tpl │ │ │ ├── _ingress.tpl │ │ │ ├── _names.tpl │ │ │ ├── _utils.tpl │ │ │ ├── validations │ │ │ │ ├── _validations.tpl │ │ │ │ └── _cassandra.tpl │ │ │ └── _images.tpl │ │ │ └── Chart.yaml │ │ ├── Chart.lock │ │ ├── .helmignore │ │ ├── ci │ │ └── values-production-with-rbac.yaml │ │ └── Chart.yaml ├── variables.tf ├── aws-route53.tf ├── .gitignore ├── aws-s3.tf ├── cloudflare.tf ├── aws-rds.tf ├── do-spaces.tf ├── providers.tf └── kubeconfig_do ├── package.hxml ├── test ├── libraries │ ├── InstallDeps │ │ ├── empty.hxml │ │ ├── cpp.hxml │ │ ├── cpp-single.hxml │ │ ├── git-deps.hxml │ │ ├── foo │ │ │ └── Foo.hx │ │ ├── target-lib.hxml │ │ ├── target-lib-uppercase.hxml │ │ ├── haxelib.xml │ │ ├── haxelib.json │ │ └── tag_haxelib.json │ ├── libFoo │ │ ├── build.hxml │ │ ├── other_build.hxml │ │ ├── old_build.hxml │ │ ├── other_haxelib.json │ │ ├── other_foo_haxelib.json │ │ ├── foo │ │ │ └── Foo.hx │ │ ├── haxelib.xml │ │ └── haxelib.json │ ├── libBadMetaJson │ │ ├── doc │ │ │ └── meta.json │ │ └── haxelib.json │ ├── libInvalidLicense │ │ ├── Main.hx │ │ └── haxelib.json │ ├── libNoHaxelibJson │ │ └── Main.hx │ ├── libBadMetaJson2 │ │ ├── doc │ │ │ └── meta.json │ │ └── haxelib.json │ ├── libBadDefineJson │ │ ├── doc │ │ │ └── defines.json │ │ └── haxelib.json │ ├── symlinks.zip │ ├── libBar2 │ │ ├── run.n │ │ ├── Run.hx │ │ ├── RunN.hx │ │ ├── bar │ │ │ └── Bar.hx │ │ ├── haxelib.json │ │ └── haxelib.xml │ ├── symlinks-broken.zip │ ├── libBar │ │ ├── Run.hx │ │ ├── bar │ │ │ └── Bar.hx │ │ ├── haxelib.xml │ │ └── haxelib.json │ ├── UseCp │ │ ├── lib │ │ │ └── src │ │ │ │ └── bar │ │ │ │ └── Bar.hx │ │ └── haxelib.json │ ├── libDeep │ │ └── libDeep │ │ │ ├── bar │ │ │ └── Bar.hx │ │ │ └── haxelib.json │ ├── libDeep2 │ │ └── libDeep │ │ │ ├── bar │ │ │ └── Bar.hx │ │ │ └── haxelib.json │ ├── libDeep3 │ │ └── libDeep │ │ │ ├── bar │ │ │ └── Bar.hx │ │ │ └── haxelib.json │ ├── libBaz │ │ ├── tools │ │ │ └── Main.hx │ │ ├── haxelib.xml │ │ └── haxelib.json │ ├── libFooGitDep │ │ ├── foo │ │ │ └── Foo.hx │ │ └── haxelib.json │ ├── libFooHgDep │ │ ├── foo │ │ │ └── Foo.hx │ │ └── haxelib.json │ ├── libDocumentationFiles │ │ ├── doc │ │ │ ├── defines.json │ │ │ └── meta.json │ │ └── haxelib.json │ ├── libWithGitFolder │ │ └── haxelib.json │ ├── libEnvironment │ │ ├── Run.hx │ │ └── haxelib.json │ ├── libBrokenDep │ │ └── haxelib.json │ ├── libMissingDep │ │ └── haxelib.json │ ├── libMissingDepVersion │ │ └── haxelib.json │ ├── libBadHaxelibJson │ │ └── haxelib.json │ └── libMissingMetaJson │ │ └── haxelib.json ├── repo │ └── .gitignore ├── tests │ ├── integration │ │ ├── import.hx │ │ ├── TestSetup.hx │ │ ├── TestMisc.hx │ │ ├── TestHg.hx │ │ ├── TestGit.hx │ │ ├── TestUser.hx │ │ ├── TestInfo.hx │ │ ├── TestUpgrade.hx │ │ ├── TestOwner.hx │ │ └── TestEmpty.hx │ ├── TestRemoveSymlinksBroken.hx │ ├── TestHg.hx │ ├── TestGit.hx │ ├── TestRepoReformatterOnLocal.hx │ ├── TestLibFlagData.hx │ ├── TestRemoveSymlinks.hx │ ├── TestGlobalScope.hx │ ├── TestVersionData.hx │ └── TestSemVer.hx ├── docker-compose-dev.yml ├── docker-compose.yml ├── TestBase.hx ├── WebsiteTests.hx ├── website │ └── controller │ │ ├── RSSControllerTest.hx │ │ ├── DocumentationControllerTest.hx │ │ └── UserControllerTest.hx ├── Prepare.hx └── HaxelibTests.hx ├── www ├── legacy │ └── .gitignore ├── files │ └── 3.0 │ │ └── .gitignore ├── favicon.ico ├── .gitignore ├── img │ ├── haxe-logo.png │ ├── logo_small.png │ ├── homepage_banner.jpg │ ├── glyphicons-halflings.png │ ├── glyphicons-halflings-white.png │ ├── haxe-logo-horizontal-on-dark.png │ └── haxe-logo.svg ├── documentation-files │ ├── installation.md │ ├── tips-and-tricks.md │ ├── api.md │ ├── haxelibs-in-projects.md │ ├── index.md │ ├── faq.md │ └── per-project-setup.md ├── dbconfig.json ├── view │ ├── project │ │ ├── docs.html │ │ └── versionList.html │ ├── documentation │ │ └── documentationPage.html │ ├── user │ │ ├── list.html │ │ └── profile.html │ └── home │ │ ├── projectList.html │ │ ├── recent.html │ │ ├── tagProjectList.html │ │ ├── tagList.html │ │ └── search.html ├── api │ └── 3.0 │ │ └── .gitignore └── .htaccess ├── prepare_tests.hxml ├── server-start.hxml ├── .devcontainer ├── direnv.toml ├── mysql.gpg ├── devcontainer.json ├── rclone │ └── rclone.conf └── docker-compose.yml ├── lib └── .gitignore ├── run.n ├── client.hxml ├── ci.hxml ├── client_legacy.hxml ├── deploy_key.enc ├── each.hxml ├── src ├── legacyhaxelib │ ├── haxelib.sh │ ├── haxelib.hxml │ ├── .htaccess │ └── Remoting_SiteApi.hx ├── website │ ├── model │ │ └── SiteDb.hx │ ├── api │ │ ├── DocumentationApi.hx │ │ └── UserApi.hx │ ├── controller │ │ ├── UserController.hx │ │ └── DocumentationController.hx │ ├── homepage-example.txt │ ├── tasks │ │ └── HaxelibCacheTasks.hx │ ├── Tasks.hx │ ├── cache │ │ └── DummyCache.hx │ └── Util.hx ├── haxelib │ ├── api │ │ ├── Hxml.hx │ │ └── LibraryData.hx │ ├── Util.hx │ ├── SiteApi.hx │ ├── server │ │ └── Paths.hx │ ├── ProjectName.hx │ └── MetaData.hx └── Package.hx ├── .dockerignore ├── server-daemon-tora.sh ├── server_website.hxml ├── client_tests.hxml ├── server-daemon-httpd.sh ├── integration_tests.hxml ├── server_tasks.hxml ├── client_cpp.hxml ├── server_legacy.hxml ├── .github ├── FUNDING.yml └── workflows │ ├── ci-prod.yml │ └── ci-dev.yml ├── server_gitrepo.hxml ├── server.hxml ├── server_api.hxml ├── server_website_highlighter.hxml ├── server_tests.hxml ├── skeema ├── Tag.sql ├── .skeema ├── auth_group.sql ├── User.sql ├── Developer.sql ├── _join_Group_User.sql ├── auth_user.sql ├── UFMailLog.sql ├── DBCacheItem.sql ├── Project.sql ├── auth_permission.sql └── Version.sql ├── server_each.hxml ├── .vscode ├── settings.json └── tasks.json ├── generate_extern.sh ├── .gitmodules ├── haxelib.json ├── .gitignore ├── deploy.json ├── package.json ├── LICENSE ├── CMakeLists.txt └── apache2.conf /uf-content/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf -------------------------------------------------------------------------------- /bin/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /terraform/.terraform-version: -------------------------------------------------------------------------------- 1 | 1.3.9 -------------------------------------------------------------------------------- /package.hxml: -------------------------------------------------------------------------------- 1 | -p src 2 | --run Package -------------------------------------------------------------------------------- /test/libraries/InstallDeps/empty.hxml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/repo/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /www/legacy/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /www/files/3.0/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /prepare_tests.hxml: -------------------------------------------------------------------------------- 1 | -cp test 2 | --run Prepare -------------------------------------------------------------------------------- /test/libraries/libFoo/build.hxml: -------------------------------------------------------------------------------- 1 | -lib Bar 2 | -------------------------------------------------------------------------------- /test/libraries/InstallDeps/cpp.hxml: -------------------------------------------------------------------------------- 1 | --cpp bin 2 | -------------------------------------------------------------------------------- /test/libraries/libFoo/other_build.hxml: -------------------------------------------------------------------------------- 1 | -lib bar 2 | -------------------------------------------------------------------------------- /server-start.hxml: -------------------------------------------------------------------------------- 1 | -cmd nekotools server -rewrite -d www -------------------------------------------------------------------------------- /test/libraries/InstallDeps/cpp-single.hxml: -------------------------------------------------------------------------------- 1 | -cpp bin 2 | -------------------------------------------------------------------------------- /test/libraries/libFoo/old_build.hxml: -------------------------------------------------------------------------------- 1 | -lib Bar:1.0.0 2 | -------------------------------------------------------------------------------- /.devcontainer/direnv.toml: -------------------------------------------------------------------------------- 1 | [whitelist] 2 | prefix = [ "/workspace" ] -------------------------------------------------------------------------------- /lib/.gitignore: -------------------------------------------------------------------------------- 1 | # generated by `yarn dts2hx` 2 | /dts2hx-generated -------------------------------------------------------------------------------- /run.n: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HaxeFoundation/haxelib/HEAD/run.n -------------------------------------------------------------------------------- /client.hxml: -------------------------------------------------------------------------------- 1 | each.hxml 2 | -neko run.n 3 | -main haxelib.client.Main 4 | -------------------------------------------------------------------------------- /test/libraries/libBadMetaJson/doc/meta.json: -------------------------------------------------------------------------------- 1 | This is not a json file 2 | -------------------------------------------------------------------------------- /ci.hxml: -------------------------------------------------------------------------------- 1 | -cp test 2 | -main RunCi 3 | -neko bin/ci.n 4 | #-cmd neko bin/ci.n 5 | -------------------------------------------------------------------------------- /client_legacy.hxml: -------------------------------------------------------------------------------- 1 | each.hxml 2 | -neko bin/legacyhaxelib.n 3 | -main legacyhaxelib.Main -------------------------------------------------------------------------------- /deploy_key.enc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HaxeFoundation/haxelib/HEAD/deploy_key.enc -------------------------------------------------------------------------------- /each.hxml: -------------------------------------------------------------------------------- 1 | -cp src 2 | -cp hx3compat/std 3 | -cp hx4compat/std 4 | -cp crypto/src 5 | -------------------------------------------------------------------------------- /src/legacyhaxelib/haxelib.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | exec haxe --run legacyhaxelib.Main "$@" 3 | -------------------------------------------------------------------------------- /www/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HaxeFoundation/haxelib/HEAD/www/favicon.ico -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | uf-content 2 | deploy 3 | bin 4 | test 5 | deploy_key 6 | www/node_modules/ 7 | -------------------------------------------------------------------------------- /server-daemon-tora.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | exec /usr/bin/neko /src/tora.n 6 | -------------------------------------------------------------------------------- /server_website.hxml: -------------------------------------------------------------------------------- 1 | server_each.hxml 2 | -main website.Server 3 | -neko www/index.n 4 | -------------------------------------------------------------------------------- /test/libraries/libFoo/other_haxelib.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "bar": "" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/libraries/libInvalidLicense/Main.hx: -------------------------------------------------------------------------------- 1 | function main() { 2 | trace("Hello, world!"); 3 | } 4 | -------------------------------------------------------------------------------- /test/libraries/libNoHaxelibJson/Main.hx: -------------------------------------------------------------------------------- 1 | function main() { 2 | trace("Hello, world!"); 3 | } 4 | -------------------------------------------------------------------------------- /www/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | js/*.min.js 3 | js/highlighter.js 4 | css/*.min.css 5 | fonts/ -------------------------------------------------------------------------------- /client_tests.hxml: -------------------------------------------------------------------------------- 1 | each.hxml 2 | -p test 3 | --main HaxelibTests 4 | --debug 5 | --neko bin/test.n 6 | -------------------------------------------------------------------------------- /server-daemon-httpd.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | exec /usr/sbin/apachectl -D FOREGROUND 6 | -------------------------------------------------------------------------------- /test/libraries/InstallDeps/git-deps.hxml: -------------------------------------------------------------------------------- 1 | -lib hx.signal:git:https://github.com/fzzr-/hx.signal.git#0.9.3 -------------------------------------------------------------------------------- /test/libraries/libBadMetaJson2/doc/meta.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "Malformed meta" 4 | } 5 | ] 6 | -------------------------------------------------------------------------------- /test/libraries/libFoo/other_foo_haxelib.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "Foo": "" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /www/img/haxe-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HaxeFoundation/haxelib/HEAD/www/img/haxe-logo.png -------------------------------------------------------------------------------- /www/img/logo_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HaxeFoundation/haxelib/HEAD/www/img/logo_small.png -------------------------------------------------------------------------------- /.devcontainer/mysql.gpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HaxeFoundation/haxelib/HEAD/.devcontainer/mysql.gpg -------------------------------------------------------------------------------- /integration_tests.hxml: -------------------------------------------------------------------------------- 1 | each.hxml 2 | -p test 3 | -main IntegrationTests 4 | -neko bin/integration_tests.n -------------------------------------------------------------------------------- /test/libraries/libBadDefineJson/doc/defines.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "Malformed define" 4 | } 5 | ] 6 | -------------------------------------------------------------------------------- /server_tasks.hxml: -------------------------------------------------------------------------------- 1 | server_each.hxml 2 | -lib ufront-uftasks 3 | -main website.Tasks 4 | -neko www/tasks.n 5 | -------------------------------------------------------------------------------- /test/libraries/symlinks.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HaxeFoundation/haxelib/HEAD/test/libraries/symlinks.zip -------------------------------------------------------------------------------- /www/img/homepage_banner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HaxeFoundation/haxelib/HEAD/www/img/homepage_banner.jpg -------------------------------------------------------------------------------- /src/legacyhaxelib/haxelib.hxml: -------------------------------------------------------------------------------- 1 | -neko haxelib.n 2 | -main legacyhaxelib.Main 3 | -cmd "nekotools boot haxelib.n" 4 | -------------------------------------------------------------------------------- /terraform/aws-ssm.tf: -------------------------------------------------------------------------------- 1 | data "aws_ssm_parameter" "cloudflare_api_token" { 2 | name = "cloudflare_api_token" 3 | } 4 | -------------------------------------------------------------------------------- /test/libraries/libBar2/run.n: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HaxeFoundation/haxelib/HEAD/test/libraries/libBar2/run.n -------------------------------------------------------------------------------- /www/documentation-files/installation.md: -------------------------------------------------------------------------------- 1 | # Installing and Upgrading Haxelib 2 | 3 | 4 | More information to go here... -------------------------------------------------------------------------------- /www/documentation-files/tips-and-tricks.md: -------------------------------------------------------------------------------- 1 | # Tips and Tricks when using Haxelib 2 | 3 | More information to go here... 4 | -------------------------------------------------------------------------------- /www/img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HaxeFoundation/haxelib/HEAD/www/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /test/libraries/symlinks-broken.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HaxeFoundation/haxelib/HEAD/test/libraries/symlinks-broken.zip -------------------------------------------------------------------------------- /www/dbconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "user" : "dbUser", 3 | "pass" : "dbPass", 4 | "host" : "dbHost", 5 | "database" : "haxelib" 6 | } -------------------------------------------------------------------------------- /test/libraries/libBar/Run.hx: -------------------------------------------------------------------------------- 1 | class Run { 2 | static public function main() { 3 | Sys.print('Bar Run.hx script'); 4 | } 5 | } 6 | 7 | -------------------------------------------------------------------------------- /www/img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HaxeFoundation/haxelib/HEAD/www/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /www/img/haxe-logo-horizontal-on-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HaxeFoundation/haxelib/HEAD/www/img/haxe-logo-horizontal-on-dark.png -------------------------------------------------------------------------------- /test/libraries/libBar/bar/Bar.hx: -------------------------------------------------------------------------------- 1 | package bar; 2 | 3 | class Bar { 4 | 5 | static function new() { 6 | trace("new Bar"); 7 | } 8 | 9 | } -------------------------------------------------------------------------------- /test/libraries/libBar2/Run.hx: -------------------------------------------------------------------------------- 1 | class Run { 2 | static public function main() { 3 | Sys.print('Bar2 Run.hx script'); 4 | } 5 | } 6 | 7 | -------------------------------------------------------------------------------- /test/libraries/libBar2/RunN.hx: -------------------------------------------------------------------------------- 1 | class Run { 2 | static public function main() { 3 | Sys.print('Bar2 run.n script'); 4 | } 5 | } 6 | 7 | -------------------------------------------------------------------------------- /test/libraries/libBar2/bar/Bar.hx: -------------------------------------------------------------------------------- 1 | package bar; 2 | 3 | class Bar { 4 | 5 | static function new() { 6 | trace("new Bar"); 7 | } 8 | 9 | } -------------------------------------------------------------------------------- /test/libraries/libFoo/foo/Foo.hx: -------------------------------------------------------------------------------- 1 | package foo; 2 | 3 | class Foo { 4 | 5 | public function new() { 6 | trace("new Foo"); 7 | } 8 | 9 | } -------------------------------------------------------------------------------- /test/libraries/InstallDeps/foo/Foo.hx: -------------------------------------------------------------------------------- 1 | package foo; 2 | 3 | class Foo { 4 | 5 | public function new() { 6 | trace("new Foo"); 7 | } 8 | 9 | } -------------------------------------------------------------------------------- /test/libraries/UseCp/lib/src/bar/Bar.hx: -------------------------------------------------------------------------------- 1 | package bar; 2 | 3 | class Bar { 4 | 5 | static function new() { 6 | trace("new Bar"); 7 | } 8 | 9 | } -------------------------------------------------------------------------------- /test/libraries/libDeep/libDeep/bar/Bar.hx: -------------------------------------------------------------------------------- 1 | package bar; 2 | 3 | class Bar { 4 | 5 | static function new() { 6 | trace("new Bar"); 7 | } 8 | 9 | } -------------------------------------------------------------------------------- /test/libraries/libDeep2/libDeep/bar/Bar.hx: -------------------------------------------------------------------------------- 1 | package bar; 2 | 3 | class Bar { 4 | 5 | static function new() { 6 | trace("new Bar"); 7 | } 8 | 9 | } -------------------------------------------------------------------------------- /test/libraries/libDeep3/libDeep/bar/Bar.hx: -------------------------------------------------------------------------------- 1 | package bar; 2 | 3 | class Bar { 4 | 5 | static function new() { 6 | trace("new Bar"); 7 | } 8 | 9 | } -------------------------------------------------------------------------------- /test/libraries/libBaz/tools/Main.hx: -------------------------------------------------------------------------------- 1 | package tools; 2 | 3 | class Main { 4 | static function main() { 5 | Sys.print('Baz tools.Main script'); 6 | } 7 | } -------------------------------------------------------------------------------- /client_cpp.hxml: -------------------------------------------------------------------------------- 1 | each.hxml 2 | --cpp bin/cpp 3 | --main haxelib.client.Main 4 | -D destination=../../haxelib{EXESUFFIX} 5 | --dce full 6 | -D analyzer-optimize 7 | -------------------------------------------------------------------------------- /test/libraries/InstallDeps/target-lib.hxml: -------------------------------------------------------------------------------- 1 | -lib hxcpp:git:https://github.com/HaxeFoundation/hxcpp.git 2 | 3 | cpp.hxml 4 | # this file contains a --cpp flag 5 | -------------------------------------------------------------------------------- /test/libraries/libFooGitDep/foo/Foo.hx: -------------------------------------------------------------------------------- 1 | package foo; 2 | 3 | class Foo { 4 | 5 | public function new() { 6 | trace("new Foo"); 7 | } 8 | 9 | } 10 | -------------------------------------------------------------------------------- /test/libraries/libFooHgDep/foo/Foo.hx: -------------------------------------------------------------------------------- 1 | package foo; 2 | 3 | class Foo { 4 | 5 | public function new() { 6 | trace("new Foo"); 7 | } 8 | 9 | } 10 | -------------------------------------------------------------------------------- /test/libraries/InstallDeps/target-lib-uppercase.hxml: -------------------------------------------------------------------------------- 1 | -lib HXCPP:git:https://github.com/HaxeFoundation/hxcpp.git 2 | 3 | cpp.hxml 4 | # this file contains a --cpp flag 5 | -------------------------------------------------------------------------------- /server_legacy.hxml: -------------------------------------------------------------------------------- 1 | server_each.hxml 2 | -neko www/legacy/index.n 3 | -main legacyhaxelib.Site 4 | -lib record-macros 5 | -D haxelib_site 6 | -D haxelib_legacy 7 | -dce no 8 | -------------------------------------------------------------------------------- /test/tests/integration/import.hx: -------------------------------------------------------------------------------- 1 | package tests.integration; 2 | 3 | import IntegrationTests.*; 4 | using IntegrationTests; 5 | using StringTools; 6 | using haxe.io.Path; 7 | -------------------------------------------------------------------------------- /www/documentation-files/api.md: -------------------------------------------------------------------------------- 1 | # Accessing Haxelib info through the Remoting API 2 | # Accessing Haxelib info through the JSON API 3 | 4 | 5 | More information to go here... -------------------------------------------------------------------------------- /www/view/project/docs.html: -------------------------------------------------------------------------------- 1 |

Api Docs coming soon.

2 |

Hopefully using the New Dox Template.

-------------------------------------------------------------------------------- /terraform/bitnami/mysql/templates/extra-list.yaml: -------------------------------------------------------------------------------- 1 | {{- range .Values.extraDeploy }} 2 | --- 3 | {{ include "common.tplvalues.render" (dict "value" . "context" $) }} 4 | {{- end }} 5 | -------------------------------------------------------------------------------- /www/api/3.0/.gitignore: -------------------------------------------------------------------------------- 1 | # No need to ignore index.n since the .gitignore in project root ignored *.n 2 | # This file, however, still should present such that git will track this folder. -------------------------------------------------------------------------------- /terraform/bitnami/mysql/charts/common/values.yaml: -------------------------------------------------------------------------------- 1 | ## bitnami/common 2 | ## It is required by CI/CD tools and processes. 3 | ## @skip exampleValue 4 | ## 5 | exampleValue: common-chart 6 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | open_collective: haxe 4 | custom: ['https://haxe.org/foundation/support-plans.html', 'https://haxe.org/foundation/donate.html'] 5 | -------------------------------------------------------------------------------- /server_gitrepo.hxml: -------------------------------------------------------------------------------- 1 | each.hxml 2 | --class-path lib/dts2hx-generated 3 | --class-path lib/node-sys-db 4 | --library hxnodejs 5 | --library record-macros 6 | --js gitrepo.js 7 | --main haxelib.server.GitRepo 8 | -------------------------------------------------------------------------------- /server.hxml: -------------------------------------------------------------------------------- 1 | # The new haxelib website (on the same 3.0 repo) 2 | 3 | server_website_highlighter.hxml 4 | --next 5 | server_website.hxml 6 | --next 7 | server_tasks.hxml 8 | --next 9 | server_api.hxml 10 | -------------------------------------------------------------------------------- /test/tests/TestRemoveSymlinksBroken.hx: -------------------------------------------------------------------------------- 1 | package tests; 2 | 3 | class TestRemoveSymlinksBroken extends TestRemoveSymlinks { 4 | public function new():Void { 5 | super(); 6 | lib = "symlinks-broken"; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /server_api.hxml: -------------------------------------------------------------------------------- 1 | -cp src 2 | -neko www/api/3.0/index.n 3 | -main haxelib.server.Repo 4 | -lib aws-sdk-neko 5 | -lib record-macros 6 | -cp hx3compat/std 7 | -cp hx4compat/std 8 | -dce no 9 | -D haxelib_api 10 | -------------------------------------------------------------------------------- /terraform/variables.tf: -------------------------------------------------------------------------------- 1 | variable "HAXELIB_SERVER_IMAGE_DEVELOPMENT" { 2 | type = string 3 | default = null 4 | } 5 | 6 | variable "HAXELIB_SERVER_IMAGE_MASTER" { 7 | type = string 8 | default = null 9 | } 10 | -------------------------------------------------------------------------------- /server_website_highlighter.hxml: -------------------------------------------------------------------------------- 1 | # generate code highlighter 2 | -lib html-haxe-code-highlighter:0.1.2 3 | -js www/js/highlighter.js 4 | -main highlighter.Highlighter 5 | -D highlighter_standalone 6 | -D analyzer-optimize 7 | -dce full -------------------------------------------------------------------------------- /server_tests.hxml: -------------------------------------------------------------------------------- 1 | server_each.hxml 2 | -cp test 3 | # Now the testing libs 4 | -lib buddy:2.8.1 5 | -lib mockatoo 6 | -lib utest 7 | --no-inline 8 | -main WebsiteTests 9 | -neko bin/websitetest.n 10 | -cmd neko bin/websitetest.n 11 | -------------------------------------------------------------------------------- /skeema/Tag.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE `Tag` ( 2 | `id` int(11) NOT NULL AUTO_INCREMENT, 3 | `tag` mediumtext NOT NULL, 4 | `project` int(11) NOT NULL, 5 | PRIMARY KEY (`id`), 6 | KEY `Tag_project` (`project`) 7 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; 8 | -------------------------------------------------------------------------------- /skeema/.skeema: -------------------------------------------------------------------------------- 1 | default-character-set=utf8mb4 2 | default-collation=utf8mb4_general_ci 3 | generator=skeema:1.7.0-community 4 | 5 | [rds] 6 | flavor=mysql:5.7 7 | host=haxe-org.ct0xwjh6v08k.eu-west-1.rds.amazonaws.com 8 | port=3306 9 | schema=haxelib 10 | -------------------------------------------------------------------------------- /src/legacyhaxelib/.htaccess: -------------------------------------------------------------------------------- 1 | # Set index.n to come before index.php 2 | 3 | DirectoryIndex index.n 4 | 5 | # Enable rewrite 6 | 7 | RewriteEngine On 8 | RewriteCond %{REQUEST_FILENAME} !-f 9 | RewriteCond %{REQUEST_FILENAME} !-d 10 | RewriteRule ^(.*)$ index.n/$1 -------------------------------------------------------------------------------- /skeema/auth_group.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE `auth_group` ( 2 | `id` int(11) NOT NULL AUTO_INCREMENT, 3 | `created` datetime NOT NULL, 4 | `modified` datetime NOT NULL, 5 | `name` varchar(255) NOT NULL, 6 | PRIMARY KEY (`id`) 7 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; 8 | -------------------------------------------------------------------------------- /terraform/bitnami/mysql/Chart.lock: -------------------------------------------------------------------------------- 1 | dependencies: 2 | - name: common 3 | repository: https://charts.bitnami.com/bitnami 4 | version: 1.10.3 5 | digest: sha256:710e8247ae70ea63a2fb2fde4320511ff28c7b5c7a738861427f104a7718bdf4 6 | generated: "2021-12-25T15:29:08.745458449Z" 7 | -------------------------------------------------------------------------------- /skeema/User.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE `User` ( 2 | `id` int(11) NOT NULL AUTO_INCREMENT, 3 | `name` mediumtext NOT NULL, 4 | `fullname` mediumtext NOT NULL, 5 | `email` mediumtext NOT NULL, 6 | `pass` mediumtext NOT NULL, 7 | PRIMARY KEY (`id`) 8 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; 9 | -------------------------------------------------------------------------------- /skeema/Developer.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE `Developer` ( 2 | `user` int(11) NOT NULL, 3 | `project` int(11) NOT NULL, 4 | `id` int(11) NOT NULL AUTO_INCREMENT, 5 | PRIMARY KEY (`user`,`project`), 6 | KEY `Developer_project` (`project`), 7 | KEY `id` (`id`) 8 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; 9 | -------------------------------------------------------------------------------- /test/libraries/libDocumentationFiles/doc/defines.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "define": "test", 4 | "doc": "Test define" 5 | }, 6 | { 7 | "define": "test2", 8 | "doc": "Test define 2", 9 | "platforms": ["eval"], 10 | "params": ["foo"], 11 | "links": ["https://example.com"] 12 | } 13 | ] 14 | -------------------------------------------------------------------------------- /src/website/model/SiteDb.hx: -------------------------------------------------------------------------------- 1 | package website.model; 2 | 3 | typedef Developer = haxelib.server.SiteDb.Developer; 4 | typedef Project = haxelib.server.SiteDb.Project; 5 | typedef Tag = haxelib.server.SiteDb.Tag; 6 | typedef User = haxelib.server.SiteDb.User; 7 | typedef Version = haxelib.server.SiteDb.Version; -------------------------------------------------------------------------------- /skeema/_join_Group_User.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE `_join_Group_User` ( 2 | `id` int(11) NOT NULL AUTO_INCREMENT, 3 | `created` datetime NOT NULL, 4 | `modified` datetime NOT NULL, 5 | `r1` int(10) unsigned NOT NULL, 6 | `r2` int(10) unsigned NOT NULL, 7 | PRIMARY KEY (`id`) 8 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; 9 | -------------------------------------------------------------------------------- /test/libraries/libBar2/haxelib.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Bar", 3 | "url" : "http://example.org", 4 | "license": "MIT", 5 | "tags": ["bar", "version2"], 6 | "description": "This project is an example of an haxelib project", 7 | "version": "2.0.0", 8 | "releasenote": "Version 2.", 9 | "contributors": ["Bar"] 10 | } -------------------------------------------------------------------------------- /test/libraries/libBar/haxelib.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | This project is an example of an haxelib project 6 | Initial release, everything is working correctly 7 | -------------------------------------------------------------------------------- /test/libraries/libBar2/haxelib.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | This project is an example of an haxelib project 6 | Initial release, everything is working correctly 7 | -------------------------------------------------------------------------------- /test/libraries/InstallDeps/haxelib.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | This project is an example of an haxelib project 6 | Initial release, everything is working correctly 7 | -------------------------------------------------------------------------------- /test/libraries/libBaz/haxelib.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | This project is an example of an haxelib project 6 | Initial release, everything is working correctly 7 | -------------------------------------------------------------------------------- /test/libraries/libFoo/haxelib.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | This project is an example of an haxelib project 6 | Initial release, everything is working correctly 7 | -------------------------------------------------------------------------------- /test/libraries/libBar/haxelib.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Bar", 3 | "url" : "http://example.org", 4 | "license": "GPL", 5 | "tags": ["bar", "test"], 6 | "description": "This project is an example of an haxelib project", 7 | "version": "1.0.0", 8 | "releasenote": "Initial release, everything is working correctly", 9 | "contributors": ["Bar"] 10 | } -------------------------------------------------------------------------------- /test/libraries/libDeep/libDeep/haxelib.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Deep", 3 | "url" : "http://example.org", 4 | "license": "Public", 5 | "tags": ["deep", "test"], 6 | "description": "This project's zip contains a folder that holds the lib.", 7 | "version": "1.0.0", 8 | "releasenote": "N/A", 9 | "contributors": ["DeepAuthor", "AnotherGuy"] 10 | } -------------------------------------------------------------------------------- /test/libraries/UseCp/haxelib.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "UseCp", 3 | "url" : "http://example.org", 4 | "license": "GPL", 5 | "tags": [], 6 | "description": "This project use a deep class path.", 7 | "version": "0.0.1", 8 | "releasenote": "Initial release, everything is working correctly", 9 | "classPath": "lib/src", 10 | "contributors": ["Bar"] 11 | } -------------------------------------------------------------------------------- /test/libraries/libWithGitFolder/haxelib.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "libWithGitFolder", 3 | "url" : "http://example.org", 4 | "license": "GPL", 5 | "tags": [], 6 | "description": "This project contains a .git folder", 7 | "version": "0.0.1", 8 | "releasenote": "Initial release, everything is working correctly", 9 | "contributors": ["Bar"] 10 | } 11 | -------------------------------------------------------------------------------- /test/libraries/libEnvironment/Run.hx: -------------------------------------------------------------------------------- 1 | class Run { 2 | static function main() { 3 | switch Sys.args() { 4 | case ["get", envVar, _]: 5 | Sys.print(Sys.getEnv(envVar)); 6 | case ["cwd", cwd]: 7 | Sys.print(cwd); 8 | case _: 9 | Sys.stderr().writeString("Invalid command or arguments\n"); 10 | Sys.exit(1); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /test/libraries/libDocumentationFiles/doc/meta.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "metadata": ":test", 4 | "doc": "Some test metadata" 5 | }, 6 | { 7 | "metadata": ":test2", 8 | "doc": "Some other test metadata", 9 | "platforms": ["eval"], 10 | "params": ["foo"], 11 | "links": ["https://example.com"], 12 | "targets": ["TClass", "TClassField"] 13 | } 14 | ] 15 | -------------------------------------------------------------------------------- /test/libraries/libInvalidLicense/haxelib.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Bar", 3 | "url" : "http://example.org", 4 | "license": "Unknown", 5 | "tags": ["bar", "test"], 6 | "description": "This project is an example of an haxelib project", 7 | "version": "1.0.0", 8 | "releasenote": "Initial release, everything is working correctly", 9 | "contributors": ["Bar"] 10 | } 11 | -------------------------------------------------------------------------------- /test/libraries/libEnvironment/haxelib.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Environment", 3 | "url" : "http://example.org", 4 | "license": "GPL", 5 | "tags": ["foo", "test"], 6 | "description": "This project is an example of an haxelib project", 7 | "version": "0.0.0", 8 | "releasenote": "Initial release, everything is working correctly", 9 | "contributors": ["Foo"] 10 | } 11 | -------------------------------------------------------------------------------- /test/libraries/libBrokenDep/haxelib.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Foo", 3 | "url" : "http://example.org", 4 | "license": "GPL", 5 | "tags": ["foo", "test"], 6 | "description": "This project has a git dependency with a non-existent url", 7 | "version": "1.0.0", 8 | "dependencies": { 9 | "Bar": "git:./libraries/broken-git-dep" 10 | }, 11 | "contributors": ["Foo"] 12 | } 13 | -------------------------------------------------------------------------------- /test/libraries/libDeep2/libDeep/haxelib.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Deep", 3 | "url" : "http://example.org", 4 | "license": "Public", 5 | "tags": ["deep", "test"], 6 | "description": "This project's zip contains a folder that holds the lib.", 7 | "version": "1.0.1", 8 | "releasenote": "AnotherGuy took over the ownership.", 9 | "contributors": ["AnotherGuy", "DeepAuthor"] 10 | } -------------------------------------------------------------------------------- /test/libraries/libBaz/haxelib.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Baz", 3 | "url" : "http://example.org", 4 | "license": "GPL", 5 | "tags": ["baz", "test"], 6 | "description": "This project is an example of an haxelib project", 7 | "version": "0.1.0-alpha.0", 8 | "releasenote": "Initial release, everything is working correctly", 9 | "contributors": ["Baz"], 10 | "main": "tools.Main" 11 | } -------------------------------------------------------------------------------- /test/libraries/libDeep3/libDeep/haxelib.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Deep", 3 | "url" : "http://example.org", 4 | "license": "Public", 5 | "tags": ["deep", "test"], 6 | "description": "This project's zip contains a folder that holds the lib.", 7 | "version": "1.0.2", 8 | "releasenote": "Removed DeepAuthor in contributors, add Foo.", 9 | "contributors": ["AnotherGuy", "Foo"] 10 | } -------------------------------------------------------------------------------- /test/libraries/libMissingDep/haxelib.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Foo", 3 | "url" : "http://example.org", 4 | "license": "GPL", 5 | "tags": ["foo", "test"], 6 | "description": "This project depends on a library that doesn't exist on the server", 7 | "version": "1.0.0", 8 | "releasenote": "", 9 | "dependencies": { 10 | "MissingDep": "" 11 | }, 12 | "contributors": ["Foo"] 13 | } 14 | -------------------------------------------------------------------------------- /server_each.hxml: -------------------------------------------------------------------------------- 1 | each.hxml 2 | -lib ufront 3 | -lib ufront-mail:1.0.0-rc.4 4 | -lib ufront-ufadmin 5 | -lib erazor:1.0.1 6 | -lib markdown:1.0.0 7 | -lib cleversort 8 | -lib aws-sdk-neko 9 | -lib record-macros 10 | -lib html-haxe-code-highlighter:0.1.2 11 | -D server 12 | -D getter_support 13 | # https://github.com/HaxeFoundation/haxe/issues/4903 14 | --macro keep('StringBuf') -------------------------------------------------------------------------------- /test/libraries/libMissingDepVersion/haxelib.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Foo", 3 | "url" : "http://example.org", 4 | "license": "GPL", 5 | "tags": ["foo", "test"], 6 | "description": "This project depends on a version of Bar that doesn't exist on the server", 7 | "version": "1.0.0", 8 | "releasenote": "", 9 | "dependencies": { 10 | "Bar": "2.0.0" 11 | }, 12 | "contributors": ["Foo"] 13 | } 14 | -------------------------------------------------------------------------------- /test/libraries/libBadHaxelibJson/haxelib.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "BadHaxelibJson", 3 | "url" : "http://example.org", 4 | "license": "GPL", 5 | "tags": ["bar", "test"], 6 | "description": "This project is an example of an haxelib project", 7 | "version": "1.0.0", 8 | "releasenote": "Initial release, everything is working correctly", 9 | "contributors": ["BadHaxelibJson"], 10 | "dependencies": {,} 11 | } -------------------------------------------------------------------------------- /test/libraries/libFoo/haxelib.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Foo", 3 | "url" : "http://example.org", 4 | "license": "GPL", 5 | "tags": ["foo", "test"], 6 | "description": "This project is an example of an haxelib project", 7 | "version": "0.1.0-alpha.0", 8 | "releasenote": "Initial release, everything is working correctly", 9 | "dependencies": { 10 | "Bar": "" 11 | }, 12 | "contributors": ["Foo"] 13 | } -------------------------------------------------------------------------------- /www/view/documentation/documentationPage.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
Menu
4 | 9 |
10 |
11 | @content 12 |
13 |
14 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "haxe.configurations": [ 3 | ["client.hxml"], 4 | ["client_tests.hxml"], 5 | ["integration_tests.hxml"], 6 | ["prepare_tests.hxml"], 7 | ["server_each.hxml", "-neko", "repo.n"] 8 | ], 9 | "haxeTestExplorer.testCommand":[ 10 | "${haxe}", 11 | "client_tests.hxml", 12 | "--library", 13 | "test-adapter", 14 | "--cmd", 15 | "neko bin/test.n" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /test/libraries/libFooGitDep/haxelib.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Foo", 3 | "url" : "http://example.org", 4 | "license": "GPL", 5 | "tags": ["foo", "test"], 6 | "description": "This project is an example of an haxelib project", 7 | "version": "1.0.0", 8 | "releasenote": "Initial release, everything is working correctly", 9 | "dependencies": { 10 | "Bar": "git:./libraries/libBar" 11 | }, 12 | "contributors": ["Foo"] 13 | } 14 | -------------------------------------------------------------------------------- /test/libraries/libFooHgDep/haxelib.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Foo", 3 | "url" : "http://example.org", 4 | "license": "GPL", 5 | "tags": ["foo", "test"], 6 | "description": "This project is an example of an haxelib project", 7 | "version": "1.0.0", 8 | "releasenote": "Initial release, everything is working correctly", 9 | "dependencies": { 10 | "Bar": "hg:./libraries/libBar" 11 | }, 12 | "contributors": ["Foo"] 13 | } 14 | -------------------------------------------------------------------------------- /test/libraries/libBadMetaJson/haxelib.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "BadMetaJson", 3 | "url" : "http://example.org", 4 | "license": "GPL", 5 | "tags": ["bar", "test"], 6 | "description": "This project is an example of an haxelib project", 7 | "version": "1.0.0", 8 | "releasenote": "Initial release, everything is working correctly", 9 | "documentation": { 10 | "metadata": "doc/meta.json" 11 | }, 12 | "contributors": ["Bar"] 13 | } 14 | -------------------------------------------------------------------------------- /generate_extern.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | OUTPUT_DIR="lib/dts2hx-generated" 6 | 7 | mkdir -p "$OUTPUT_DIR" 8 | 9 | rm -rf "$OUTPUT_DIR"/* 10 | 11 | npx dts2hx \ 12 | @types/node \ 13 | octokit \ 14 | @octokit/auth-app \ 15 | mysql2 \ 16 | simple-git \ 17 | @types/node-fetch \ 18 | @types/fs-extra \ 19 | --noLibWrap \ 20 | --useSystemHaxe \ 21 | --output \ 22 | "$OUTPUT_DIR" 23 | -------------------------------------------------------------------------------- /test/libraries/libBadMetaJson2/haxelib.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "BadMetaJson2", 3 | "url" : "http://example.org", 4 | "license": "GPL", 5 | "tags": ["bar", "test"], 6 | "description": "This project is an example of an haxelib project", 7 | "version": "1.0.0", 8 | "releasenote": "Initial release, everything is working correctly", 9 | "documentation": { 10 | "metadata": "doc/meta.json" 11 | }, 12 | "contributors": ["Bar"] 13 | } 14 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "hx3compat"] 2 | path = hx3compat 3 | url = https://github.com/haxefoundation/hx3compat 4 | [submodule "lib/record-macros"] 5 | path = lib/record-macros 6 | url = https://github.com/HaxeFoundation/record-macros 7 | [submodule "hx4compat"] 8 | path = hx4compat 9 | url = https://github.com/HaxeFoundation/hx4compat 10 | [submodule "crypto"] 11 | path = crypto 12 | url = https://github.com/HaxeFoundation/crypto 13 | -------------------------------------------------------------------------------- /test/libraries/libBadDefineJson/haxelib.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "BadDefineJson", 3 | "url" : "http://example.org", 4 | "license": "GPL", 5 | "tags": ["bar", "test"], 6 | "description": "This project is an example of an haxelib project", 7 | "version": "1.0.0", 8 | "releasenote": "Initial release, everything is working correctly", 9 | "documentation": { 10 | "defines": "doc/defines.json" 11 | }, 12 | "contributors": ["Bar"] 13 | } 14 | -------------------------------------------------------------------------------- /test/libraries/libMissingMetaJson/haxelib.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "MissingMetaJson", 3 | "url" : "http://example.org", 4 | "license": "GPL", 5 | "tags": ["bar", "test"], 6 | "description": "This project is an example of an haxelib project", 7 | "version": "1.0.0", 8 | "releasenote": "Initial release, everything is working correctly", 9 | "documentation": { 10 | "metadata": "doc/meta.json" 11 | }, 12 | "contributors": ["Bar"] 13 | } 14 | -------------------------------------------------------------------------------- /skeema/auth_user.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE `auth_user` ( 2 | `id` int(11) NOT NULL AUTO_INCREMENT, 3 | `created` datetime NOT NULL, 4 | `modified` datetime NOT NULL, 5 | `username` varchar(40) NOT NULL, 6 | `salt` varchar(32) NOT NULL, 7 | `password` varchar(64) NOT NULL, 8 | `forcePasswordChange` tinyint(1) NOT NULL, 9 | PRIMARY KEY (`id`), 10 | UNIQUE KEY `auth_user_username` (`username`) 11 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; 12 | -------------------------------------------------------------------------------- /test/tests/integration/TestSetup.hx: -------------------------------------------------------------------------------- 1 | package tests.integration; 2 | 3 | import haxelib.api.RepoManager; 4 | 5 | class TestSetup extends IntegrationTests { 6 | function testCleanEnv():Void { 7 | // remove .haxelib to simulate an enviroment that haven't `haxelib setup` yet 8 | RepoManager.unsetGlobalPath(); 9 | 10 | final installResult = haxelib(["setup", originalRepo]).result(); 11 | assertEquals(0, installResult.code); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /skeema/UFMailLog.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE `UFMailLog` ( 2 | `id` int(11) NOT NULL AUTO_INCREMENT, 3 | `created` datetime NOT NULL, 4 | `modified` datetime NOT NULL, 5 | `to` varchar(255) NOT NULL, 6 | `from` varchar(255) NOT NULL, 7 | `subject` varchar(255) NOT NULL, 8 | `date` datetime NOT NULL, 9 | `email` mediumblob NOT NULL, 10 | `numAttachments` int(11) NOT NULL, 11 | PRIMARY KEY (`id`) 12 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; 13 | -------------------------------------------------------------------------------- /test/libraries/InstallDeps/haxelib.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Foo", 3 | "url" : "http://example.org", 4 | "license": "GPL", 5 | "tags": ["foo", "test"], 6 | "description": "This project is an example of an haxelib project", 7 | "version": "0.1.0-alpha.0", 8 | "releasenote": "Initial release, everything is working correctly", 9 | "dependencies": { 10 | "signal": "git:https://github.com/fzzr-/hx.signal.git" 11 | }, 12 | "contributors": ["Foo"] 13 | } -------------------------------------------------------------------------------- /terraform/bitnami/mysql/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | -------------------------------------------------------------------------------- /test/libraries/InstallDeps/tag_haxelib.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Foo", 3 | "url" : "http://example.org", 4 | "license": "GPL", 5 | "tags": ["foo", "test"], 6 | "description": "This project is an example of an haxelib project", 7 | "version": "0.1.0-alpha.0", 8 | "releasenote": "Initial release, everything is working correctly", 9 | "dependencies": { 10 | "signal": "git:https://github.com/fzzr-/hx.signal.git#0.9.2" 11 | }, 12 | "contributors": ["Foo"] 13 | } -------------------------------------------------------------------------------- /skeema/DBCacheItem.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE `DBCacheItem` ( 2 | `id` int(11) NOT NULL AUTO_INCREMENT, 3 | `created` datetime NOT NULL, 4 | `modified` datetime NOT NULL, 5 | `namespace` varchar(255) NOT NULL, 6 | `cacheID` varchar(255) NOT NULL, 7 | `data` mediumblob NOT NULL, 8 | PRIMARY KEY (`id`), 9 | UNIQUE KEY `DBCacheItem_namespace_cacheID` (`namespace`,`cacheID`), 10 | KEY `DBCacheItem_namespace` (`namespace`) 11 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; 12 | -------------------------------------------------------------------------------- /src/haxelib/api/Hxml.hx: -------------------------------------------------------------------------------- 1 | package haxelib.api; 2 | 3 | using StringTools; 4 | 5 | private final regex = ~/\r?\n/g; 6 | 7 | /** 8 | Normalizes `hxmlContents` by stripping comments, trimming whitespace 9 | from each line and removing empty lines 10 | **/ 11 | function normalizeHxml(hxmlContents:String):String { 12 | return regex.split(hxmlContents).map(StringTools.trim).filter(function(line) { 13 | return line != "" && !line.startsWith("#"); 14 | }).join('\n'); 15 | } 16 | -------------------------------------------------------------------------------- /test/tests/integration/TestMisc.hx: -------------------------------------------------------------------------------- 1 | package tests.integration; 2 | 3 | class TestMisc extends IntegrationTests { 4 | function testCwdWhenPassingToUpdatedHaxelib() { 5 | // so that the call is passed on 6 | haxelib(["dev", "haxelib", IntegrationTests.projectRoot]); 7 | 8 | final r = haxelib(["install", "empty.hxml", "--cwd", "libraries/InstallDeps"]).result(); 9 | assertSuccess(r); 10 | assertTrue(r.out.startsWith("Installing all libraries from")); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /terraform/bitnami/mysql/charts/common/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | .vscode/ 23 | -------------------------------------------------------------------------------- /test/libraries/libDocumentationFiles/haxelib.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "DocumentationFiles", 3 | "url" : "http://example.org", 4 | "license": "GPL", 5 | "tags": ["bar", "test"], 6 | "description": "This project is an example of an haxelib project", 7 | "version": "1.0.0", 8 | "releasenote": "Initial release, everything is working correctly", 9 | "documentation": { 10 | "metadata": "doc/meta.json", 11 | "defines": "doc/defines.json" 12 | }, 13 | "contributors": ["Bar"] 14 | } 15 | -------------------------------------------------------------------------------- /skeema/Project.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE `Project` ( 2 | `id` int(11) NOT NULL AUTO_INCREMENT, 3 | `name` mediumtext NOT NULL, 4 | `description` mediumtext NOT NULL, 5 | `website` mediumtext NOT NULL, 6 | `license` mediumtext NOT NULL, 7 | `downloads` int(11) NOT NULL, 8 | `owner` int(11) NOT NULL, 9 | `version` int(11) DEFAULT NULL, 10 | PRIMARY KEY (`id`), 11 | KEY `Project_owner` (`owner`), 12 | KEY `Project_version` (`version`) 13 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; 14 | -------------------------------------------------------------------------------- /terraform/bitnami/mysql/charts/common/templates/_tplvalues.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Renders a value that contains template. 4 | Usage: 5 | {{ include "common.tplvalues.render" ( dict "value" .Values.path.to.the.Value "context" $) }} 6 | */}} 7 | {{- define "common.tplvalues.render" -}} 8 | {{- if typeIs "string" .value }} 9 | {{- tpl .value .context }} 10 | {{- else }} 11 | {{- tpl (.value | toYaml) .context }} 12 | {{- end }} 13 | {{- end -}} 14 | -------------------------------------------------------------------------------- /skeema/auth_permission.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE `auth_permission` ( 2 | `id` int(11) NOT NULL AUTO_INCREMENT, 3 | `created` datetime NOT NULL, 4 | `modified` datetime NOT NULL, 5 | `permission` varchar(255) NOT NULL, 6 | `groupID` int(10) unsigned DEFAULT NULL, 7 | `userID` int(10) unsigned DEFAULT NULL, 8 | PRIMARY KEY (`id`), 9 | UNIQUE KEY `auth_permission_permission_userID` (`permission`,`userID`), 10 | UNIQUE KEY `auth_permission_permission_groupID` (`permission`,`groupID`) 11 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; 12 | -------------------------------------------------------------------------------- /test/tests/TestHg.hx: -------------------------------------------------------------------------------- 1 | package tests; 2 | 3 | import sys.FileSystem; 4 | import haxelib.VersionData.VcsID; 5 | 6 | class TestHg extends TestVcs { 7 | static final REPO_PATH = 'test/repo/hg'; 8 | 9 | static public function init() { 10 | HaxelibTests.deleteDirectory(REPO_PATH); 11 | HaxelibTests.runCommand('hg', ['clone', 'http://hg.code.sf.net/p/hx-signal/mercurial', REPO_PATH]); 12 | } 13 | 14 | public function new():Void { 15 | super(VcsID.Hg, "hg", FileSystem.fullPath(REPO_PATH), "default", "b022617bccfb"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "haxelib", 3 | "dockerComposeFile": "docker-compose.yml", 4 | "service": "workspace", 5 | "workspaceFolder": "/workspace", 6 | "remoteEnv": { 7 | "LOCAL_WORKSPACE_FOLDER": "${localWorkspaceFolder}" 8 | }, 9 | "customizations": { 10 | "vscode": { 11 | "extensions": [ 12 | "ms-azuretools.vscode-docker", 13 | "nadako.vshaxe", 14 | "hashicorp.terraform", 15 | "earthly.earthfile-syntax-highlighting" 16 | ] 17 | } 18 | }, 19 | "remoteUser": "vscode" 20 | } -------------------------------------------------------------------------------- /.devcontainer/rclone/rclone.conf: -------------------------------------------------------------------------------- 1 | [r2] 2 | type = s3 3 | provider = Cloudflare 4 | env_auth = false 5 | endpoint = https://09c8df40903546d43dba5a1924ee4b43.r2.cloudflarestorage.com 6 | # Add these to .envrc 7 | # export RCLONE_CONFIG_R2_ACCESS_KEY_ID=FIXME 8 | # export RCLONE_CONFIG_R2_SECRET_ACCESS_KEY=FIXME 9 | 10 | [do] 11 | type = s3 12 | provider = DigitalOcean 13 | region = fra1 14 | endpoint = fra1.digitaloceanspaces.com 15 | # Add these to .envrc 16 | # export RCLONE_CONFIG_DO_ACCESS_KEY_ID=FIXME 17 | # export RCLONE_CONFIG_DO_SECRET_ACCESS_KEY=FIXME -------------------------------------------------------------------------------- /skeema/Version.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE `Version` ( 2 | `id` int(11) NOT NULL AUTO_INCREMENT, 3 | `major` int(11) NOT NULL, 4 | `minor` int(11) NOT NULL, 5 | `patch` int(11) NOT NULL, 6 | `preview` tinyint(3) unsigned DEFAULT NULL, 7 | `previewNum` int(11) DEFAULT NULL, 8 | `date` mediumtext NOT NULL, 9 | `comments` mediumtext NOT NULL, 10 | `downloads` int(11) NOT NULL, 11 | `documentation` mediumtext, 12 | `project` int(11) NOT NULL, 13 | PRIMARY KEY (`id`), 14 | KEY `Version_project` (`project`) 15 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; 16 | -------------------------------------------------------------------------------- /test/tests/TestGit.hx: -------------------------------------------------------------------------------- 1 | package tests; 2 | 3 | import sys.FileSystem; 4 | import haxelib.VersionData.VcsID; 5 | 6 | class TestGit extends TestVcs { 7 | static final REPO_PATH = 'test/repo/git'; 8 | 9 | static public function init() { 10 | HaxelibTests.deleteDirectory(REPO_PATH); 11 | HaxelibTests.runCommand('git', ['clone', 'https://github.com/fzzr-/hx.signal.git', REPO_PATH]); 12 | } 13 | 14 | public function new():Void { 15 | super(VcsID.Git, "git", FileSystem.fullPath(REPO_PATH), "develop", "2feb1476dadd66ee0aa20587b1ee30a6b4faac0f"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/tests/TestRepoReformatterOnLocal.hx: -------------------------------------------------------------------------------- 1 | package tests; 2 | 3 | import sys.io.File; 4 | import sys.FileSystem; 5 | 6 | import haxelib.api.RepoManager; 7 | import haxelib.api.Repository; 8 | 9 | class TestRepoReformatterOnLocal extends TestRepoReformatter { 10 | 11 | override function get_repoPath():String { 12 | return '${TestRepoReformatter.dir}/.haxelib'; 13 | } 14 | 15 | override function getRepo():Repository { 16 | RepoManager.createLocal(TestRepoReformatter.dir); 17 | return Repository.get(TestRepoReformatter.dir); 18 | } 19 | 20 | override function cleanUpRepo() { /* nothing needed here*/ } 21 | } 22 | -------------------------------------------------------------------------------- /terraform/bitnami/mysql/ci/values-production-with-rbac.yaml: -------------------------------------------------------------------------------- 1 | # Test values file for generating all of the yaml and check that 2 | # the rendering is correct 3 | 4 | architecture: replication 5 | auth: 6 | usePasswordFiles: true 7 | 8 | primary: 9 | extraEnvVars: 10 | - name: TEST 11 | value: "3" 12 | podDisruptionBudget: 13 | create: true 14 | 15 | secondary: 16 | replicaCount: 2 17 | extraEnvVars: 18 | - name: TEST 19 | value: "2" 20 | podDisruptionBudget: 21 | create: true 22 | 23 | serviceAccount: 24 | create: true 25 | name: mysql-service-account 26 | rbac: 27 | create: true 28 | 29 | metrics: 30 | enabled: true 31 | -------------------------------------------------------------------------------- /terraform/bitnami/mysql/charts/common/templates/_warnings.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Warning about using rolling tag. 4 | Usage: 5 | {{ include "common.warnings.rollingTag" .Values.path.to.the.imageRoot }} 6 | */}} 7 | {{- define "common.warnings.rollingTag" -}} 8 | 9 | {{- if and (contains "bitnami/" .repository) (not (.tag | toString | regexFind "-r\\d+$|sha256:")) }} 10 | WARNING: Rolling tag detected ({{ .repository }}:{{ .tag }}), please note that it is strongly recommended to avoid using rolling tags in a production environment. 11 | +info https://docs.bitnami.com/containers/how-to/understand-rolling-tags-containers/ 12 | {{- end }} 13 | 14 | {{- end -}} 15 | -------------------------------------------------------------------------------- /terraform/bitnami/mysql/charts/common/Chart.yaml: -------------------------------------------------------------------------------- 1 | annotations: 2 | category: Infrastructure 3 | apiVersion: v2 4 | appVersion: 1.10.0 5 | description: A Library Helm Chart for grouping common logic between bitnami charts. 6 | This chart is not deployable by itself. 7 | home: https://github.com/bitnami/charts/tree/master/bitnami/common 8 | icon: https://bitnami.com/downloads/logos/bitnami-mark.png 9 | keywords: 10 | - common 11 | - helper 12 | - template 13 | - function 14 | - bitnami 15 | maintainers: 16 | - email: containers@bitnami.com 17 | name: Bitnami 18 | name: common 19 | sources: 20 | - https://github.com/bitnami/charts 21 | - https://www.bitnami.com/ 22 | type: library 23 | version: 1.10.3 24 | -------------------------------------------------------------------------------- /terraform/bitnami/mysql/charts/common/templates/_labels.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Kubernetes standard labels 4 | */}} 5 | {{- define "common.labels.standard" -}} 6 | app.kubernetes.io/name: {{ include "common.names.name" . }} 7 | helm.sh/chart: {{ include "common.names.chart" . }} 8 | app.kubernetes.io/instance: {{ .Release.Name }} 9 | app.kubernetes.io/managed-by: {{ .Release.Service }} 10 | {{- end -}} 11 | 12 | {{/* 13 | Labels to use on deploy.spec.selector.matchLabels and svc.spec.selector 14 | */}} 15 | {{- define "common.labels.matchLabels" -}} 16 | app.kubernetes.io/name: {{ include "common.names.name" . }} 17 | app.kubernetes.io/instance: {{ .Release.Name }} 18 | {{- end -}} 19 | -------------------------------------------------------------------------------- /test/docker-compose-dev.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | web: 4 | build: .. 5 | image: haxelib_web 6 | ports: 7 | - "2000:80" 8 | environment: 9 | - HAXELIB_DB_HOST=dbHost 10 | - HAXELIB_DB_PORT=3306 11 | - HAXELIB_DB_USER=dbUser 12 | - HAXELIB_DB_PASS=dbPass 13 | - HAXELIB_DB_NAME=haxelib 14 | volumes: 15 | - ../www:/var/www/html 16 | dbHost: 17 | image: mariadb 18 | ports: 19 | - "3306:3306" 20 | environment: 21 | - MYSQL_ALLOW_EMPTY_PASSWORD=yes 22 | - MYSQL_DATABASE=haxelib 23 | - MYSQL_USER=dbUser 24 | - MYSQL_PASSWORD=dbPass 25 | volumes: 26 | - database:/var/lib/mysql 27 | volumes: 28 | database: {} -------------------------------------------------------------------------------- /src/website/api/DocumentationApi.hx: -------------------------------------------------------------------------------- 1 | package website.api; 2 | 3 | import sys.FileSystem; 4 | import ufront.web.HttpError; 5 | import ufront.api.UFApi; 6 | import sys.io.File; 7 | using tink.CoreApi; 8 | 9 | class DocumentationApi extends UFApi { 10 | @inject("documentationPath") public var docPath:String; 11 | 12 | public function getDocumentationHTML( page:String ):Outcome { 13 | if ( page==null ) 14 | page = "index"; 15 | var markdownFile = docPath+page+'.md'; 16 | var markdown = 17 | try File.getContent( markdownFile ) 18 | catch(e:Dynamic) return Failure( new Error(404,'Documentation page $page not found: $e') ); 19 | var html = Markdown.markdownToHtml( markdown ); 20 | return Success( html ); 21 | } 22 | } -------------------------------------------------------------------------------- /terraform/bitnami/mysql/templates/primary/initialization-configmap.yaml: -------------------------------------------------------------------------------- 1 | {{- if and .Values.initdbScripts (not .Values.initdbScriptsConfigMap) }} 2 | apiVersion: v1 3 | kind: ConfigMap 4 | metadata: 5 | name: {{ printf "%s-init-scripts" (include "mysql.primary.fullname" .) }} 6 | namespace: {{ .Release.Namespace }} 7 | labels: {{- include "common.labels.standard" . | nindent 4 }} 8 | app.kubernetes.io/component: primary 9 | {{- if .Values.commonAnnotations }} 10 | annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} 11 | {{- end }} 12 | data: 13 | {{- include "common.tplvalues.render" (dict "value" .Values.initdbScripts "context" .) | nindent 2 }} 14 | {{ end }} 15 | -------------------------------------------------------------------------------- /terraform/bitnami/mysql/Chart.yaml: -------------------------------------------------------------------------------- 1 | annotations: 2 | category: Database 3 | apiVersion: v2 4 | appVersion: 8.0.28 5 | dependencies: 6 | - name: common 7 | repository: https://charts.bitnami.com/bitnami 8 | tags: 9 | - bitnami-common 10 | version: 1.x.x 11 | description: Chart to create a Highly available MySQL cluster 12 | home: https://github.com/bitnami/charts/tree/master/bitnami/mysql 13 | icon: https://bitnami.com/assets/stacks/mysql/img/mysql-stack-220x234.png 14 | keywords: 15 | - mysql 16 | - database 17 | - sql 18 | - cluster 19 | - high availability 20 | maintainers: 21 | - email: containers@bitnami.com 22 | name: Bitnami 23 | name: mysql 24 | sources: 25 | - https://github.com/bitnami/bitnami-docker-mysql 26 | - https://mysql.com 27 | version: 8.8.23 28 | -------------------------------------------------------------------------------- /terraform/bitnami/mysql/charts/common/templates/_storage.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Return the proper Storage Class 4 | {{ include "common.storage.class" ( dict "persistence" .Values.path.to.the.persistence "global" $) }} 5 | */}} 6 | {{- define "common.storage.class" -}} 7 | 8 | {{- $storageClass := .persistence.storageClass -}} 9 | {{- if .global -}} 10 | {{- if .global.storageClass -}} 11 | {{- $storageClass = .global.storageClass -}} 12 | {{- end -}} 13 | {{- end -}} 14 | 15 | {{- if $storageClass -}} 16 | {{- if (eq "-" $storageClass) -}} 17 | {{- printf "storageClassName: \"\"" -}} 18 | {{- else }} 19 | {{- printf "storageClassName: %s" $storageClass -}} 20 | {{- end -}} 21 | {{- end -}} 22 | 23 | {{- end -}} 24 | -------------------------------------------------------------------------------- /test/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | haxelib_server: 4 | image: haxe/lib.haxe.org:development 5 | ports: 6 | - "80:80" 7 | environment: 8 | - HAXELIB_DB_HOST=dbHost 9 | - HAXELIB_DB_PORT=3306 10 | - HAXELIB_DB_USER=dbUser 11 | - HAXELIB_DB_PASS=dbPass 12 | - HAXELIB_DB_NAME=haxelib 13 | dbHost: 14 | image: mysql:5.7.36 15 | ports: 16 | - "3306:3306" 17 | environment: 18 | - TZ=UTC 19 | - MYSQL_ALLOW_EMPTY_PASSWORD=yes 20 | - MYSQL_DATABASE=haxelib 21 | - MYSQL_USER=dbUser 22 | - MYSQL_PASSWORD=dbPass 23 | volumes: 24 | - database:/var/lib/mysql 25 | healthcheck: 26 | test: ["CMD", "mysqladmin", "ping", "--silent"] 27 | volumes: 28 | database: {} 29 | -------------------------------------------------------------------------------- /www/view/user/list.html: -------------------------------------------------------------------------------- 1 |

@title

2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | @for (u in list) { 12 | 13 | 14 | 15 | 16 | 25 | 26 | } 27 | 28 |
UserProjects
Avatar of @u.user.name@u.user.name@u.user.fullname 17 |

18 | @{i = 0;} 19 | @for (p in u.projects) { 20 | @{i++;} 21 | @p.name@if(i 24 |

-------------------------------------------------------------------------------- /terraform/bitnami/mysql/templates/primary/configmap.yaml: -------------------------------------------------------------------------------- 1 | {{- if (include "mysql.primary.createConfigmap" .) }} 2 | apiVersion: v1 3 | kind: ConfigMap 4 | metadata: 5 | name: {{ include "mysql.primary.fullname" . }} 6 | namespace: {{ .Release.Namespace }} 7 | labels: {{- include "common.labels.standard" . | nindent 4 }} 8 | app.kubernetes.io/component: primary 9 | {{- if .Values.commonLabels }} 10 | {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} 11 | {{- end }} 12 | {{- if .Values.commonAnnotations }} 13 | annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} 14 | {{- end }} 15 | data: 16 | my.cnf: |- 17 | {{ .Values.primary.configuration | nindent 4 }} 18 | {{- end -}} 19 | -------------------------------------------------------------------------------- /terraform/bitnami/mysql/templates/secondary/configmap.yaml: -------------------------------------------------------------------------------- 1 | {{- if (include "mysql.secondary.createConfigmap" .) }} 2 | apiVersion: v1 3 | kind: ConfigMap 4 | metadata: 5 | name: {{ include "mysql.secondary.fullname" . }} 6 | namespace: {{ .Release.Namespace }} 7 | labels: {{- include "common.labels.standard" . | nindent 4 }} 8 | app.kubernetes.io/component: secondary 9 | {{- if .Values.commonLabels }} 10 | {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} 11 | {{- end }} 12 | {{- if .Values.commonAnnotations }} 13 | annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} 14 | {{- end }} 15 | data: 16 | my.cnf: |- 17 | {{ .Values.secondary.configuration | nindent 4 }} 18 | {{- end -}} 19 | -------------------------------------------------------------------------------- /haxelib.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "haxelib", 3 | "url" : "https://lib.haxe.org/documentation/", 4 | "license": "MIT", 5 | "tags": ["haxelib", "core"], 6 | "description": "The haxelib client", 7 | "classPath": "src", 8 | "version": "4.2.0", 9 | "releasenote": " * Add `state save` and `state load` commands (#610)\n * Exit with error when hxml install fails (#625)\n * Allow compiling client with hxcpp target (#643)\n * Get compiler version for run scripts lazily (#646)\n * Change the order of haxelib git submodule installation (#638)\n * Fix crashes with git commands on Windows (#642)\n * Disallow library submissions containing .git folders (#664)", 10 | "contributors": ["HaxeFoundation", "back2dos", "ncannasse", "jason", "Simn", "nadako", "andyli"], 11 | "dependencies":{ 12 | "hx3compat": "", 13 | "hx4compat": "", 14 | "crypto": "" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /terraform/bitnami/mysql/templates/role.yaml: -------------------------------------------------------------------------------- 1 | {{- if and .Values.serviceAccount.create .Values.rbac.create }} 2 | apiVersion: {{ include "common.capabilities.rbac.apiVersion" . }} 3 | kind: Role 4 | metadata: 5 | name: {{ include "common.names.fullname" . }} 6 | namespace: {{ .Release.Namespace }} 7 | labels: {{- include "common.labels.standard" . | nindent 4 }} 8 | {{- if .Values.commonLabels }} 9 | {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} 10 | {{- end }} 11 | {{- if .Values.commonAnnotations }} 12 | annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} 13 | {{- end }} 14 | rules: 15 | - apiGroups: 16 | - "" 17 | resources: 18 | - endpoints 19 | verbs: 20 | - get 21 | {{- end }} 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .tmp-earthly-out* 2 | 3 | # Compiled files 4 | *.exe 5 | *.n 6 | *.zip 7 | /*.js 8 | test/libraries/vsc/ 9 | dump/ 10 | deploy/ 11 | haxelib_repo/ 12 | repo_integration_tests/ 13 | /haxelib 14 | run.c 15 | /tmp 16 | 17 | .envrc 18 | 19 | node_modules 20 | 21 | # run.n is in the repo 22 | !/run.n 23 | 24 | # Runtime files 25 | *.tmp 26 | *.db 27 | 28 | # IDE files 29 | .idea 30 | 31 | deploy_key 32 | 33 | # GitHub App private key 34 | *.private-key.pem 35 | 36 | .haxelib 37 | haxelib_global 38 | 39 | .devcontainer/workspace 40 | 41 | 42 | # CMake 43 | CMakeCache.txt 44 | CMakeFiles 45 | CMakeScripts 46 | Testing 47 | Makefile 48 | cmake_install.cmake 49 | install_manifest.txt 50 | compile_commands.json 51 | CTestTestfile.cmake 52 | 53 | # VisualStudio 54 | *.vcxproj 55 | *.vcxproj.filters 56 | *.sln 57 | Win32 58 | haxelib.dir 59 | 60 | # unit testing 61 | .unittest 62 | -------------------------------------------------------------------------------- /www/documentation-files/haxelibs-in-projects.md: -------------------------------------------------------------------------------- 1 | # Adding libraries to Haxe projects 2 | 3 | When the haxelib is installed, it is ready to be used it code. This is a matter of adding `--library libraryname` (or `-L libraryname`) to the [compiler arguments](https://haxe.org/manual/compiler-usage.html). 4 | 5 | ``` 6 | haxe --main Main --library libraryname --js bin/main.js 7 | ``` 8 | 9 | The same parameters you pass to the compiler can be stored in a [hxml file](https://haxe.org/manual/compiler-usage-hxml.html): 10 | 11 | ``` 12 | --main Main 13 | --library libraryname 14 | --js bin/main.js 15 | ``` 16 |
17 | 18 | ## Using Haxelib in OpenFL 19 | 20 | When using OpenFL, add `` tags in the project.xml to include Haxe libraries: 21 | 22 | ```xml 23 | 24 | ``` 25 | 26 | To specify a version: 27 | 28 | ```xml 29 | 30 | ``` 31 | -------------------------------------------------------------------------------- /deploy.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [ 3 | "api/", 4 | "css/", 5 | "documentation-files/", 6 | "img/", 7 | "view/", 8 | "dbconfig.json", 9 | "favicon.ico", 10 | "index.n", 11 | "tasks.n", 12 | ".htaccess" 13 | ], 14 | "targets": [ 15 | { 16 | "name": "lib.haxe.org", 17 | "gitRepo": "ssh://haxelib@lib.haxe.org/data/haxelib/haxelibwebsite.git", 18 | "defines": ["deploy"], 19 | "hxmls": ["server"], 20 | "debug": false, 21 | "servers": [{ 22 | "name": "lib.haxe.org", 23 | "user": "haxelib", 24 | "host": "lib.haxe.org", 25 | "port": 22, 26 | "remoteDir": "/data/haxelib/www/" 27 | }] 28 | } 29 | ], 30 | "hooks": { 31 | "beforeBuild": [], 32 | "afterBuild": [], 33 | "beforeCopy": [], 34 | "afterCopy": [], 35 | "beforePush": [], 36 | "afterPush": [], 37 | "beforePull": [], 38 | "afterPull": ["touch index.n"], 39 | "afterComplete": [] 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /test/tests/integration/TestHg.hx: -------------------------------------------------------------------------------- 1 | package tests.integration; 2 | 3 | import haxelib.api.FsUtils; 4 | import haxelib.api.Vcs; 5 | import tests.util.Vcs; 6 | 7 | class TestHg extends TestVcs { 8 | public function new () { 9 | super("hg"); 10 | } 11 | 12 | override function setup() { 13 | super.setup(); 14 | 15 | makeHgRepo(vcsLibPath, ["haxelib.xml"]); 16 | createHgTag(vcsLibPath, vcsTag); 17 | 18 | makeHgRepo(vcsLibNoHaxelibJson); 19 | makeHgRepo(vcsBrokenDependency); 20 | } 21 | 22 | override function tearDown() { 23 | resetHgRepo(vcsLibPath); 24 | resetHgRepo(vcsLibNoHaxelibJson); 25 | resetHgRepo(vcsBrokenDependency); 26 | 27 | super.tearDown(); 28 | } 29 | 30 | public function updateVcsRepo() { 31 | addToHgRepo(vcsLibPath, "haxelib.xml"); 32 | } 33 | 34 | public function getVcsCommit():String { 35 | return FsUtils.runInDirectory(vcsLibPath, Vcs.create(Hg).getRef); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /terraform/aws-route53.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | haxe_org_zoneid = "ZNT6UZLXKF3IS" 3 | } 4 | 5 | resource "aws_route53_record" "lib" { 6 | zone_id = local.haxe_org_zoneid 7 | name = "lib.haxe.org" 8 | type = "CNAME" 9 | ttl = "1800" 10 | records = ["do-k8s.haxe.org"] 11 | } 12 | 13 | resource "aws_route53_record" "development-lib" { 14 | zone_id = local.haxe_org_zoneid 15 | name = "development-lib.haxe.org" 16 | type = "CNAME" 17 | ttl = "1800" 18 | records = ["do-k8s.haxe.org"] 19 | } 20 | 21 | resource "aws_route53_record" "do-lib" { 22 | zone_id = local.haxe_org_zoneid 23 | name = "do-lib.haxe.org" 24 | type = "CNAME" 25 | ttl = "86400" 26 | records = ["do-k8s.haxe.org"] 27 | } 28 | 29 | resource "aws_route53_record" "do-development-lib" { 30 | zone_id = local.haxe_org_zoneid 31 | name = "do-development-lib.haxe.org" 32 | type = "CNAME" 33 | ttl = "86400" 34 | records = ["do-k8s.haxe.org"] 35 | } 36 | -------------------------------------------------------------------------------- /terraform/bitnami/mysql/templates/rolebinding.yaml: -------------------------------------------------------------------------------- 1 | {{- if and .Values.serviceAccount.create .Values.rbac.create }} 2 | kind: RoleBinding 3 | apiVersion: {{ include "common.capabilities.rbac.apiVersion" . }} 4 | metadata: 5 | name: {{ include "common.names.fullname" . }} 6 | namespace: {{ .Release.Namespace }} 7 | labels: {{- include "common.labels.standard" . | nindent 4 }} 8 | {{- if .Values.commonLabels }} 9 | {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} 10 | {{- end }} 11 | {{- if .Values.commonAnnotations }} 12 | annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} 13 | {{- end }} 14 | subjects: 15 | - kind: ServiceAccount 16 | name: {{ include "mysql.serviceAccountName" . }} 17 | roleRef: 18 | apiGroup: rbac.authorization.k8s.io 19 | kind: Role 20 | name: {{ include "common.names.fullname" . -}} 21 | {{- end }} 22 | -------------------------------------------------------------------------------- /src/website/controller/UserController.hx: -------------------------------------------------------------------------------- 1 | package website.controller; 2 | 3 | import haxe.crypto.Md5; 4 | import ufront.web.Controller; 5 | import ufront.web.result.*; 6 | import website.api.UserApi; 7 | using tink.CoreApi; 8 | 9 | @cacheRequest 10 | class UserController extends Controller { 11 | 12 | @inject public var api:UserApi; 13 | 14 | @:route("/$username") 15 | public function profile( username:String ) { 16 | var data = api.getUserProfile( username ).sure(); 17 | var user = data.a; 18 | return new ViewResult({ 19 | title: '$username (${user.fullname}) on Haxelib', 20 | user: user, 21 | projects: data.b, 22 | emailHash: Md5.encode( user.email ), 23 | }); 24 | } 25 | 26 | @:route("/") 27 | public function list() { 28 | var userList = api.getUserList().sure(); 29 | return new ViewResult({ 30 | title: 'Haxelib Contributors', 31 | list: userList 32 | }); 33 | } 34 | // Future: edit your own profile. Especially password resets. 35 | } 36 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "haxelib", 3 | "version": "0.0.0", 4 | "description": "Haxelib is a library management tool shipped with the Haxe Toolkit.", 5 | "scripts": {}, 6 | "repository": { 7 | "type": "git", 8 | "url": "git+https://github.com/HaxeFoundation/haxelib.git" 9 | }, 10 | "author": "", 11 | "license": "MIT", 12 | "bugs": { 13 | "url": "https://github.com/HaxeFoundation/haxelib/issues" 14 | }, 15 | "homepage": "https://github.com/HaxeFoundation/haxelib#readme", 16 | "private": true, 17 | "dependencies": { 18 | "deasync": "^0.1.23", 19 | "fs-extra": "^10.0.0", 20 | "mysql2": "^2.3.0", 21 | "node-fetch": "^2", 22 | "octokit": "^1.5.0", 23 | "promise-synchronizer": "^3.0.0", 24 | "simple-git": "^2.45.1" 25 | }, 26 | "devDependencies": { 27 | "@types/fs-extra": "^9.0.13", 28 | "@types/mysql": "^2.15.19", 29 | "@types/node": "^16.10.1", 30 | "@types/node-fetch": "^2", 31 | "dts2hx": "^0.16.1" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /terraform/bitnami/mysql/templates/primary/svc-headless.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ include "mysql.primary.fullname" . }}-headless 5 | namespace: {{ .Release.Namespace }} 6 | labels: {{- include "common.labels.standard" . | nindent 4 }} 7 | app.kubernetes.io/component: primary 8 | {{- if .Values.commonLabels }} 9 | {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} 10 | {{- end }} 11 | annotations: 12 | {{- if .Values.commonAnnotations }} 13 | {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} 14 | {{- end }} 15 | spec: 16 | type: ClusterIP 17 | clusterIP: None 18 | publishNotReadyAddresses: true 19 | ports: 20 | - name: mysql 21 | port: {{ .Values.primary.service.port }} 22 | targetPort: mysql 23 | selector: {{ include "common.labels.matchLabels" . | nindent 4 }} 24 | app.kubernetes.io/component: primary 25 | -------------------------------------------------------------------------------- /terraform/.gitignore: -------------------------------------------------------------------------------- 1 | # Local .terraform directories 2 | **/.terraform/* 3 | 4 | # .tfstate files 5 | *.tfstate 6 | *.tfstate.* 7 | 8 | # Crash log files 9 | crash.log 10 | 11 | # Exclude all .tfvars files, which are likely to contain sentitive data, such as 12 | # password, private keys, and other secrets. These should not be part of version 13 | # control as they are data points which are potentially sensitive and subject 14 | # to change depending on the environment. 15 | # 16 | *.tfvars 17 | 18 | # Ignore override files as they are usually used to override resources locally and so 19 | # are not checked in 20 | override.tf 21 | override.tf.json 22 | *_override.tf 23 | *_override.tf.json 24 | 25 | # Include override files you do wish to add to version control using negated pattern 26 | # 27 | # !example_override.tf 28 | 29 | # Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan 30 | # example: *tfplan* 31 | 32 | # Ignore CLI configuration files 33 | .terraformrc 34 | terraform.rc 35 | -------------------------------------------------------------------------------- /terraform/bitnami/mysql/templates/serviceaccount.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.serviceAccount.create }} 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: {{ include "mysql.serviceAccountName" . }} 6 | namespace: {{ .Release.Namespace }} 7 | labels: {{- include "common.labels.standard" . | nindent 4 }} 8 | {{- if .Values.commonLabels }} 9 | {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} 10 | {{- end }} 11 | annotations: 12 | {{- if .Values.serviceAccount.annotations }} 13 | {{- include "common.tplvalues.render" ( dict "value" .Values.serviceAccount.annotations "context" $ ) | nindent 4 }} 14 | {{- end }} 15 | {{- if .Values.commonAnnotations }} 16 | {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} 17 | {{- end }} 18 | {{- if (not .Values.auth.customPasswordFiles) }} 19 | secrets: 20 | - name: {{ template "mysql.secretName" . }} 21 | {{- end }} 22 | {{- end }} 23 | -------------------------------------------------------------------------------- /terraform/bitnami/mysql/templates/secrets.yaml: -------------------------------------------------------------------------------- 1 | {{- if eq (include "mysql.createSecret" .) "true" }} 2 | apiVersion: v1 3 | kind: Secret 4 | metadata: 5 | name: {{ include "common.names.fullname" . }} 6 | namespace: {{ .Release.Namespace }} 7 | labels: {{- include "common.labels.standard" . | nindent 4 }} 8 | {{- if .Values.commonLabels }} 9 | {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} 10 | {{- end }} 11 | {{- if .Values.commonAnnotations }} 12 | annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} 13 | {{- end }} 14 | type: Opaque 15 | data: 16 | mysql-root-password: {{ include "mysql.root.password" . | b64enc | quote }} 17 | mysql-password: {{ include "mysql.password" . | b64enc | quote }} 18 | {{- if eq .Values.architecture "replication" }} 19 | mysql-replication-password: {{ include "mysql.replication.password" . | b64enc | quote }} 20 | {{- end }} 21 | {{- end }} 22 | -------------------------------------------------------------------------------- /terraform/bitnami/mysql/templates/secondary/svc-headless.yaml: -------------------------------------------------------------------------------- 1 | {{- if eq .Values.architecture "replication" }} 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | name: {{ include "mysql.secondary.fullname" . }}-headless 6 | namespace: {{ .Release.Namespace }} 7 | labels: {{- include "common.labels.standard" . | nindent 4 }} 8 | app.kubernetes.io/component: secondary 9 | {{- if .Values.commonLabels }} 10 | {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} 11 | {{- end }} 12 | annotations: 13 | {{- if .Values.commonAnnotations }} 14 | {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} 15 | {{- end }} 16 | spec: 17 | type: ClusterIP 18 | clusterIP: None 19 | publishNotReadyAddresses: true 20 | ports: 21 | - name: mysql 22 | port: {{ .Values.secondary.service.port }} 23 | targetPort: mysql 24 | selector: {{ include "common.labels.matchLabels" . | nindent 4 }} 25 | app.kubernetes.io/component: secondary 26 | {{- end }} 27 | -------------------------------------------------------------------------------- /src/website/homepage-example.txt: -------------------------------------------------------------------------------- 1 | haxelib install actuate # Install `actuate` library 2 | haxelib install actuate 1.8.1 # Install a specific version 3 | haxe -lib actuate -main Test -js test.js # Use `actuate` library in your Haxe build 4 | 5 | haxelib list # List all of your installed libraries 6 | haxelib list openfl # List your installed libraries that have "openfl" in the name 7 | 8 | haxelib install actuate.zip # Install a library from a zip file 9 | haxelib install test.hxml # Install all the libs listed in a hxml 10 | haxelib install all # Install all the libs in the hxml files in the current directory 11 | 12 | haxelib submit actuate.zip # Use Haxelib to share your library with others! 13 | -------------------------------------------------------------------------------- /terraform/aws-s3.tf: -------------------------------------------------------------------------------- 1 | resource "aws_s3_bucket" "lib-haxe-org" { 2 | bucket = "lib.haxe.org" 3 | } 4 | 5 | resource "aws_s3_bucket_acl" "lib-haxe-org" { 6 | bucket = aws_s3_bucket.lib-haxe-org.bucket 7 | access_control_policy { 8 | grant { 9 | grantee { 10 | id = data.aws_canonical_user_id.current.id 11 | type = "CanonicalUser" 12 | } 13 | permission = "FULL_CONTROL" 14 | } 15 | 16 | grant { 17 | grantee { 18 | id = "c4c1ede66af53448b93c283ce9448c4ba468c9432aa01d700d3878632f77d2d0" 19 | type = "CanonicalUser" 20 | } 21 | permission = "FULL_CONTROL" 22 | } 23 | 24 | owner { 25 | id = data.aws_canonical_user_id.current.id 26 | } 27 | } 28 | } 29 | 30 | resource "aws_s3_bucket_website_configuration" "lib-haxe-org" { 31 | bucket = aws_s3_bucket.lib-haxe-org.bucket 32 | 33 | index_document { 34 | suffix = "index.html" 35 | } 36 | } 37 | 38 | resource "aws_s3_bucket_versioning" "lib-haxe-org" { 39 | bucket = aws_s3_bucket.lib-haxe-org.bucket 40 | versioning_configuration { 41 | status = "Enabled" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /terraform/bitnami/mysql/templates/primary/pdb.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.primary.pdb.enabled }} 2 | apiVersion: policy/v1beta1 3 | kind: PodDisruptionBudget 4 | metadata: 5 | name: {{ include "mysql.primary.fullname" . }} 6 | namespace: {{ .Release.Namespace }} 7 | labels: {{- include "common.labels.standard" . | nindent 4 }} 8 | app.kubernetes.io/component: primary 9 | {{- if .Values.commonLabels }} 10 | {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} 11 | {{- end }} 12 | {{- if .Values.commonAnnotations }} 13 | annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} 14 | {{- end }} 15 | spec: 16 | {{- if .Values.primary.pdb.minAvailable }} 17 | minAvailable: {{ .Values.primary.pdb.minAvailable }} 18 | {{- end }} 19 | {{- if .Values.primary.pdb.maxUnavailable }} 20 | maxUnavailable: {{ .Values.primary.pdb.maxUnavailable }} 21 | {{- end }} 22 | selector: 23 | matchLabels: {{ include "common.labels.matchLabels" . | nindent 6 }} 24 | app.kubernetes.io/component: primary 25 | {{- end }} 26 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "type": "haxe", 6 | "args": "active configuration", 7 | "group": { 8 | "kind": "build", 9 | "isDefault": true 10 | } 11 | }, 12 | { 13 | "type": "shell", 14 | "command": "neko", 15 | "label": "Haxelib Client Unit Tests", 16 | "args": [ 17 | "bin/test.n" 18 | ], 19 | "dependsOrder": "sequence", 20 | "dependsOn": [ 21 | "haxe: client_tests.hxml" 22 | ], 23 | "problemMatcher": [ 24 | "$haxe", 25 | "$haxe-absolute", 26 | "$haxe-error", 27 | "$haxe-trace" 28 | ], 29 | "group": { 30 | "kind": "test", 31 | "isDefault": true 32 | } 33 | }, 34 | { 35 | "type": "shell", 36 | "command": "neko", 37 | "label": "Haxelib Integration Tests", 38 | "args": [ 39 | "bin/integration_tests.n" 40 | ], 41 | "dependsOrder": "sequence", 42 | "dependsOn": [ 43 | "haxe: integration_tests.hxml" 44 | ], 45 | "problemMatcher": [ 46 | "$haxe", 47 | "$haxe-absolute", 48 | "$haxe-error", 49 | "$haxe-trace" 50 | ], 51 | "group": "test" 52 | } 53 | ] 54 | } 55 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2005-2024 Haxe Foundation 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/website/tasks/HaxelibCacheTasks.hx: -------------------------------------------------------------------------------- 1 | package website.tasks; 2 | 3 | import ufront.tasks.UFTaskSet; 4 | import ufront.cache.DBCache; 5 | import ufront.cache.RequestCacheMiddleware; 6 | import website.api.ProjectApi; 7 | 8 | class HaxelibCacheTasks extends UFTaskSet { 9 | @:skip @inject public var api:DBCacheApi; 10 | 11 | /** Set up the cache table. **/ 12 | public function setup():Void api.setup(); 13 | 14 | /** Clear every cached item. **/ 15 | public function clearAll():Void api.clearAll(); 16 | 17 | /** Clear all cached pages. **/ 18 | public function clearPageCache() api.clearNamespace( RequestCacheMiddleware.namespace ); 19 | 20 | /** Clear a projects zip file cache entries, and also the page caches for that project. **/ 21 | public function clearZipCache( project:String, version:String ) { 22 | var namespaces = ProjectApi.cacheNames; 23 | var prefix = '$project:$version:%'; 24 | api.clearItemLike( namespaces.info, prefix ); 25 | api.clearItemLike( namespaces.dirListing, prefix ); 26 | api.clearItemLike( namespaces.fileBytes, prefix ); 27 | api.clearItemLike( RequestCacheMiddleware.namespace, '/p/$project/%' ); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /terraform/cloudflare.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | cloudflare = { 3 | account_id = "09c8df40903546d43dba5a1924ee4b43" 4 | zones = { 5 | haxe-org = { 6 | zone_id = "01d9191b31046d86b5d7ba8f44c89b7c" 7 | } 8 | } 9 | } 10 | } 11 | 12 | resource "cloudflare_record" "lib-haxe-org" { 13 | zone_id = local.cloudflare.zones.haxe-org.zone_id 14 | name = "lib" 15 | type = "CNAME" 16 | ttl = "1800" 17 | value = "do-k8s.haxe.org" 18 | } 19 | 20 | resource "cloudflare_record" "development-lib" { 21 | zone_id = local.cloudflare.zones.haxe-org.zone_id 22 | name = "development-lib" 23 | type = "CNAME" 24 | ttl = "1800" 25 | value = "do-k8s.haxe.org" 26 | } 27 | 28 | resource "cloudflare_record" "do-lib" { 29 | zone_id = local.cloudflare.zones.haxe-org.zone_id 30 | name = "do-lib" 31 | type = "CNAME" 32 | ttl = "86400" 33 | value = "do-k8s.haxe.org" 34 | } 35 | 36 | resource "cloudflare_record" "do-development-lib" { 37 | zone_id = local.cloudflare.zones.haxe-org.zone_id 38 | name = "do-development-lib" 39 | type = "CNAME" 40 | ttl = "86400" 41 | value = "do-k8s.haxe.org" 42 | } 43 | -------------------------------------------------------------------------------- /test/tests/integration/TestGit.hx: -------------------------------------------------------------------------------- 1 | package tests.integration; 2 | 3 | import haxelib.api.FsUtils; 4 | import haxelib.api.Vcs; 5 | import tests.util.Vcs; 6 | 7 | class TestGit extends TestVcs { 8 | public function new () { 9 | super("git"); 10 | } 11 | 12 | override function setup() { 13 | super.setup(); 14 | 15 | makeGitRepo(vcsLibPath, ["haxelib.xml"]); 16 | createGitTag(vcsLibPath, vcsTag); 17 | 18 | makeGitRepo(vcsLibNoHaxelibJson); 19 | makeGitRepo(vcsBrokenDependency); 20 | } 21 | 22 | override function tearDown() { 23 | resetGitRepo(vcsLibPath); 24 | resetGitRepo(vcsLibNoHaxelibJson); 25 | resetGitRepo(vcsBrokenDependency); 26 | 27 | super.tearDown(); 28 | } 29 | 30 | public function updateVcsRepo() { 31 | addToGitRepo(vcsLibPath, "haxelib.xml"); 32 | } 33 | 34 | public function getVcsCommit():String { 35 | return FsUtils.runInDirectory(vcsLibPath, Vcs.create(Git).getRef); 36 | } 37 | 38 | function testInstallShortcommit() { 39 | 40 | final shortCommitId = getVcsCommit().substr(0, 7); 41 | 42 | updateVcsRepo(); 43 | 44 | final r = haxelib([cmd, "Bar", vcsLibPath, shortCommitId]).result(); 45 | assertSuccess(r); 46 | 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /terraform/bitnami/mysql/templates/secondary/pdb.yaml: -------------------------------------------------------------------------------- 1 | {{- if and (eq .Values.architecture "replication") .Values.secondary.pdb.enabled }} 2 | apiVersion: policy/v1beta1 3 | kind: PodDisruptionBudget 4 | metadata: 5 | name: {{ include "mysql.secondary.fullname" . }} 6 | namespace: {{ .Release.Namespace }} 7 | labels: {{- include "common.labels.standard" . | nindent 4 }} 8 | app.kubernetes.io/component: secondary 9 | {{- if .Values.commonLabels }} 10 | {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} 11 | {{- end }} 12 | {{- if .Values.commonAnnotations }} 13 | annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} 14 | {{- end }} 15 | spec: 16 | {{- if .Values.secondary.pdb.minAvailable }} 17 | minAvailable: {{ .Values.secondary.pdb.minAvailable }} 18 | {{- end }} 19 | {{- if .Values.secondary.pdb.maxUnavailable }} 20 | maxUnavailable: {{ .Values.secondary.pdb.maxUnavailable }} 21 | {{- end }} 22 | selector: 23 | matchLabels: {{ include "common.labels.matchLabels" . | nindent 6 }} 24 | app.kubernetes.io/component: secondary 25 | {{- end }} 26 | -------------------------------------------------------------------------------- /www/view/home/projectList.html: -------------------------------------------------------------------------------- 1 |

@title

2 |

@description

3 | 4 |
5 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | @for (p in projects) { 27 | 28 | 32 | 33 | 34 | 35 | 36 | } 37 | 38 |
ProjectDescriptionVersionDownloads
29 | @p.name 30 |
@@@p.author 31 |
@p.description@p.version.name
@formatDate(p.version.date)
@p.downloads
39 | -------------------------------------------------------------------------------- /.devcontainer/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | workspace: 4 | image: haxe/haxelib_devcontainer_workspace:development 5 | init: true 6 | volumes: 7 | - /var/run/docker.sock:/var/run/docker-host.sock 8 | - ./rclone:/home/vscode/.config/rclone:cached 9 | - ..:/workspace:cached 10 | environment: 11 | - HAXELIB_SERVER=localhost 12 | - HAXELIB_SERVER_PORT=80 13 | - HAXELIB_DB_HOST=localhost 14 | - HAXELIB_DB_PORT=3306 15 | - HAXELIB_DB_USER=dbUser 16 | - HAXELIB_DB_PASS=dbPass 17 | - HAXELIB_DB_NAME=haxelib 18 | - EARTHLY_BUILDKIT_HOST=tcp://earthly:8372 19 | - EARTHLY_USE_INLINE_CACHE=true 20 | - EARTHLY_SAVE_INLINE_CACHE=true 21 | user: vscode 22 | entrypoint: /usr/local/share/docker-init.sh 23 | command: sleep infinity 24 | earthly: 25 | image: earthly/buildkitd:v0.6.30 26 | privileged: true 27 | environment: 28 | - BUILDKIT_TCP_TRANSPORT_ENABLED=true 29 | expose: 30 | - 8372 31 | volumes: 32 | # https://docs.earthly.dev/docs/guides/using-the-earthly-docker-images/buildkit-standalone#earthly_tmp_dir 33 | - earthly-tmp:/tmp/earthly:rw 34 | 35 | volumes: 36 | earthly-tmp: 37 | -------------------------------------------------------------------------------- /www/view/user/profile.html: -------------------------------------------------------------------------------- 1 |
2 |

« All Haxelib Contributors

3 |
4 | 5 | 16 | 17 |

Projects

18 | 19 |
20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | @for( p in projects ) { 29 | 30 | 31 | 32 | 33 | 34 | } 35 |
ProjectDownloads
@p.name@p.description@p.downloads
36 |
37 |
38 | -------------------------------------------------------------------------------- /test/TestBase.hx: -------------------------------------------------------------------------------- 1 | import sys.FileSystem; 2 | import sys.io.Process; 3 | import haxe.io.Eof; 4 | import haxe.unit.TestCase; 5 | 6 | 7 | class TestBase extends TestCase { 8 | static final haxelibPath = FileSystem.fullPath("run.n"); 9 | 10 | public function runHaxelib(args:Array, printProgress = false) { 11 | final p = new Process("neko", [haxelibPath].concat(args)); 12 | var stdout = ''; 13 | var stderr = ''; 14 | var eofCount = 0; 15 | var c; 16 | while (eofCount < 2) { 17 | eofCount = 0; 18 | try { 19 | c = p.stdout.readByte(); 20 | if (printProgress) Sys.stdout().writeByte(c); 21 | stdout += String.fromCharCode(c); 22 | } catch(e:Eof) { 23 | eofCount++; 24 | } 25 | try { 26 | c = p.stderr.readByte(); 27 | if (printProgress) Sys.stderr().writeByte(c); 28 | stderr += String.fromCharCode(c); 29 | } catch(e:Eof) { 30 | eofCount++; 31 | } 32 | } 33 | if (printProgress) { 34 | Sys.stdout().flush(); 35 | Sys.stderr().flush(); 36 | } 37 | final exitCode = p.exitCode(); 38 | p.close(); 39 | return { 40 | stdout: stdout, 41 | stderr: stderr, 42 | exitCode: exitCode 43 | } 44 | } 45 | 46 | public function deleteDirectory(dir:String):Void { 47 | HaxelibTests.deleteDirectory(dir); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /test/tests/TestLibFlagData.hx: -------------------------------------------------------------------------------- 1 | package tests; 2 | 3 | import haxe.io.Path; 4 | import haxelib.api.LibFlagData; 5 | 6 | using Lambda; 7 | 8 | class TestLibFlagData extends TestBase { 9 | 10 | static var CWD:String = null; 11 | 12 | override function setup() { 13 | CWD = Sys.getCwd(); 14 | 15 | final dir = Path.join([CWD, "test/libraries/InstallDeps"]); 16 | Sys.setCwd(dir); 17 | } 18 | 19 | override function tearDown() { 20 | Sys.setCwd(CWD); 21 | } 22 | 23 | function testTargetFlag() { 24 | final libraries = fromHxml("cpp.hxml"); 25 | 26 | assertEquals(1, libraries.count(f -> f.name == "hxcpp")); 27 | 28 | final libraries = fromHxml("cpp-single.hxml"); 29 | 30 | assertEquals(1, libraries.count(f -> f.name == "hxcpp")); 31 | } 32 | 33 | // test for issue #511 34 | function testBackendExplicit() { 35 | final libraries = fromHxml("target-lib.hxml"); 36 | 37 | assertEquals(1, libraries.count(f -> f.name == "hxcpp")); 38 | } 39 | 40 | // specified explicitly with non-standard capitalisation 41 | function testBackendExplicitUppercase() { 42 | final libraries = fromHxml("target-lib-uppercase.hxml"); 43 | 44 | assertEquals(1, libraries.count(f -> f.name == "HXCPP")); 45 | assertEquals(0, libraries.count(f -> f.name == "hxcpp")); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /terraform/bitnami/mysql/templates/metrics-svc.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.metrics.enabled }} 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | name: {{ printf "%s-metrics" (include "common.names.fullname" .) }} 6 | namespace: {{ .Release.Namespace }} 7 | labels: {{- include "common.labels.standard" . | nindent 4 }} 8 | {{- if .Values.commonLabels }} 9 | {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} 10 | {{- end }} 11 | app.kubernetes.io/component: metrics 12 | {{- if or .Values.metrics.service.annotations .Values.commonAnnotations }} 13 | annotations: 14 | {{- if .Values.metrics.service.annotations }} 15 | {{- include "common.tplvalues.render" (dict "value" .Values.metrics.service.annotations "context" $) | nindent 4 }} 16 | {{- end }} 17 | {{- if .Values.commonAnnotations }} 18 | {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} 19 | {{- end }} 20 | {{- end }} 21 | spec: 22 | type: {{ .Values.metrics.service.type }} 23 | ports: 24 | - port: {{ .Values.metrics.service.port }} 25 | targetPort: metrics 26 | protocol: TCP 27 | name: metrics 28 | selector: {{- include "common.labels.matchLabels" $ | nindent 4 }} 29 | {{- end }} 30 | -------------------------------------------------------------------------------- /test/tests/integration/TestUser.hx: -------------------------------------------------------------------------------- 1 | package tests.integration; 2 | 3 | class TestUser extends IntegrationTests { 4 | function test():Void { 5 | { 6 | final r = haxelib(["register", bar.user, bar.email, bar.fullname, bar.pw, bar.pw]).result(); 7 | assertSuccess(r); 8 | } 9 | 10 | { 11 | final r = haxelib(["user", "Bar"]).result(); 12 | assertSuccess(r); 13 | 14 | assertTrue(r.out.indexOf("Bar") >= 0); 15 | 16 | assertTrue(r.out.indexOf(bar.email) == -1); 17 | assertTrue(r.out.indexOf("(private)") >= 0); 18 | assertTrue(r.out.indexOf(bar.fullname) >= 0); 19 | assertTrue(r.out.indexOf(bar.pw) == -1); 20 | } 21 | 22 | { 23 | final r = haxelib(["submit", Path.join([IntegrationTests.projectRoot, "test/libraries/UseCp.zip"]), bar.pw]).result(); 24 | assertSuccess(r); 25 | } 26 | 27 | { 28 | final r = haxelib(["user", "Bar"]).result(); 29 | assertSuccess(r); 30 | 31 | assertTrue(r.out.indexOf("Bar") >= 0); 32 | 33 | assertTrue(r.out.indexOf(bar.email) == -1); 34 | assertTrue(r.out.indexOf("(private)") >= 0); 35 | assertTrue(r.out.indexOf(bar.fullname) >= 0); 36 | assertTrue(r.out.indexOf(bar.pw) == -1); 37 | 38 | assertTrue(r.out.indexOf("UseCp") >= 0); 39 | } 40 | } 41 | 42 | function testNotExist():Void { 43 | { 44 | final r = haxelib(["user", "Bar"]).result(); 45 | assertTrue(r.code != 0); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /test/tests/TestRemoveSymlinks.hx: -------------------------------------------------------------------------------- 1 | package tests; 2 | 3 | import sys.FileSystem; 4 | import haxe.io.Path; 5 | 6 | import haxelib.api.RepoManager; 7 | import haxelib.api.Installer; 8 | import haxelib.api.Scope; 9 | 10 | class TestRemoveSymlinks extends TestBase 11 | { 12 | //----------- properties, fields ------------// 13 | 14 | static final REPO = "haxelib-repo"; 15 | final repo:String; 16 | var lib:String; 17 | var origRepo:String; 18 | 19 | //--------------- constructor ---------------// 20 | public function new() { 21 | super(); 22 | lib = "symlinks"; 23 | 24 | repo = Path.join([Sys.getCwd(), "test", REPO]); 25 | } 26 | 27 | //--------------- initialize ----------------// 28 | 29 | override public function setup():Void { 30 | origRepo = RepoManager.getGlobalPath(); 31 | 32 | final libzip = Path.join([Sys.getCwd(), "test", "libraries", lib + ".zip"]); 33 | 34 | RepoManager.setGlobalPath(repo); 35 | 36 | final installer = new Installer(getScope()); 37 | installer.installLocal(libzip); 38 | } 39 | 40 | override public function tearDown():Void { 41 | RepoManager.setGlobalPath(origRepo); 42 | 43 | deleteDirectory(repo); 44 | } 45 | 46 | //----------------- tests -------------------// 47 | 48 | public function testRemoveLibWithSymlinks():Void { 49 | final code = runHaxelib(["remove", lib]).exitCode; 50 | assertEquals(code, 0); 51 | assertFalse(FileSystem.exists(Path.join([repo, lib]))); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /www/view/home/recent.html: -------------------------------------------------------------------------------- 1 |

Latest updates

2 |

@description

3 | 4 |
5 | 14 |
15 | 16 | @{ var prevDate = null;} 17 | 18 | @for (update in projects) { 19 | @{ var curDate = formatDate(update.v.date); } 20 | @if(prevDate != curDate) { 21 | 22 | 23 | 24 | 25 | 26 | 27 | } 28 | 29 | 33 | 34 | 35 | 36 | 37 | @{prevDate = curDate;} 38 | } 39 |

@curDate

ProjectChangesVersion
30 | @update.p.name 31 | 32 | @if (update.v.comments != null && update.v.comments.length > 0){@escape(update.v.comments)}@update.v.name
@formatDate(update.v.date, true)
40 | -------------------------------------------------------------------------------- /test/WebsiteTests.hx: -------------------------------------------------------------------------------- 1 | package; 2 | 3 | import website.api.ProjectListApi; 4 | import ufront.app.UfrontApplication; 5 | import ufront.mailer.*; 6 | import ufront.auth.EasyAuth; 7 | import ufront.view.TemplatingEngines; 8 | import twl.webapp.*; 9 | import twl.*; 10 | import buddy.*; 11 | 12 | class WebsiteTests implements Buddy<[ 13 | website.controller.DocumentationControllerTest, 14 | website.controller.HomeControllerTest, 15 | // website.controller.ProjectControllerTest, 16 | website.controller.RSSControllerTest, 17 | // website.controller.UserControllerTest, 18 | ]> { 19 | static var ufApp:UfrontApplication; 20 | 21 | public static function getTestApp():UfrontApplication { 22 | if ( ufApp==null ) { 23 | // Create a UfrontApplication suitable for unit testing. 24 | ufApp = new UfrontApplication({ 25 | indexController: website.controller.HomeController, 26 | errorHandlers: [], 27 | disableBrowserTrace: true, 28 | contentDirectory: "../uf-content/", 29 | templatingEngines: [TemplatingEngines.erazor], 30 | viewPath: "www/view/", 31 | defaultLayout: "layout.html", 32 | }); 33 | 34 | // Different injections for our test suite. 35 | ufApp.injector.map( UFMailer ).toSingleton( TestMailer ); 36 | ufApp.injector.map( EasyAuth ).toValue( new EasyAuthAdminMode() ); 37 | ufApp.injector.map( String, "documentationPath" ).toValue( "www/documentation-files/" ); 38 | 39 | haxelib.server.SiteDb.init(); 40 | } 41 | return ufApp; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/website/controller/DocumentationController.hx: -------------------------------------------------------------------------------- 1 | package website.controller; 2 | 3 | import ufront.web.Controller; 4 | import ufront.web.result.*; 5 | import website.api.DocumentationApi; 6 | import ufront.core.OrderedStringMap; 7 | using tink.CoreApi; 8 | 9 | @cacheRequest 10 | class DocumentationController extends Controller { 11 | 12 | @inject public var api:DocumentationApi; 13 | 14 | @:route("/$page") 15 | public function documentationPage( ?page:String ) { 16 | var html = api.getDocumentationHTML( page ).sure(); 17 | var documentationPages = getDocumentationPages(); 18 | var docTitle = 19 | if ( page==null ) documentationPages.get('/documentation/'); 20 | else documentationPages.get('/documentation/$page/'); 21 | return new ViewResult({ 22 | title: '$docTitle - Haxelib Documentation', 23 | content: html, 24 | }); 25 | } 26 | 27 | public static function getDocumentationPages():OrderedStringMap { 28 | var pages = new OrderedStringMap(); 29 | pages.set( "/documentation/", "Getting Started" ); 30 | pages.set( "/documentation/using-haxelib/", "Using Haxelib" ); 31 | pages.set( "/documentation/creating-a-haxelib-package/", "Creating a Haxelib" ); 32 | pages.set( "/documentation/per-project-setup/", "Per project setup" ); 33 | pages.set( "/documentation/haxelibs-in-projects/", "Adding libraries to projects" ); 34 | pages.set( "/documentation/faq/", "FAQ" ); 35 | // pages.set( "/documentation/api/", "API" ); 36 | return pages; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /.github/workflows/ci-prod.yml: -------------------------------------------------------------------------------- 1 | name: CI-prod 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | workflow_dispatch: 8 | 9 | jobs: 10 | deploy-prod: 11 | concurrency: deploy 12 | runs-on: ubuntu-latest 13 | container: haxe/haxelib_devcontainer_workspace:${{ github.sha }} 14 | env: 15 | AWS_DEFAULT_REGION: eu-west-1 16 | AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} 17 | AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} 18 | DIGITALOCEAN_ACCESS_TOKEN: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }} 19 | SPACES_ACCESS_KEY_ID: ${{ secrets.SPACES_ACCESS_KEY_ID }} 20 | SPACES_SECRET_ACCESS_KEY: ${{ secrets.SPACES_SECRET_ACCESS_KEY }} 21 | TF_VAR_HAXELIB_DB_PASS: ${{ secrets.TF_VAR_HAXELIB_DB_PASS }} 22 | TF_INPUT: 0 23 | TF_IN_AUTOMATION: 1 24 | steps: 25 | - uses: actions/checkout@v2 26 | - name: Verify image existence 27 | run: docker manifest inspect haxe/lib.haxe.org:${{ github.sha }} 28 | - name: Initialize Terraform 29 | run: terraform init 30 | working-directory: terraform 31 | - name: Ensure no pending infra changes 32 | run: terraform plan -refresh=false -detailed-exitcode 33 | working-directory: terraform 34 | - name: Set haxelib-server image 35 | run: terraform apply -auto-approve -refresh=false 36 | working-directory: terraform 37 | env: 38 | TF_VAR_HAXELIB_SERVER_IMAGE_MASTER: haxe/lib.haxe.org:${{ github.sha }} 39 | -------------------------------------------------------------------------------- /src/legacyhaxelib/Remoting_SiteApi.hx: -------------------------------------------------------------------------------- 1 | package legacyhaxelib; 2 | 3 | class Remoting_SiteApi { 4 | public function new(c:haxe.remoting.Connection) { 5 | this.__cnx = c; 6 | } 7 | var __cnx : haxe.remoting.Connection; 8 | public function search(word:String):List<{ public var name(default, default) : String; public var id(default, default) : StdTypes.Int; }> return __cnx.resolve("search").call([word]); 9 | public function infos(project:String):legacyhaxelib.Data.ProjectInfos return __cnx.resolve("infos").call([project]); 10 | public function user(name:String):legacyhaxelib.Data.UserInfos return __cnx.resolve("user").call([name]); 11 | public function register(name:String, pass:String, mail:String, fullname:String):StdTypes.Bool return __cnx.resolve("register").call([name, pass, mail, fullname]); 12 | public function isNewUser(name:String):StdTypes.Bool return __cnx.resolve("isNewUser").call([name]); 13 | public function checkDeveloper(prj:String, user:String):StdTypes.Void __cnx.resolve("checkDeveloper").call([prj, user]); 14 | public function checkPassword(user:String, pass:String):StdTypes.Bool return __cnx.resolve("checkPassword").call([user, pass]); 15 | public function getSubmitId():String return __cnx.resolve("getSubmitId").call([]); 16 | public function processSubmit(id:String, user:String, pass:String):String return __cnx.resolve("processSubmit").call([id, user, pass]); 17 | public function postInstall(project:String, version:String):StdTypes.Void __cnx.resolve("postInstall").call([project, version]); 18 | } -------------------------------------------------------------------------------- /terraform/bitnami/mysql/templates/networkpolicy.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.networkPolicy.enabled }} 2 | kind: NetworkPolicy 3 | apiVersion: {{ template "common.capabilities.networkPolicy.apiVersion" . }} 4 | metadata: 5 | name: {{ template "common.names.fullname" . }} 6 | labels: 7 | {{- include "common.labels.standard" . | nindent 4 }} 8 | {{- if .Values.commonAnnotations }} 9 | annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} 10 | {{- end }} 11 | namespace: {{ .Release.Namespace }} 12 | spec: 13 | podSelector: 14 | matchLabels: 15 | {{- include "common.labels.matchLabels" . | nindent 6 }} 16 | ingress: 17 | # Allow inbound connections 18 | - ports: 19 | - port: {{ .Values.primary.service.port }} 20 | {{- if not .Values.networkPolicy.allowExternal }} 21 | from: 22 | - podSelector: 23 | matchLabels: 24 | {{ template "common.names.fullname" . }}-client: "true" 25 | {{- if .Values.networkPolicy.explicitNamespacesSelector }} 26 | namespaceSelector: 27 | {{ toYaml .Values.networkPolicy.explicitNamespacesSelector | indent 12 }} 28 | {{- end }} 29 | - podSelector: 30 | matchLabels: 31 | {{- include "common.labels.matchLabels" . | nindent 14 }} 32 | {{- end }} 33 | {{- if .Values.metrics.enabled }} 34 | # Allow prometheus scrapes 35 | - ports: 36 | - port: 9104 37 | {{- end }} 38 | {{- end }} 39 | -------------------------------------------------------------------------------- /www/view/home/tagProjectList.html: -------------------------------------------------------------------------------- 1 | 2 |

Tagged with @currentTag

3 |

@description

4 | 5 |
6 | 15 |
16 | 17 |
18 |
19 |

All Tags

20 |
    21 | @for (t in tags) { 22 |
  • @t.tag (@t.count)
  • 23 | } 24 |
25 |
26 |
27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | @for (p in projects) { 39 | 40 | 44 | 45 | 46 | 47 | 48 | } 49 | 50 |
ProjectDescriptionVersionDownloads
41 | @p.name 42 |
@@@p.author 43 |
@p.description@p.version.name@p.downloads
51 |
52 |
53 | 54 | -------------------------------------------------------------------------------- /test/website/controller/RSSControllerTest.hx: -------------------------------------------------------------------------------- 1 | package website.controller; 2 | 3 | import website.controller.*; 4 | import ufront.web.result.*; 5 | import website.Server; 6 | 7 | // These imports are common for our various test-suite tools. 8 | import buddy.*; 9 | import mockatoo.Mockatoo.*; 10 | import ufront.test.TestUtils.NaturalLanguageTests.*; 11 | import utest.Assert; 12 | using buddy.Should; 13 | using ufront.test.TestUtils; 14 | using mockatoo.Mockatoo; 15 | 16 | class RSSControllerTest extends BuddySuite { 17 | public function new() { 18 | 19 | var haxelibSite = WebsiteTests.getTestApp(); 20 | 21 | describe("When I try to view the RSS feed", { 22 | it("Should give me some valid XML with the latest updates", function (done) { 23 | whenIVisit( "/rss" ) 24 | .onTheApp( haxelibSite ) 25 | .itShouldLoad( RSSController, "rss", [{number:null}] ) 26 | .itShouldReturn( ContentResult, function (result) { 27 | result.contentType.should.be( "text/xml" ); 28 | var rss = Xml.parse( result.content ); 29 | }) 30 | .andFinishWith( done ); 31 | }); 32 | it("Should let me set the number of entries to include", function (done) { 33 | whenIVisit( "/rss" ) 34 | .withTheQueryParams([ "number"=>"3" ]) 35 | .onTheApp( haxelibSite ) 36 | .itShouldLoad( RSSController, "rss", [{number:3}] ) 37 | .itShouldReturn( ContentResult, function (result) { 38 | result.contentType.should.be( "text/xml" ); 39 | var rss = Xml.parse( result.content ); 40 | // TODO: check that 3 results were loaded. 41 | }) 42 | .andFinishWith( done ); 43 | }); 44 | }); 45 | } 46 | } -------------------------------------------------------------------------------- /src/website/Tasks.hx: -------------------------------------------------------------------------------- 1 | package website; 2 | 3 | import haxelib.server.SiteDb; 4 | import mcli.Dispatch; 5 | import ufront.api.UFApi; 6 | import ufront.tasks.UFTaskSet; 7 | import ufront.auth.*; 8 | import ufront.auth.tasks.EasyAuthTasks; 9 | import ufront.auth.EasyAuth; 10 | import ufront.web.session.*; 11 | import website.tasks.*; 12 | using ufront.core.InjectionTools; 13 | 14 | class Tasks extends UFTaskSet 15 | { 16 | /** 17 | The CLI runner. 18 | **/ 19 | static function main() { 20 | // Only access the command line runner from the command line, not the web. 21 | if ( !neko.Web.isModNeko ) { 22 | 23 | // This is an auth system that lets you do anything regardless of permissions, handy for CLI tools 24 | var auth = new EasyAuthAdminMode(); 25 | 26 | var tasks = new Tasks(); 27 | tasks.injector.map( UFHttpSession ).toValue( new VoidSession() ); 28 | tasks.injector.map( UFAuthHandler ).toValue( auth ); 29 | tasks.injector.map( EasyAuth ).toValue( auth ); 30 | tasks.injector.map( String, "contentDirectory" ).toValue( "../uf-content" ); 31 | tasks.useCLILogging( "log/twl-webapp.log" ); 32 | 33 | // Inject our APIs 34 | for ( api in CompileTime.getAllClasses(UFApi) ) 35 | tasks.injector.mapRuntimeTypeOf( api ); 36 | 37 | SiteDb.init(); 38 | tasks.execute( Sys.args() ); 39 | SiteDb.cleanup(); 40 | } 41 | } 42 | 43 | /** 44 | Easyauth task set 45 | @alias a 46 | **/ 47 | public function auth( d:Dispatch ) { 48 | executeSubTasks( d, EasyAuthTasks ); 49 | } 50 | 51 | /** 52 | DBCache task set 53 | @alias c 54 | **/ 55 | public function cache( d:Dispatch ) { 56 | executeSubTasks( d, HaxelibCacheTasks ); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /test/tests/integration/TestInfo.hx: -------------------------------------------------------------------------------- 1 | package tests.integration; 2 | 3 | class TestInfo extends IntegrationTests { 4 | function test():Void { 5 | { 6 | final r = haxelib(["register", bar.user, bar.email, bar.fullname, bar.pw, bar.pw]).result(); 7 | assertSuccess(r); 8 | } 9 | 10 | { 11 | final r = haxelib(["submit", Path.join([IntegrationTests.projectRoot, "test/libraries/libBar.zip"]), bar.pw]).result(); 12 | assertSuccess(r); 13 | } 14 | 15 | { 16 | final r = haxelib(["info", "Bar"]).result(); 17 | assertSuccess(r); 18 | 19 | assertTrue(r.out.indexOf("Bar") >= 0); 20 | 21 | // license 22 | assertTrue(r.out.indexOf("GPL") >= 0); 23 | 24 | // tags 25 | assertTrue(r.out.indexOf("bar") >= 0); 26 | assertTrue(r.out.indexOf("test") >= 0); 27 | 28 | // versions 29 | assertTrue(r.out.indexOf("1.0.0") >= 0); 30 | } 31 | 32 | { 33 | final r = haxelib(["submit", Path.join([IntegrationTests.projectRoot, "test/libraries/libBar2.zip"]), bar.pw]).result(); 34 | assertSuccess(r); 35 | } 36 | 37 | { 38 | final r = haxelib(["info", "Bar"]).result(); 39 | assertSuccess(r); 40 | 41 | assertTrue(r.out.indexOf("Bar") >= 0); 42 | 43 | // license 44 | assertTrue(r.out.indexOf("MIT") >= 0); 45 | 46 | // tags 47 | assertTrue(r.out.indexOf("bar") >= 0); 48 | assertTrue(r.out.indexOf("test") == -1); 49 | assertTrue(r.out.indexOf("version2") >= 0); 50 | 51 | // versions 52 | assertTrue(r.out.indexOf("1.0.0") >= 0); 53 | assertTrue(r.out.indexOf("2.0.0") >= 0); 54 | } 55 | } 56 | 57 | function testNotExist():Void { 58 | { 59 | final r = haxelib(["info", "Bar"]).result(); 60 | assertTrue(r.code != 0); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /terraform/bitnami/mysql/charts/common/templates/_errors.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Through error when upgrading using empty passwords values that must not be empty. 4 | 5 | Usage: 6 | {{- $validationError00 := include "common.validations.values.single.empty" (dict "valueKey" "path.to.password00" "secret" "secretName" "field" "password-00") -}} 7 | {{- $validationError01 := include "common.validations.values.single.empty" (dict "valueKey" "path.to.password01" "secret" "secretName" "field" "password-01") -}} 8 | {{ include "common.errors.upgrade.passwords.empty" (dict "validationErrors" (list $validationError00 $validationError01) "context" $) }} 9 | 10 | Required password params: 11 | - validationErrors - String - Required. List of validation strings to be return, if it is empty it won't throw error. 12 | - context - Context - Required. Parent context. 13 | */}} 14 | {{- define "common.errors.upgrade.passwords.empty" -}} 15 | {{- $validationErrors := join "" .validationErrors -}} 16 | {{- if and $validationErrors .context.Release.IsUpgrade -}} 17 | {{- $errorString := "\nPASSWORDS ERROR: You must provide your current passwords when upgrading the release." -}} 18 | {{- $errorString = print $errorString "\n Note that even after reinstallation, old credentials may be needed as they may be kept in persistent volume claims." -}} 19 | {{- $errorString = print $errorString "\n Further information can be obtained at https://docs.bitnami.com/general/how-to/troubleshoot-helm-chart-issues/#credential-errors-while-upgrading-chart-releases" -}} 20 | {{- $errorString = print $errorString "\n%s" -}} 21 | {{- printf $errorString $validationErrors | fail -}} 22 | {{- end -}} 23 | {{- end -}} 24 | -------------------------------------------------------------------------------- /test/tests/TestGlobalScope.hx: -------------------------------------------------------------------------------- 1 | package tests; 2 | 3 | import sys.FileSystem; 4 | 5 | import tests.util.DirectoryState; 6 | 7 | import haxelib.ProjectName; 8 | import haxelib.SemVer; 9 | import haxelib.VersionData.VcsID; 10 | 11 | using haxe.io.Path; 12 | 13 | class TestGlobalScope extends TestScope { 14 | 15 | final scopeDir = new DirectoryState(TestScope.repo, 16 | ["devlib"], 17 | [ 18 | 'lib/.current' => "2.0.0", 19 | 'devlib/.dev' => FileSystem.absolutePath(TestScope.devlibPath), 20 | 'capitalized/.name' => "Capitalized", 21 | 'capitalized/.current' => "1.0.0" 22 | ] 23 | ); 24 | 25 | function initScope():Void { 26 | scopeDir.add(); 27 | } 28 | 29 | 30 | override function tearDown() { 31 | deleteDirectory('${TestScope.repo}/broken/'); 32 | super.tearDown(); 33 | } 34 | 35 | function testGetPathNonCurrent() { 36 | // global scope can also get path for non-current versions 37 | final lib = ProjectName.ofString("lib"); 38 | 39 | assertEquals('${TestScope.repo}/${TestScope.lib2Path}', scope.getPath(lib)); 40 | 41 | assertEquals('${TestScope.repo}/${TestScope.lib1Path}', scope.getPath(lib, SemVer.ofString("1.0.0"))); 42 | 43 | assertEquals('${TestScope.repo}/${TestScope.libGitPath}', scope.getPath(lib, VcsID.Git)); 44 | } 45 | 46 | function testIsInstalledBroken() { 47 | FileSystem.createDirectory('${TestScope.repo}/broken/'); 48 | assertFalse(scope.isLibraryInstalled(ProjectName.ofString("broken"))); 49 | } 50 | 51 | function testRunScriptNonCurrent() { 52 | // global scope can also run script for non-current versions 53 | try { 54 | scope.runScript(ProjectName.ofString("lib"), {args: ["LIB"]}, VcsID.Git); 55 | assertTrue(true); 56 | } catch (e) { 57 | assertTrue(false); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /test/website/controller/DocumentationControllerTest.hx: -------------------------------------------------------------------------------- 1 | package website.controller; 2 | 3 | import website.controller.*; 4 | import ufront.web.result.ViewResult; 5 | import website.Server; 6 | using tink.CoreApi; 7 | 8 | // These imports are common for our various test-suite tools. 9 | import buddy.*; 10 | import mockatoo.Mockatoo.*; 11 | import ufront.test.TestUtils.NaturalLanguageTests.*; 12 | import utest.Assert; 13 | using haxe.io.Path; 14 | using buddy.Should; 15 | using ufront.test.TestUtils; 16 | using mockatoo.Mockatoo; 17 | 18 | class DocumentationControllerTest extends BuddySuite { 19 | public function new() { 20 | 21 | var haxelibSite = WebsiteTests.getTestApp(); 22 | 23 | describe("When viewing documentation", { 24 | it("Should load all pages without errors", function (done) { 25 | var pages = DocumentationController.getDocumentationPages(); 26 | var allResults = []; 27 | for ( url in pages.keys() ) { 28 | var title = pages.get( url ); 29 | var page = 30 | if ( url=="/documentation/" ) null 31 | else url.substr( "/documentation/".length ).removeTrailingSlashes(); 32 | var result = whenIVisit( url ) 33 | .onTheApp( haxelibSite ) 34 | .itShouldLoad( DocumentationController, "documentationPage", [page] ) 35 | .itShouldReturn( ViewResult, function (result) { 36 | Assert.same( TFromEngine("documentation/documentationPage"), result.templateSource ); 37 | Assert.same( TFromEngine("layout.html"), result.layoutSource ); 38 | (result.data['title']:String).should.be('$title - Haxelib Documentation'); 39 | }); 40 | allResults.push( result.result ); 41 | } 42 | 43 | Future.ofMany( allResults ).handle( function() done() ); 44 | }); 45 | }); 46 | 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /www/view/home/tagList.html: -------------------------------------------------------------------------------- 1 | 2 |

@title

3 |

@description

4 | 5 |
6 | 15 |
16 | 17 |
18 |
19 |

All Tags

20 | 25 |
26 |
27 |
28 | @for (i in 0...min(tags.length, 10)) { 29 | @{var t = tags[i];} 30 |

@escape(t.tag)

31 |
32 | @for( i in 0...3) { 33 |
34 | @for( p in taggedProjects(t.tag, i * 3, 3) ) { 35 |

36 | @p.name
37 | 38 | @p.version.name  updated @formatDate(p.version.date) 39 | 40 |

41 | } 42 |
43 | } 44 |
45 | More haxelibs tagged with "@escape(t.tag)" (@t.count) 46 |
47 | } 48 |
49 |
50 |
51 | -------------------------------------------------------------------------------- /www/view/home/search.html: -------------------------------------------------------------------------------- 1 |

@title

2 |

@description

3 | 4 |
5 | 14 |
15 | 16 | @if (projects!=null && projects.length>0) { 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | @for (p in projects) { 28 | 29 | 33 | 34 | 35 | 36 | 37 | } 38 | 39 |
ProjectDescriptionVersionDownloads
30 | @p.name 31 |
(By @@@p.author) 32 |
@p.description@p.version.name
@formatDate(p.version.date)
@p.downloads
40 | 41 | } 42 | else if (projects!=null && projects.length==0) { 43 |

No search results found.

44 | } 45 | 46 |
47 |

48 | 49 | Not found what you are looking for? 50 | Search Haxelib for "@searchTerm" using Google instead. 51 | 52 |

53 |
54 | 55 | @if (projects!=null && projects.length==0) { 56 |

 

57 | } 58 | -------------------------------------------------------------------------------- /src/haxelib/Util.hx: -------------------------------------------------------------------------------- 1 | package haxelib; 2 | 3 | #if macro 4 | import haxe.macro.Expr; 5 | 6 | using haxe.macro.Tools; 7 | #end 8 | 9 | using StringTools; 10 | 11 | class Util { 12 | macro static public function rethrow(e) { 13 | return if (haxe.macro.Context.defined("neko")) 14 | macro neko.Lib.rethrow(e); 15 | else 16 | macro throw e; 17 | } 18 | 19 | #if macro 20 | static function readVersionFromHaxelibJson() { 21 | return haxe.Json.parse(sys.io.File.getContent("haxelib.json")).version; 22 | } 23 | #end 24 | 25 | macro static public function getHaxelibVersion() { 26 | return macro $v{readVersionFromHaxelibJson()}; 27 | } 28 | 29 | macro static public function getHaxelibVersionLong() { 30 | var version:String = readVersionFromHaxelibJson(); 31 | // check if the .git folder exist 32 | // prevent getting the git info of a parent directory 33 | if (!sys.FileSystem.isDirectory(".git")) 34 | return macro $v{version}; 35 | 36 | var p; 37 | try { 38 | //get commit sha 39 | p = new sys.io.Process("git", ["rev-parse", "HEAD"]); 40 | var sha = p.stdout.readAll().toString().trim(); 41 | p.close(); 42 | 43 | //check to see if there is changes, staged or not 44 | p = new sys.io.Process("git", ["status", "--porcelain"]); 45 | var changes = p.stdout.readAll().toString().trim(); 46 | p.close(); 47 | 48 | var longVersion = version + switch(changes) { 49 | case "": 50 | ' ($sha)'; 51 | case _: 52 | ' ($sha - dirty)'; 53 | } 54 | return macro $v{longVersion}; 55 | } catch(e:Dynamic) { 56 | if (p != null) p.close(); 57 | return macro $v{version}; 58 | } 59 | } 60 | 61 | public static function pathContainsDirectory(path:String, directory:String) { 62 | return path.startsWith('$directory/') || path.contains('/$directory/'); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/website/cache/DummyCache.hx: -------------------------------------------------------------------------------- 1 | package website.cache; 2 | 3 | import tink.CoreApi; 4 | import ufront.core.Futuristic; 5 | import ufront.cache.UFCache; 6 | 7 | class DummyCacheConnection implements UFCacheConnection implements UFCacheConnectionSync { 8 | static var cache:DummyCache = new DummyCache(); 9 | 10 | public function new() {}; 11 | 12 | public function getNamespaceSync( namespace:String ):DummyCache 13 | return cache; 14 | 15 | public function getNamespace( namespace:String ):DummyCache 16 | return cache; 17 | } 18 | 19 | class DummyCache implements UFCache implements UFCacheSync { 20 | 21 | public function new() {}; 22 | 23 | public function getSync( id:String ):Outcome 24 | return Failure( ENotInCache ); 25 | 26 | public function setSync( id:String, value:T ):Outcome 27 | return Success( value ); 28 | 29 | public function getOrSetSync( id:String, ?fn:Void->T ):Outcome 30 | return Success( fn() ); 31 | 32 | public function removeSync( id:String ):Outcome { 33 | return Success(Noise); 34 | } 35 | 36 | public function clearSync():Outcome { 37 | return Success(Noise); 38 | } 39 | 40 | public function get( id:String ):Surprise 41 | return Future.sync( getSync(id) ); 42 | 43 | public function set( id:String, value:Futuristic ):Surprise 44 | return value.map( function(v:T) return Success(v) ); 45 | 46 | public function getOrSet( id:String, ?fn:Void->Futuristic ):Surprise 47 | return fn().map( function(v:T) return Success(v) ); 48 | 49 | public function clear():Surprise 50 | return Future.sync( clearSync() ); 51 | 52 | public function remove( id:String ):Surprise 53 | return Future.sync( removeSync(id) ); 54 | } -------------------------------------------------------------------------------- /test/tests/integration/TestUpgrade.hx: -------------------------------------------------------------------------------- 1 | package tests.integration; 2 | 3 | class TestUpgrade extends IntegrationTests { 4 | function test():Void { 5 | { 6 | final r = haxelib(["upgrade"]).result(); 7 | assertSuccess(r); 8 | } 9 | 10 | { 11 | final r = haxelib(["register", bar.user, bar.email, bar.fullname, bar.pw, bar.pw]).result(); 12 | assertSuccess(r); 13 | } 14 | 15 | { 16 | final r = haxelib(["submit", Path.join([IntegrationTests.projectRoot, "test/libraries/libBar.zip"]), bar.pw]).result(); 17 | assertSuccess(r); 18 | } 19 | 20 | { 21 | final r = haxelib(["search", "Bar"]).result(); 22 | assertSuccess(r); 23 | assertTrue(r.out.indexOf("Bar") >= 0); 24 | } 25 | 26 | { 27 | final r = haxelib(["install", "Bar"]).result(); 28 | assertSuccess(r); 29 | } 30 | 31 | { 32 | final r = haxelib(["list", "Bar"]).result(); 33 | assertSuccess(r); 34 | assertTrue(r.out.indexOf("[1.0.0]") >= 0); 35 | } 36 | 37 | { 38 | final r = haxelib(["upgrade"]).result(); 39 | assertSuccess(r); 40 | } 41 | 42 | { 43 | final r = haxelib(["submit", Path.join([IntegrationTests.projectRoot, "test/libraries/libBar2.zip"]), bar.pw]).result(); 44 | assertSuccess(r); 45 | } 46 | 47 | { 48 | final r = haxelib(["upgrade"], "y\n").result(); 49 | assertSuccess(r); 50 | } 51 | 52 | { 53 | final r = haxelib(["list", "Bar"]).result(); 54 | assertSuccess(r); 55 | assertTrue(r.out.indexOf("[2.0.0]") >= 0); 56 | assertTrue(r.out.indexOf("1.0.0") >= 0); 57 | } 58 | 59 | { 60 | final r = haxelib(["upgrade"]).result(); 61 | assertSuccess(r); 62 | } 63 | 64 | { 65 | final r = haxelib(["remove", "Bar"]).result(); 66 | assertSuccess(r); 67 | } 68 | 69 | { 70 | final r = haxelib(["list", "Bar"]).result(); 71 | assertSuccess(r); 72 | assertTrue(r.out.indexOf("Bar") < 0); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.7) 2 | 3 | project(Haxelib C) 4 | include(GNUInstallDirs) 5 | 6 | # put output in ${CMAKE_BINARY_DIR} 7 | 8 | set(OUTPUT_DIR ${CMAKE_BINARY_DIR}) 9 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${OUTPUT_DIR}) 10 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${OUTPUT_DIR}) 11 | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${OUTPUT_DIR}) 12 | 13 | # avoid the extra "Debug", "Release" directories 14 | # http://stackoverflow.com/questions/7747857/in-cmake-how-do-i-work-around-the-debug-and-release-directories-visual-studio-2 15 | foreach( OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES} ) 16 | string( TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG ) 17 | set( CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${OUTPUT_DIR} ) 18 | set( CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${OUTPUT_DIR} ) 19 | set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${OUTPUT_DIR} ) 20 | endforeach( OUTPUTCONFIG CMAKE_CONFIGURATION_TYPES ) 21 | 22 | # find Haxe and Neko 23 | 24 | find_program(HAXE_COMPILER haxe) 25 | 26 | find_path(NEKO_INCLUDE_DIRS neko.h) 27 | find_library(NEKO_LIBRARIES neko) 28 | find_program(NEKO neko) 29 | find_program(NEKOTOOLS nekotools) 30 | 31 | message(STATUS "HAXE_COMPILER: ${HAXE_COMPILER}") 32 | message(STATUS "NEKO_INCLUDE_DIRS: ${NEKO_INCLUDE_DIRS}") 33 | message(STATUS "NEKO_LIBRARIES: ${NEKO_LIBRARIES}") 34 | message(STATUS "NEKOTOOLS: ${NEKOTOOLS}") 35 | 36 | include_directories(${NEKO_INCLUDE_DIRS}) 37 | 38 | add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/run.n 39 | COMMAND ${HAXE_COMPILER} client.hxml 40 | VERBATIM 41 | WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} 42 | ) 43 | 44 | add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/run.c 45 | COMMAND ${NEKOTOOLS} boot -c run.n 46 | VERBATIM 47 | WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} 48 | DEPENDS ${CMAKE_SOURCE_DIR}/run.n 49 | ) 50 | 51 | add_executable(haxelib 52 | ${CMAKE_SOURCE_DIR}/run.c 53 | ) 54 | 55 | target_link_libraries(haxelib ${NEKO_LIBRARIES}) 56 | -------------------------------------------------------------------------------- /terraform/bitnami/mysql/templates/servicemonitor.yaml: -------------------------------------------------------------------------------- 1 | {{- if and .Values.metrics.enabled .Values.metrics.serviceMonitor.enabled }} 2 | apiVersion: monitoring.coreos.com/v1 3 | kind: ServiceMonitor 4 | metadata: 5 | name: {{ include "common.names.fullname" . }} 6 | {{- if .Values.metrics.serviceMonitor.namespace }} 7 | namespace: {{ .Values.metrics.serviceMonitor.namespace }} 8 | {{- else }} 9 | namespace: {{ .Release.Namespace }} 10 | {{- end }} 11 | labels: {{- include "common.labels.standard" . | nindent 4 }} 12 | {{- if .Values.commonLabels }} 13 | {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} 14 | {{- end }} 15 | {{- if .Values.metrics.serviceMonitor.additionalLabels }} 16 | {{- include "common.tplvalues.render" (dict "value" .Values.metrics.serviceMonitor.additionalLabels "context" $) | nindent 4 }} 17 | {{- end }} 18 | {{- if .Values.commonAnnotations }} 19 | annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} 20 | {{- end }} 21 | spec: 22 | endpoints: 23 | - port: metrics 24 | {{- if .Values.metrics.serviceMonitor.interval }} 25 | interval: {{ .Values.metrics.serviceMonitor.interval }} 26 | {{- end }} 27 | {{- if .Values.metrics.serviceMonitor.scrapeTimeout }} 28 | scrapeTimeout: {{ .Values.metrics.serviceMonitor.scrapeTimeout }} 29 | {{- end }} 30 | {{- if .Values.metrics.serviceMonitor.honorLabels }} 31 | honorLabels: {{ .Values.metrics.serviceMonitor.honorLabels }} 32 | {{- end }} 33 | {{- if .Values.metrics.serviceMonitor.relabellings }} 34 | metricRelabelings: {{- toYaml .Values.metrics.serviceMonitor.relabellings | nindent 6 }} 35 | {{- end }} 36 | namespaceSelector: 37 | matchNames: 38 | - {{ .Release.Namespace }} 39 | selector: 40 | matchLabels: {{- include "common.labels.matchLabels" . | nindent 6 }} 41 | app.kubernetes.io/component: metrics 42 | {{- end }} 43 | -------------------------------------------------------------------------------- /terraform/aws-rds.tf: -------------------------------------------------------------------------------- 1 | resource "aws_db_option_group" "default" { 2 | name_prefix = "mysql56-default-upgrade-" 3 | option_group_description = "Option group created for required database upgrade from RDS mysql 5.5.62 to mysql 5.6.34." 4 | engine_name = "mysql" 5 | major_engine_version = "5.6" 6 | 7 | lifecycle { 8 | create_before_destroy = true 9 | } 10 | } 11 | 12 | resource "aws_db_parameter_group" "mysql57-haxe-org" { 13 | name_prefix = "mysql57-haxe-org" 14 | family = "mysql5.7" 15 | 16 | parameter { 17 | apply_method = "pending-reboot" 18 | name = "max_allowed_packet" 19 | value = "1073741824" 20 | } 21 | parameter { 22 | apply_method = "pending-reboot" 23 | name = "max_connect_errors" 24 | value = "1000" 25 | } 26 | parameter { 27 | name = "general_log" 28 | value = "1" 29 | } 30 | parameter { 31 | name = "slow_query_log" 32 | value = "1" 33 | } 34 | parameter { 35 | name = "long_query_time" 36 | value = "1" 37 | } 38 | parameter { 39 | name = "sort_buffer_size" 40 | value = "8388608" 41 | } 42 | 43 | parameter { 44 | name = "gtid-mode" 45 | value = "ON" 46 | apply_method = "pending-reboot" 47 | } 48 | parameter { 49 | name = "enforce_gtid_consistency" 50 | value = "ON" 51 | apply_method = "pending-reboot" 52 | } 53 | parameter { 54 | name = "binlog_format" 55 | value = "ROW" 56 | } 57 | parameter { 58 | name = "binlog_row_image" 59 | value = "FULL" 60 | } 61 | parameter { 62 | name = "binlog_rows_query_log_events" 63 | value = 1 64 | } 65 | 66 | lifecycle { 67 | create_before_destroy = true 68 | } 69 | } 70 | 71 | resource "aws_db_option_group" "mysql57-haxe-org" { 72 | name_prefix = "mysql57-haxe-org" 73 | engine_name = "mysql" 74 | major_engine_version = "5.7" 75 | 76 | lifecycle { 77 | create_before_destroy = true 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /terraform/bitnami/mysql/charts/common/templates/_ingress.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | 3 | {{/* 4 | Generate backend entry that is compatible with all Kubernetes API versions. 5 | 6 | Usage: 7 | {{ include "common.ingress.backend" (dict "serviceName" "backendName" "servicePort" "backendPort" "context" $) }} 8 | 9 | Params: 10 | - serviceName - String. Name of an existing service backend 11 | - servicePort - String/Int. Port name (or number) of the service. It will be translated to different yaml depending if it is a string or an integer. 12 | - context - Dict - Required. The context for the template evaluation. 13 | */}} 14 | {{- define "common.ingress.backend" -}} 15 | {{- $apiVersion := (include "common.capabilities.ingress.apiVersion" .context) -}} 16 | {{- if or (eq $apiVersion "extensions/v1beta1") (eq $apiVersion "networking.k8s.io/v1beta1") -}} 17 | serviceName: {{ .serviceName }} 18 | servicePort: {{ .servicePort }} 19 | {{- else -}} 20 | service: 21 | name: {{ .serviceName }} 22 | port: 23 | {{- if typeIs "string" .servicePort }} 24 | name: {{ .servicePort }} 25 | {{- else if or (typeIs "int" .servicePort) (typeIs "float64" .servicePort) }} 26 | number: {{ .servicePort | int }} 27 | {{- end }} 28 | {{- end -}} 29 | {{- end -}} 30 | 31 | {{/* 32 | Print "true" if the API pathType field is supported 33 | Usage: 34 | {{ include "common.ingress.supportsPathType" . }} 35 | */}} 36 | {{- define "common.ingress.supportsPathType" -}} 37 | {{- if (semverCompare "<1.18-0" (include "common.capabilities.kubeVersion" .)) -}} 38 | {{- print "false" -}} 39 | {{- else -}} 40 | {{- print "true" -}} 41 | {{- end -}} 42 | {{- end -}} 43 | 44 | {{/* 45 | Returns true if the ingressClassname field is supported 46 | Usage: 47 | {{ include "common.ingress.supportsIngressClassname" . }} 48 | */}} 49 | {{- define "common.ingress.supportsIngressClassname" -}} 50 | {{- if semverCompare "<1.18-0" (include "common.capabilities.kubeVersion" .) -}} 51 | {{- print "false" -}} 52 | {{- else -}} 53 | {{- print "true" -}} 54 | {{- end -}} 55 | {{- end -}} 56 | -------------------------------------------------------------------------------- /test/Prepare.hx: -------------------------------------------------------------------------------- 1 | import sys.*; 2 | import sys.io.*; 3 | import haxe.io.*; 4 | 5 | class Prepare { 6 | static function zipDir(dir:String, outPath:String):Void { 7 | var entries = new List(); 8 | 9 | function add(path:String, target:String) { 10 | if (!FileSystem.exists(path)) 11 | throw 'Invalid path: $path'; 12 | 13 | if (FileSystem.isDirectory(path)) { 14 | for (item in FileSystem.readDirectory(path)) 15 | add(path + "/" + item, target == "" ? item : target + "/" + item); 16 | } else { 17 | var bytes = File.getBytes(path); 18 | var entry:haxe.zip.Entry = { 19 | fileName: target, 20 | fileSize: bytes.length, 21 | fileTime: FileSystem.stat(path).mtime, 22 | compressed: false, 23 | dataSize: 0, 24 | data: bytes, 25 | crc32: haxe.crypto.Crc32.make(bytes), 26 | } 27 | haxe.zip.Tools.compress(entry, 9); 28 | entries.add(entry); 29 | } 30 | } 31 | add(dir, ""); 32 | 33 | var out = File.write(outPath, true); 34 | var writer = new haxe.zip.Writer(out); 35 | writer.write(entries); 36 | out.close(); 37 | } 38 | 39 | static function main():Void { 40 | var system = Sys.systemName(); 41 | var cwd = Sys.getCwd(); 42 | 43 | /* 44 | Additional setup 45 | */ 46 | var gitFolder = "test/libraries/libWithGitFolder/.git"; 47 | if (!sys.FileSystem.exists(gitFolder)) { 48 | FileSystem.createDirectory(gitFolder); 49 | } 50 | 51 | /* 52 | (re)package the dummy libraries 53 | */ 54 | var libsPath = "test/libraries"; 55 | for (item in FileSystem.readDirectory(libsPath)) { 56 | var path = Path.join([libsPath, item]); 57 | if (FileSystem.isDirectory(path)) { 58 | switch system { 59 | case 'Windows': 60 | zipDir(path, 'test/libraries/${item}.zip'); 61 | case _: 62 | Sys.setCwd(path); 63 | var exitCode = Sys.command('zip', ['-r', '../${item}.zip', '.']); 64 | Sys.setCwd(cwd); 65 | if(exitCode != 0) { 66 | Sys.stderr().writeString('Failed to zip $item\n'); 67 | } 68 | } 69 | } 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /www/documentation-files/index.md: -------------------------------------------------------------------------------- 1 | # Getting Started With Haxelib 2 | 3 | Haxelib is the library manager that comes with any Haxe distribution. Connected to a central repository, it allows submitting and retrieving libraries and has multiple features beyond that. Available libraries can be found at . 4 | 5 | A basic Haxe library is a collection of `.hx` files. That is, libraries are distributed by source code by default, making it easy to inspect and modify their behavior. Each library is identified by a unique name, which is utilized when telling the Haxe Compiler which libraries to use for a given compilation. 6 | 7 | ### Using with Haxe 8 | 9 | Any installed Haxe library can be made available to the compiler through the `--library ` (or `-L `) argument. This is very similiar to the `--class-path ` argument, but expects a library name instead of a directory path. These commands are explained thoroughly in [Compiler Usage](http://haxe.org/manual/compiler-usage.html). 10 | 11 | For our exemplary usage we chose a very simple Haxe library called "random". It provides a set of static convenience methods to achieve various random effects, such as picking a random element from an array. 12 | 13 | ```haxe 14 | class Main { 15 | static public function main() { 16 | var elt = Random.fromArray([1, 2, 3]); 17 | trace(elt); 18 | } 19 | } 20 | ``` 21 | 22 | Compiling this without any `--library` argument causes an error message along the lines of `Unknown identifier : Random`. This shows that installed Haxe libraries are not available to the compiler by default unless they are explicitly added. A working command line for above program is `haxe --library random --main Main --interp`. 23 | 24 | If the compiler emits an error `Error: Library random is not installed : run 'haxelib install random'` the library has to be installed via the `haxelib` command first. As the error message suggests, this is achieved through `haxelib install random`. We will learn more about the `haxelib` command in [Using Haxelib](/documentation/using-haxelib/). 25 | -------------------------------------------------------------------------------- /test/tests/TestVersionData.hx: -------------------------------------------------------------------------------- 1 | package tests; 2 | 3 | import haxelib.SemVer; 4 | import haxelib.VersionData; 5 | import haxelib.VersionData.VersionDataHelper.extractVersion; 6 | 7 | class TestVersionData extends TestBase { 8 | function testHaxelib() { 9 | assertTrue(extractVersion("1.0.0").equals(Haxelib(SemVer.ofString("1.0.0")))); 10 | assertTrue(extractVersion("1.0.0-beta").equals(Haxelib(SemVer.ofString("1.0.0-beta")))); 11 | } 12 | 13 | function assertVersionDataEquals(expected:VersionData, actual:VersionData) { 14 | assertEquals(Std.string(expected), Std.string(actual)); 15 | } 16 | 17 | function testGit() { 18 | assertVersionDataEquals(extractVersion("git:https://some.url"), VcsInstall(VcsID.ofString("git"), { 19 | url: "https://some.url", 20 | branch: null, 21 | commit: null, 22 | tag: null, 23 | subDir: null 24 | })); 25 | 26 | assertVersionDataEquals(extractVersion("git:https://some.url#branch"), VcsInstall(VcsID.ofString("git"), { 27 | url: "https://some.url", 28 | branch: "branch", 29 | commit: null, 30 | tag: null, 31 | subDir: null 32 | })); 33 | 34 | assertVersionDataEquals(extractVersion("git:https://some.url#abcdef0"), VcsInstall(VcsID.ofString("git"), { 35 | url: "https://some.url", 36 | branch: null, 37 | commit: "abcdef0", 38 | tag: null, 39 | subDir: null 40 | })); 41 | } 42 | 43 | function testMercurial() { 44 | assertVersionDataEquals(extractVersion("hg:https://some.url"), VcsInstall(VcsID.ofString("hg"), { 45 | url: "https://some.url", 46 | branch: null, 47 | commit: null, 48 | tag: null, 49 | subDir: null 50 | })); 51 | 52 | assertVersionDataEquals(extractVersion("hg:https://some.url#branch"), VcsInstall(VcsID.ofString("hg"), { 53 | url: "https://some.url", 54 | branch: "branch", 55 | commit: null, 56 | tag: null, 57 | subDir: null 58 | })); 59 | 60 | assertVersionDataEquals(extractVersion("hg:https://some.url#abcdef0"), VcsInstall(VcsID.ofString("hg"), { 61 | url: "https://some.url", 62 | branch: null, 63 | commit: "abcdef0", 64 | tag: null, 65 | subDir: null 66 | })); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /terraform/bitnami/mysql/charts/common/templates/_names.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "common.names.name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create chart name and version as used by the chart label. 11 | */}} 12 | {{- define "common.names.chart" -}} 13 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} 14 | {{- end -}} 15 | 16 | {{/* 17 | Create a default fully qualified app name. 18 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 19 | If release name contains chart name it will be used as a full name. 20 | */}} 21 | {{- define "common.names.fullname" -}} 22 | {{- if .Values.fullnameOverride -}} 23 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} 24 | {{- else -}} 25 | {{- $name := default .Chart.Name .Values.nameOverride -}} 26 | {{- if contains $name .Release.Name -}} 27 | {{- .Release.Name | trunc 63 | trimSuffix "-" -}} 28 | {{- else -}} 29 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 30 | {{- end -}} 31 | {{- end -}} 32 | {{- end -}} 33 | 34 | {{/* 35 | Create a default fully qualified dependency name. 36 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 37 | If release name contains chart name it will be used as a full name. 38 | Usage: 39 | {{ include "common.names.dependency.fullname" (dict "chartName" "dependency-chart-name" "chartValues" .Values.dependency-chart "context" $) }} 40 | */}} 41 | {{- define "common.names.dependency.fullname" -}} 42 | {{- if .chartValues.fullnameOverride -}} 43 | {{- .chartValues.fullnameOverride | trunc 63 | trimSuffix "-" -}} 44 | {{- else -}} 45 | {{- $name := default .chartName .chartValues.nameOverride -}} 46 | {{- if contains $name .context.Release.Name -}} 47 | {{- .context.Release.Name | trunc 63 | trimSuffix "-" -}} 48 | {{- else -}} 49 | {{- printf "%s-%s" .context.Release.Name $name | trunc 63 | trimSuffix "-" -}} 50 | {{- end -}} 51 | {{- end -}} 52 | {{- end -}} 53 | -------------------------------------------------------------------------------- /terraform/do-spaces.tf: -------------------------------------------------------------------------------- 1 | resource "random_string" "do-haxelib-bucket-suffix" { 2 | length = 8 3 | lower = true 4 | upper = false 5 | special = false 6 | } 7 | 8 | resource "digitalocean_spaces_bucket" "haxelib" { 9 | name = "haxelib-${random_string.do-haxelib-bucket-suffix.result}" 10 | region = "fra1" 11 | acl = "private" 12 | versioning { 13 | enabled = true 14 | } 15 | lifecycle_rule { 16 | enabled = true 17 | prefix = "mysqldump/" 18 | expiration { 19 | days = 30 20 | } 21 | } 22 | } 23 | 24 | resource "digitalocean_cdn" "haxelib" { 25 | origin = digitalocean_spaces_bucket.haxelib.bucket_domain_name 26 | ttl = 86400 # 1 day 27 | } 28 | 29 | resource "digitalocean_spaces_bucket_policy" "haxelib" { 30 | region = digitalocean_spaces_bucket.haxelib.region 31 | bucket = digitalocean_spaces_bucket.haxelib.name 32 | policy = jsonencode({ 33 | "Version" : "2012-10-17", 34 | "Statement" : [ 35 | { 36 | "Sid" : "PublicReadGetObject", 37 | "Effect" : "Allow", 38 | "Principal" : "*", 39 | "Action" : "s3:GetObject", 40 | "Resource" : [ 41 | "arn:aws:s3:::${digitalocean_spaces_bucket.haxelib.name}/files/*" 42 | ], 43 | } 44 | ] 45 | }) 46 | } 47 | 48 | data "kubernetes_secret_v1" "haxelib-server-do-spaces" { 49 | metadata { 50 | name = "haxelib-server-do-spaces" 51 | } 52 | } 53 | 54 | resource "kubernetes_secret_v1" "rclone-haxelib-s3-to-spaces-config" { 55 | metadata { 56 | name = "rclone-haxelib-s3-to-spaces-config" 57 | } 58 | 59 | data = { 60 | "rclone.conf" = <<-EOT 61 | [s3] 62 | type = s3 63 | env_auth = true 64 | region = eu-west-1 65 | acl = private 66 | 67 | [spaces] 68 | type = s3 69 | env_auth = false 70 | access_key_id = ${data.kubernetes_secret_v1.haxelib-server-do-spaces.data.SPACES_ACCESS_KEY_ID} 71 | secret_access_key = ${data.kubernetes_secret_v1.haxelib-server-do-spaces.data.SPACES_SECRET_ACCESS_KEY} 72 | endpoint = ${digitalocean_spaces_bucket.haxelib.region}.digitaloceanspaces.com 73 | acl = private 74 | EOT 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /terraform/bitnami/mysql/templates/primary/svc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ include "mysql.primary.fullname" . }} 5 | namespace: {{ .Release.Namespace }} 6 | labels: {{- include "common.labels.standard" . | nindent 4 }} 7 | app.kubernetes.io/component: primary 8 | {{- if .Values.commonLabels }} 9 | {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} 10 | {{- end }} 11 | annotations: 12 | {{- if .Values.commonAnnotations }} 13 | {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} 14 | {{- end }} 15 | {{- if .Values.primary.service.annotations }} 16 | {{- include "common.tplvalues.render" ( dict "value" .Values.primary.service.annotations "context" $ ) | nindent 4 }} 17 | {{- end }} 18 | spec: 19 | type: {{ .Values.primary.service.type }} 20 | {{- if and (eq .Values.primary.service.type "ClusterIP") .Values.primary.service.clusterIP }} 21 | clusterIP: {{ .Values.primary.service.clusterIP }} 22 | {{- end }} 23 | {{- if and .Values.primary.service.loadBalancerIP (eq .Values.primary.service.type "LoadBalancer") }} 24 | loadBalancerIP: {{ .Values.primary.service.loadBalancerIP }} 25 | externalTrafficPolicy: {{ .Values.primary.service.externalTrafficPolicy | quote }} 26 | {{- end }} 27 | {{- if and (eq .Values.primary.service.type "LoadBalancer") .Values.primary.service.loadBalancerSourceRanges }} 28 | loadBalancerSourceRanges: {{- toYaml .Values.primary.service.loadBalancerSourceRanges | nindent 4 }} 29 | {{- end }} 30 | ports: 31 | - name: mysql 32 | port: {{ .Values.primary.service.port }} 33 | protocol: TCP 34 | targetPort: mysql 35 | {{- if (and (or (eq .Values.primary.service.type "NodePort") (eq .Values.primary.service.type "LoadBalancer")) .Values.primary.service.nodePort) }} 36 | nodePort: {{ .Values.primary.service.nodePort }} 37 | {{- else if eq .Values.primary.service.type "ClusterIP" }} 38 | nodePort: null 39 | {{- end }} 40 | selector: {{ include "common.labels.matchLabels" . | nindent 4 }} 41 | app.kubernetes.io/component: primary 42 | -------------------------------------------------------------------------------- /www/documentation-files/faq.md: -------------------------------------------------------------------------------- 1 | # FAQ 2 | 3 | 4 | ### How do I change my password? 5 | At the moment there is no way to change your password using the website or command-line. Please [create an issue](https://github.com/HaxeFoundation/haxelib/issues/new?labels=support&title=change%20password%20request&body=My%20haxelib%20user%20name%20is%20`USERNAME`.) and state your haxelib user name. 6 | 7 | --- 8 | 9 | ### How to use `haxelib` on the command line 10 | Check out [using haxelib](/documentation/using-haxelib/). 11 | 12 | --- 13 | 14 | ### Can a project have multiple contributors? 15 | Yes, just add multiple usernames in the contributors list (`"contributors": ["Juraj","Jason","Nicolas"],`) and make a new release. This will allow multiple users to submit. 16 | 17 | --- 18 | 19 | ### How do I transfer ownership of a haxelib? 20 | Haxelib only sees contributors, so you can add the new "owner" and remove the old one and make a new release. 21 | 22 | --- 23 | 24 | ### How to make a haxelib.json file? 25 | Check out [creating a haxelib package](/documentation/creating-a-haxelib-package/). 26 | 27 | --- 28 | 29 | ### How do I validate my haxelib.json file? 30 | If you want to be sure if the haxelib json file is correct, try using `haxelib submit`. This will validate if the data is correct. Press ctrl+c to terminate the actual submission. 31 | 32 | --- 33 | 34 | ### How do I get a readme/changelog/license tab on my haxelib project page? 35 | Add a "README.md", "CHANGELOG.md" and/or "LICENSE.md" markdown file in your zip file that is submitted. 36 | 37 | --- 38 | 39 | ### Why doesn't my project have stats graph? 40 | The project stats graph is only shown when the project has more than one release. 41 | 42 | --- 43 | 44 | ### How do I remove my haxelib? 45 | At the moment there is no way to remove a library from the registry, because this could break existing projects. If there serious issues like vulnerabilities or copyright infringements, please [create an issue](https://github.com/HaxeFoundation/haxelib/issues/new?labels=support) and explain. 46 | 47 | --- 48 | 49 | ### Where can I report haxelib issues? 50 | Go to . 51 | -------------------------------------------------------------------------------- /src/haxelib/SiteApi.hx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C)2005-2016 Haxe Foundation 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | package haxelib; 23 | 24 | import haxelib.MetaData; 25 | import haxelib.Data.Dependencies; 26 | import haxe.ds.*; 27 | 28 | interface SiteApi { 29 | public function search( word : String ) : List<{ id : Int, name : String }>; 30 | public function infos( project : String ) : ProjectInfos; 31 | public function getLatestVersion( project : String ) : SemVer; 32 | public function user( name : String ) : UserInfos; 33 | public function register( name : String, pass : String, mail : String, fullname : String ) : Void; 34 | public function isNewUser( name : String ) : Bool; 35 | public function checkDeveloper( prj : String, user : String ) : Void; 36 | public function checkPassword( user : String, pass : String ) : Bool; 37 | public function getSubmitId() : String; 38 | public function checkDependencies( dependencies : Dependencies) : Void; 39 | 40 | public function processSubmit( id : String, user : String, pass : String ) : String; 41 | 42 | public function postInstall( project : String, version : String):Void; 43 | } 44 | 45 | -------------------------------------------------------------------------------- /terraform/providers.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 1.0" 3 | required_providers { 4 | cloudflare = { 5 | source = "cloudflare/cloudflare" 6 | version = "~> 3.34" 7 | } 8 | aws = { 9 | source = "hashicorp/aws" 10 | version = "~> 4.17" 11 | } 12 | digitalocean = { 13 | source = "digitalocean/digitalocean" 14 | version = "~> 2.20" 15 | } 16 | github = { 17 | source = "integrations/github" 18 | version = "~> 4.26" 19 | } 20 | kubernetes = { 21 | source = "hashicorp/kubernetes" 22 | version = "~> 2.11" 23 | } 24 | helm = { 25 | source = "hashicorp/helm" 26 | version = "~> 2.5" 27 | } 28 | mysql = { 29 | source = "winebarrel/mysql" 30 | version = "~> 1.10" 31 | } 32 | random = { 33 | source = "hashicorp/random" 34 | version = "~> 3.3" 35 | } 36 | } 37 | backend "s3" { 38 | bucket = "haxe-terraform" 39 | key = "haxelib.tfstate" 40 | dynamodb_table = "haxe-terraform" 41 | # AWS_DEFAULT_REGION 42 | # AWS_ACCESS_KEY_ID 43 | # AWS_SECRET_ACCESS_KEY 44 | } 45 | } 46 | 47 | data "terraform_remote_state" "previous" { 48 | backend = "s3" 49 | 50 | config = { 51 | bucket = "haxe-terraform" 52 | key = "haxelib.tfstate" 53 | dynamodb_table = "haxe-terraform" 54 | # AWS_DEFAULT_REGION 55 | # AWS_ACCESS_KEY_ID 56 | # AWS_SECRET_ACCESS_KEY 57 | } 58 | } 59 | 60 | provider "aws" { 61 | # AWS_DEFAULT_REGION 62 | # AWS_ACCESS_KEY_ID 63 | # AWS_SECRET_ACCESS_KEY 64 | assume_role { 65 | role_arn = "arn:aws:iam::045355064871:role/haxe2021-haxelib-operator" 66 | } 67 | } 68 | 69 | data "aws_canonical_user_id" "current" {} 70 | 71 | provider "digitalocean" { 72 | # DIGITALOCEAN_ACCESS_TOKEN 73 | # SPACES_ACCESS_KEY_ID 74 | # SPACES_SECRET_ACCESS_KEY 75 | } 76 | 77 | provider "kubernetes" { 78 | config_path = "${path.module}/kubeconfig_do" 79 | } 80 | 81 | 82 | provider "helm" { 83 | kubernetes { 84 | config_path = "${path.module}/kubeconfig_do" 85 | } 86 | } 87 | 88 | provider "cloudflare" { 89 | api_token = data.aws_ssm_parameter.cloudflare_api_token.value 90 | } 91 | -------------------------------------------------------------------------------- /src/website/Util.hx: -------------------------------------------------------------------------------- 1 | package website; 2 | 3 | /** 4 | * @author Mark Knol 5 | */ 6 | class Util { 7 | private static var _MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; 8 | 9 | public static function escape(str:String) return StringTools.htmlEscape(str, true); 10 | 11 | /** 12 | Outputs to "xx-Jan 2019" (accurate=true) or "xx days/weeks ago" (accurate=false) 13 | @param date should be format "yyyy-mm-dd" 14 | **/ 15 | public static function formatDate(date:String, accurate:Bool = false) { 16 | var split = date.split("-"); 17 | var target:Date = new Date(Std.parseInt(split[0]), Std.parseInt(split[1]) - 1, Std.parseInt(split[2]), 0, 0, 0); 18 | 19 | if (!accurate) { // loose date format 20 | var minuteInMs = 1000 * 60; 21 | var hourInMs = minuteInMs * 60; 22 | var dayInMs = hourInMs * 24; 23 | 24 | var targetTime = target.getTime(); 25 | 26 | var now = Date.now().getTime(); 27 | var remainingMs = now - targetTime; 28 | 29 | var days = Math.floor(remainingMs / dayInMs); 30 | var years = Std.int(days / 356); 31 | var months = Std.int(days / 30.4167); // should be accurate enough 32 | var weeks = Std.int(days / 7); 33 | 34 | if (years == 0) { 35 | if (months < 2) { 36 | if (weeks < 1) { 37 | if (days == 0) return 'today'; 38 | if (days == 1) return '$days day ago'; 39 | return '$days days ago'; 40 | } else { 41 | if (weeks == 1) return '$weeks week ago'; 42 | else return '$weeks weeks ago'; 43 | } 44 | } else { 45 | return '$months months ago'; 46 | } 47 | } else { 48 | return years > 1 ? '$years years ago' : '$years year ago'; 49 | } 50 | } else { 51 | var month = _MONTHS[target.getMonth()]; 52 | var date = target.getDate(); 53 | var day = if (date < 10) '0$date' else '$date'; 54 | return '$day-$month ${target.getFullYear()}'; 55 | } 56 | } 57 | 58 | public static function syntaxHighlightHTML(code:String):String { 59 | var html = code; 60 | html = ~/(("|')(.+?)?\2)/g.replace(html, "$1"); 61 | html = ~/(<\\?)(.+?)(\/|\s|>)/g.replace(html, "$1$2$3"); 62 | 63 | return html; 64 | } 65 | } -------------------------------------------------------------------------------- /terraform/bitnami/mysql/templates/secondary/svc.yaml: -------------------------------------------------------------------------------- 1 | {{- if eq .Values.architecture "replication" }} 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | name: {{ include "mysql.secondary.fullname" . }} 6 | namespace: {{ .Release.Namespace }} 7 | labels: {{- include "common.labels.standard" . | nindent 4 }} 8 | app.kubernetes.io/component: secondary 9 | {{- if .Values.commonLabels }} 10 | {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} 11 | {{- end }} 12 | annotations: 13 | {{- if .Values.commonAnnotations }} 14 | {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} 15 | {{- end }} 16 | {{- if .Values.secondary.service.annotations }} 17 | {{- include "common.tplvalues.render" ( dict "value" .Values.secondary.service.annotations "context" $ ) | nindent 4 }} 18 | {{- end }} 19 | spec: 20 | type: {{ .Values.secondary.service.type }} 21 | {{- if and (eq .Values.secondary.service.type "ClusterIP") .Values.secondary.service.clusterIP }} 22 | clusterIP: {{ .Values.secondary.service.clusterIP }} 23 | {{- end }} 24 | {{- if and .Values.secondary.service.loadBalancerIP (eq .Values.secondary.service.type "LoadBalancer") }} 25 | loadBalancerIP: {{ .Values.secondary.service.loadBalancerIP }} 26 | externalTrafficPolicy: {{ .Values.secondary.service.externalTrafficPolicy | quote }} 27 | {{- end }} 28 | {{- if and (eq .Values.secondary.service.type "LoadBalancer") .Values.secondary.service.loadBalancerSourceRanges }} 29 | loadBalancerSourceRanges: {{- toYaml .Values.secondary.service.loadBalancerSourceRanges | nindent 4 }} 30 | {{- end }} 31 | ports: 32 | - name: mysql 33 | port: {{ .Values.secondary.service.port }} 34 | protocol: TCP 35 | targetPort: mysql 36 | {{- if (and (or (eq .Values.secondary.service.type "NodePort") (eq .Values.secondary.service.type "LoadBalancer")) .Values.secondary.service.nodePort) }} 37 | nodePort: {{ .Values.secondary.service.nodePort }} 38 | {{- else if eq .Values.secondary.service.type "ClusterIP" }} 39 | nodePort: null 40 | {{- end }} 41 | selector: {{ include "common.labels.matchLabels" . | nindent 4 }} 42 | app.kubernetes.io/component: secondary 43 | {{- end }} 44 | -------------------------------------------------------------------------------- /www/documentation-files/per-project-setup.md: -------------------------------------------------------------------------------- 1 | ## Per-project setup 2 | 3 | Currently haxelib has two ways to have project local setups. 4 | 5 | 1. Using `haxelib newrepo` 6 | 2. Using `haxelib install all` 7 | 8 | ### Using haxelib newrepo 9 | 10 | When using `haxelib newrepo` you can have a project-local haxelib repository. 11 | 12 | Caveats: 13 | 14 | - libraries get downloaded for each project 15 | 16 | ### Using haxelib install all 17 | 18 | Haxe allows you to define specific versions of the libraries you want to use with `--library :`. If you make sure to use this in all your hxmls, then `haxelib install all --always` (the `--always` avoiding you being prompted for confirmation) will be able to ensure the libraries your project needs are available in the necessary versions. If in fact you run this in a checkout hook, your get to track your dependencies in your git repo (some other VCSs should allow for a similar setup), allowing you to have a well defined and replicable setup for any state (commit/branch/etc.). 19 | 20 | Disadvantages: 21 | 22 | - the approach requires you to define all dependencies with specific versions and then running `haxelib install all` to grab them 23 | - with this approach, any other project that does not have specific versions defined may be affected, as under some circumstances `haxelib install all` may set the global "current" version of the libraries (to be fixed) 24 | 25 | Advantages: 26 | 27 | - as pointed out above, this approach allows defining a *versionable* and *replicable* state. 28 | - you don't have to download libraries for each project, which does make a difference for heavy weights like openfl and hxcpp 29 | 30 | #### Using haxelib with git versions 31 | 32 | You can specify git versions with `--library libname:git:https://github.com/user/repo#branch` branch can be a branch or a specific commit SHA. 33 | As alternative, you might use git submodules instead, they also provide an adequate way of definining a *versionable* and *replicable* state. 34 | 35 | ### Combining both approaches 36 | 37 | You can of course combine both approaches, giving you the isolation provided by the first one, and the replicability provided by the second one. 38 | 39 | ### Future solutions 40 | 41 | A solution that combines the strengths of both approaches is in the making. Stay tuned. 42 | -------------------------------------------------------------------------------- /www/.htaccess: -------------------------------------------------------------------------------- 1 | # Set index.n to come before index.php 2 | 3 | DirectoryIndex index.n index.php index.html 4 | 5 | RewriteEngine On 6 | 7 | # Redirect http to https 8 | RewriteBase / 9 | RewriteCond %{HTTPS} !=on 10 | RewriteCond %{HTTP:X-Forwarded-Proto} !https 11 | RewriteCond %{HTTP_HOST} !^localhost(:[0-9]+)?$ 12 | RewriteCond %{HTTP_HOST} !^haxelib(:[0-9]+)?$ 13 | RewriteCond %{HTTP_HOST} !^[0-9]+.[0-9]+.[0-9]+.[0-9]+(:[0-9]+)?$ 14 | RewriteCond %{REQUEST_URI} !index\.n/?$ 15 | RewriteCond %{REQUEST_URI} !^/api/ 16 | RewriteCond %{REQUEST_URI} !^/files/ 17 | RewriteCond %{REQUEST_URI} !^/legacy/ 18 | RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=302,L,QSA] 19 | 20 | # /files are stored in S3 21 | 22 | # for recent versions of haxelib client, which send UA, use https, and support redirection 23 | RewriteBase / 24 | RewriteCond %{HTTPS} =on [OR] 25 | RewriteCond %{HTTP:X-Forwarded-Proto} =https 26 | RewriteCond %{ENV:HAXELIB_CDN} !^$ 27 | RewriteCond %{HTTP_USER_AGENT} !^$ 28 | RewriteRule "^files/(.*)$" "https://%{ENV:HAXELIB_CDN}/files/$1" [L,R=302] 29 | 30 | # for older versions of haxelib client 31 | RewriteBase / 32 | RewriteCond %{HTTPS} !on 33 | RewriteCond %{HTTP:X-Forwarded-Proto} !https 34 | RewriteCond %{REQUEST_FILENAME} !-f 35 | RewriteCond %{ENV:HAXELIB_CDN} !^$ 36 | RewriteRule "^files/(.*)$" "https://%{ENV:HAXELIB_CDN}/files/$1" [P] 37 | 38 | # Rewrite rules to send Haxe remoting calls on "/" to "haxelib1/". If it matches, that's [L], the last rule - go their immediately. 39 | 40 | RewriteBase / 41 | RewriteCond %{HTTP:X-Haxe-Remoting}: 1 42 | RewriteRule ^index\.n$ legacy/index.n [L] 43 | 44 | # Enable rewrite for the new site's pages, only if the file or dir doesn't exist 45 | 46 | RewriteBase / 47 | RewriteCond %{REQUEST_FILENAME} !-f 48 | RewriteCond %{REQUEST_FILENAME} !-d 49 | RewriteCond %{REQUEST_URI} !^/httpd-status$ 50 | RewriteRule ^(.*)$ index.n/$1 [L] 51 | 52 | # for all text/html 53 | # max-age: 60 seconds, stale-while-revalidate: 7 days 54 | Header append Cache-Control "public, max-age=60, stale-while-revalidate=604800" "expr=%{REQUEST_METHOD} == 'GET' && %{REQUEST_STATUS} == 200 && %{CONTENT_TYPE} == 'text/html; charset=utf-8'" 55 | 56 | # Get our stuff gzipped 57 | 58 | SetOutputFilter DEFLATE 59 | AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript -------------------------------------------------------------------------------- /terraform/bitnami/mysql/charts/common/templates/_utils.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Print instructions to get a secret value. 4 | Usage: 5 | {{ include "common.utils.secret.getvalue" (dict "secret" "secret-name" "field" "secret-value-field" "context" $) }} 6 | */}} 7 | {{- define "common.utils.secret.getvalue" -}} 8 | {{- $varname := include "common.utils.fieldToEnvVar" . -}} 9 | export {{ $varname }}=$(kubectl get secret --namespace {{ .context.Release.Namespace | quote }} {{ .secret }} -o jsonpath="{.data.{{ .field }}}" | base64 --decode) 10 | {{- end -}} 11 | 12 | {{/* 13 | Build env var name given a field 14 | Usage: 15 | {{ include "common.utils.fieldToEnvVar" dict "field" "my-password" }} 16 | */}} 17 | {{- define "common.utils.fieldToEnvVar" -}} 18 | {{- $fieldNameSplit := splitList "-" .field -}} 19 | {{- $upperCaseFieldNameSplit := list -}} 20 | 21 | {{- range $fieldNameSplit -}} 22 | {{- $upperCaseFieldNameSplit = append $upperCaseFieldNameSplit ( upper . ) -}} 23 | {{- end -}} 24 | 25 | {{ join "_" $upperCaseFieldNameSplit }} 26 | {{- end -}} 27 | 28 | {{/* 29 | Gets a value from .Values given 30 | Usage: 31 | {{ include "common.utils.getValueFromKey" (dict "key" "path.to.key" "context" $) }} 32 | */}} 33 | {{- define "common.utils.getValueFromKey" -}} 34 | {{- $splitKey := splitList "." .key -}} 35 | {{- $value := "" -}} 36 | {{- $latestObj := $.context.Values -}} 37 | {{- range $splitKey -}} 38 | {{- if not $latestObj -}} 39 | {{- printf "please review the entire path of '%s' exists in values" $.key | fail -}} 40 | {{- end -}} 41 | {{- $value = ( index $latestObj . ) -}} 42 | {{- $latestObj = $value -}} 43 | {{- end -}} 44 | {{- printf "%v" (default "" $value) -}} 45 | {{- end -}} 46 | 47 | {{/* 48 | Returns first .Values key with a defined value or first of the list if all non-defined 49 | Usage: 50 | {{ include "common.utils.getKeyFromList" (dict "keys" (list "path.to.key1" "path.to.key2") "context" $) }} 51 | */}} 52 | {{- define "common.utils.getKeyFromList" -}} 53 | {{- $key := first .keys -}} 54 | {{- $reverseKeys := reverse .keys }} 55 | {{- range $reverseKeys }} 56 | {{- $value := include "common.utils.getValueFromKey" (dict "key" . "context" $.context ) }} 57 | {{- if $value -}} 58 | {{- $key = . }} 59 | {{- end -}} 60 | {{- end -}} 61 | {{- printf "%s" $key -}} 62 | {{- end -}} 63 | -------------------------------------------------------------------------------- /terraform/kubeconfig_do: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | clusters: 3 | - cluster: 4 | certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lDQm5Vd0RRWUpLb1pJaHZjTkFRRUxCUUF3TXpFVk1CTUdBMVVFQ2hNTVJHbG4KYVhSaGJFOWpaV0Z1TVJvd0dBWURWUVFERXhGck9ITmhZWE1nUTJ4MWMzUmxjaUJEUVRBZUZ3MHlNakF4TVRBdwpOekl5TVRGYUZ3MDBNakF4TVRBd056SXlNVEZhTURNeEZUQVRCZ05WQkFvVERFUnBaMmwwWVd4UFkyVmhiakVhCk1CZ0dBMVVFQXhNUmF6aHpZV0Z6SUVOc2RYTjBaWElnUTBFd2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUIKRHdBd2dnRUtBb0lCQVFEUWRYM29Mdnc3Y1RoSEczQ2VYbGFxTVV2MmVhS3RkQ1V4U3JhbFJEd1B3Ui9KQ2F3dAp3OS9MYVRJbTViY2czbmMzdzAzRWxNdlVONUdvYlo4R0RLZi9NNW9jM2t6MmdiUzhpb2ZCd0RNYUtCeTIvaXBHCnhHamR0bkdRdU4zdVZGNDZPL0tnanIxTkJ3OUNZOG9ab2lEQklYUi91UzJ5OVlnVHZJcURCOWxWaWtMZ3FMK1MKMlYzV0Q1eGFhNXhLZkVRd2NWKzg2OU5rNVlxR2ZjTFgzUUNtYUN0UGhJTzJVdlFIVzM1OFd5ellUc2hVeHcxVgpwUThFWU1UMnpSRURRZHJhQ256Y2NscUhzZ2R3SzluM0lzTkN5Rzg0UUE1UE5nRzJ5QTJTOWswZVlTUElnZTVvCmduZGF4eEpjeU9nNzFaMytNK1dxVEx5YUFCTHNkOTllb3NUcEFnTUJBQUdqUlRCRE1BNEdBMVVkRHdFQi93UUUKQXdJQmhqQVNCZ05WSFJNQkFmOEVDREFHQVFIL0FnRUFNQjBHQTFVZERnUVdCQlIvNDcyd082QjhEZ1hoQUVvNApQbjVDblYyTEZEQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFYSGZ5OGp5U2lmSjhUdk1TSHlVblMrVmpoV2NmCnk0U2RvSVNpZEFRNVBzbTZYKzhtWG9KaWxqZ0VYTjNBcjNSb2V2VEVLVWhJeXd4UXBMVUhwUGk2R21oUVJoY1MKNDAxK01pTUlyMkRlTDNGTkZHVkwyaGFSMHZEejhHaGVST05zVXEvLzh6RzRWRWtHZDBQdERYcjRZV3dvNWpVSApsVUVlNkFPRjIvd0gwVTJOaGVCS3JwVWFBMnIzRG05UVNQeXR1V3pOVlA0czY4NnkxVm9PNGxrdExwYnA0Q3p4CjgwSnpmTm1UZ0pzM1d1VXEvcENvR3lKY0p3QUQ1US9YbUMyWjRCMzgwMUFXK1VqcURlS1NMdlRVWTJaR0FuclUKQ2lkT3p2MGgwSU51amFmRmYydkxNRjRUcXBUYWtiMjlzQW5ITXFnekE0VlBneGlTaE5ISmwremk5Zz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K 5 | server: https://40847d1d-9252-4ac9-87af-c3d2d2eba7e9.k8s.ondigitalocean.com 6 | name: do-lon1-haxe2021 7 | contexts: 8 | - context: 9 | cluster: do-lon1-haxe2021 10 | user: do-lon1-haxe2021-admin 11 | name: do-lon1-haxe2021 12 | current-context: do-lon1-haxe2021 13 | kind: Config 14 | preferences: {} 15 | users: 16 | - name: do-lon1-haxe2021-admin 17 | user: 18 | exec: 19 | apiVersion: client.authentication.k8s.io/v1beta1 20 | args: 21 | - kubernetes 22 | - cluster 23 | - kubeconfig 24 | - exec-credential 25 | - --version=v1beta1 26 | - --context=default 27 | - 40847d1d-9252-4ac9-87af-c3d2d2eba7e9 28 | command: doctl 29 | env: null 30 | provideClusterInfo: false 31 | -------------------------------------------------------------------------------- /apache2.conf: -------------------------------------------------------------------------------- 1 | # see http://sources.debian.net/src/apache2/2.4.10-1/debian/config-dir/apache2.conf 2 | 3 | Mutex file:/var/lock/apache2 default 4 | PidFile /var/run/apache2/apache2.pid 5 | Timeout 300 6 | KeepAlive On 7 | MaxKeepAliveRequests 100 8 | KeepAliveTimeout 5 9 | User www-data 10 | Group www-data 11 | HostnameLookups Off 12 | ErrorLog /proc/self/fd/2 13 | LogLevel warn 14 | 15 | IncludeOptional mods-enabled/*.load 16 | IncludeOptional mods-enabled/*.conf 17 | 18 | # ports.conf 19 | Listen 80 20 | 21 | Listen 443 22 | SSLProxyEngine On 23 | 24 | 25 | Listen 443 26 | 27 | 28 | 29 | Options FollowSymLinks 30 | AllowOverride None 31 | Require all denied 32 | 33 | 34 | 35 | AllowOverride All 36 | Require all granted 37 | 38 | 39 | DocumentRoot /var/www/html 40 | 41 | AccessFileName .htaccess 42 | 43 | Require all denied 44 | 45 | 46 | LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined 47 | LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined 48 | LogFormat "%h %l %u %t \"%r\" %>s %O" common 49 | LogFormat "%{Referer}i -> %U" referer 50 | LogFormat "%{User-agent}i" agent 51 | 52 | CustomLog /proc/self/fd/1 combined 53 | 54 | 55 | # Allow server status reports generated by mod_status 56 | 57 | SetHandler server-status 58 | 59 | 60 | # Keep track of extended status information for each request 61 | ExtendedStatus On 62 | 63 | 64 | # Show Proxy LoadBalancer status in mod_status 65 | ProxyStatus On 66 | 67 | 68 | 69 | # Multiple DirectoryIndex directives within the same context will add 70 | # to the list of resources to look for rather than replace 71 | # https://httpd.apache.org/docs/current/mod/mod_dir.html#directoryindex 72 | DirectoryIndex disabled 73 | DirectoryIndex index.html 74 | 75 | IncludeOptional conf-enabled/*.conf 76 | IncludeOptional sites-enabled/*.conf 77 | 78 | # https://httpd.apache.org/docs/2.4/mod/prefork.html 79 | 80 | StartServers 2 81 | MinSpareServers 2 82 | MaxSpareServers 4 83 | MaxRequestWorkers 10 84 | MaxConnectionsPerChild 8 85 | 86 | -------------------------------------------------------------------------------- /src/website/api/UserApi.hx: -------------------------------------------------------------------------------- 1 | package website.api; 2 | 3 | import haxe.crypto.Md5; 4 | import website.model.SiteDb; 5 | import ufront.web.HttpError; 6 | import ufront.api.UFApi; 7 | import haxe.Utf8; 8 | using tink.CoreApi; 9 | using CleverSort; 10 | using Lambda; 11 | 12 | class UserApi extends UFApi { 13 | @inject("documentationPath") public var docPath:String; 14 | 15 | /** 16 | Given a username, return that user object and a 17 | **/ 18 | public function getUserProfile( username:String ):Outcome>,Error> { 19 | try { 20 | var user = User.manager.select( $name==username ); 21 | if ( user==null ) 22 | return Failure( HttpError.pageNotFound() ); 23 | 24 | var projectJoins = Developer.manager.search( $user==user.id ); 25 | var projects = [for (j in projectJoins) j.projectObj]; 26 | projects.cleverSort( -_.downloads ); 27 | 28 | return Success( new Pair(user, projects) ); 29 | } 30 | catch ( e:Dynamic ) return Failure( Error.withData('Failed to fetch user profile for $username', e) ); 31 | } 32 | 33 | /** 34 | **/ 35 | public function getUserList():Outcome, totalDownloads:Int }>,Error> { 36 | try { 37 | // Fetch all the objects we are going to be using: 38 | var allUsers = User.manager.all(); 39 | var allProjects = Project.manager.all(); 40 | var joins = Developer.manager.all(); 41 | 42 | // Collate them into a map, tally the downloads 43 | var map = new Map(); 44 | for ( u in allUsers ) { 45 | var hash = Md5.encode( u.email ); 46 | var obj = { user:u, emailHash:hash, projects:[], totalDownloads:0 }; 47 | map.set( u.id, obj ); 48 | } 49 | for ( j in joins ) { 50 | var obj = map[j.userObj.id]; 51 | var project = j.projectObj; 52 | if ( project==null ) throw 'How is it null? ${j}'; 53 | obj.projects.push( project ); 54 | obj.totalDownloads += project.downloads; 55 | } 56 | 57 | // Sort the projects on each user, and then the users 58 | var arr = []; 59 | for ( obj in map ) { 60 | obj.projects.cleverSort( -_.downloads, _.name ); 61 | arr.push( obj ); 62 | } 63 | arr.cleverSort( -_.totalDownloads, _.user.fullname ); 64 | 65 | return Success( arr ); 66 | } 67 | catch ( e:Dynamic ) return Failure( Error.withData('Failed to get list of all users',e) ); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /test/tests/integration/TestOwner.hx: -------------------------------------------------------------------------------- 1 | package tests.integration; 2 | 3 | class TestOwner extends IntegrationTests { 4 | function test():Void { 5 | { 6 | final r = haxelib(["register", deepAuthor.user, deepAuthor.email, deepAuthor.fullname, deepAuthor.pw, deepAuthor.pw]).result(); 7 | assertSuccess(r); 8 | } 9 | { 10 | final r = haxelib(["register", anotherGuy.user, anotherGuy.email, anotherGuy.fullname, anotherGuy.pw, anotherGuy.pw]).result(); 11 | assertSuccess(r); 12 | } 13 | { 14 | final r = haxelib(["register", foo.user, foo.email, foo.fullname, foo.pw, foo.pw]).result(); 15 | assertSuccess(r); 16 | } 17 | 18 | 19 | /* 20 | Only the owner can submit the first version. 21 | */ 22 | 23 | { 24 | final r = haxelib(["submit", Path.join([IntegrationTests.projectRoot, "test/libraries/libDeep.zip"]), anotherGuy.user, anotherGuy.pw]).result(); 25 | assertFail(r); 26 | } 27 | 28 | { 29 | final r = haxelib(["submit", Path.join([IntegrationTests.projectRoot, "test/libraries/libDeep.zip"]), deepAuthor.user, deepAuthor.pw]).result(); 30 | assertSuccess(r); 31 | } 32 | 33 | /* 34 | Only the owner can change ownership. 35 | */ 36 | 37 | { 38 | final r = haxelib(["submit", Path.join([IntegrationTests.projectRoot, "test/libraries/libDeep2.zip"]), anotherGuy.user, anotherGuy.pw]).result(); 39 | assertFail(r); 40 | } 41 | 42 | { 43 | final r = haxelib(["submit", Path.join([IntegrationTests.projectRoot, "test/libraries/libDeep2.zip"]), deepAuthor.user, deepAuthor.pw]).result(); 44 | assertSuccess(r); 45 | } 46 | 47 | /* 48 | Only the owner can change contributors. 49 | */ 50 | 51 | { 52 | final r = haxelib(["submit", Path.join([IntegrationTests.projectRoot, "test/libraries/libDeep3.zip"]), foo.user, foo.pw]).result(); 53 | assertFail(r); 54 | } 55 | 56 | { 57 | final r = haxelib(["submit", Path.join([IntegrationTests.projectRoot, "test/libraries/libDeep3.zip"]), anotherGuy.user, anotherGuy.pw]).result(); 58 | assertSuccess(r); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/haxelib/server/Paths.hx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C)2005-2016 Haxe Foundation 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | package haxelib.server; 23 | 24 | #if neko 25 | import neko.Web; 26 | #end 27 | import haxe.io.*; 28 | 29 | /** 30 | Absolute path. 31 | */ 32 | typedef AbsPath = String; 33 | 34 | /** 35 | Relative path. 36 | */ 37 | typedef RelPath = String; 38 | 39 | class Paths { 40 | static public var CWD(default, never):AbsPath = 41 | #if neko 42 | #if haxelib_api 43 | Path.normalize(Path.join([Web.getCwd(), "..", ".."])); 44 | #elseif haxelib_legacy 45 | Path.normalize(Path.join([Web.getCwd(), ".."])); 46 | #else 47 | Web.getCwd(); 48 | #end 49 | #else 50 | Sys.getCwd(); 51 | #end 52 | static public var DB_CONFIG_NAME(default, never):RelPath = "dbconfig.json"; 53 | static public var DB_CONFIG(default, never):AbsPath = Path.join([CWD, DB_CONFIG_NAME]); 54 | static public var DB_FILE_NAME(default, never):RelPath = "haxelib.db"; 55 | static public var DB_FILE(default, never):AbsPath = Path.join([CWD, DB_FILE_NAME]); 56 | 57 | static public var TMP_DIR_NAME(default, never):RelPath = "tmp"; 58 | static public var TMP_DIR(default, never):AbsPath = Path.join([CWD, TMP_DIR_NAME]); 59 | static public var REP_DIR_NAME(default, never):RelPath = Data.REPOSITORY; 60 | } -------------------------------------------------------------------------------- /test/HaxelibTests.hx: -------------------------------------------------------------------------------- 1 | import haxe.unit.TestRunner; 2 | import sys.FileSystem; 3 | import sys.io.Process; 4 | 5 | import tests.*; 6 | 7 | using StringTools; 8 | 9 | class HaxelibTests { 10 | public static function runCommand(cmd:String, args:Array):Void { 11 | Sys.println('Command: $cmd $args'); 12 | 13 | final exitCode = Sys.command(cmd, args); 14 | 15 | Sys.println('Command exited with $exitCode: $cmd $args'); 16 | 17 | if(exitCode != 0) 18 | Sys.exit(exitCode); 19 | } 20 | 21 | static function cmdSucceed(cmd:String, ?args:Array):Bool { 22 | final p = try { 23 | new Process(cmd, args); 24 | } catch(e:Dynamic) { 25 | return false; 26 | } 27 | final exitCode = p.exitCode(); 28 | p.close(); 29 | return exitCode == 0; 30 | } 31 | 32 | static public function deleteDirectory(dir:String) { 33 | if (!FileSystem.exists(dir)) return; 34 | final exitCode = switch (Sys.systemName()) { 35 | case "Windows": 36 | Sys.command("rmdir", ["/S", "/Q", StringTools.replace(FileSystem.fullPath(dir), "/", "\\")]); 37 | case _: 38 | Sys.command("rm", ["-rf", dir]); 39 | } 40 | if (exitCode != 0) { 41 | throw 'unable to delete $dir'; 42 | } 43 | } 44 | 45 | static function main():Void { 46 | final r = new TestRunner(); 47 | 48 | final isCI = Sys.getEnv("CI") != null; 49 | 50 | if (isCI || cmdSucceed("hg", ["version"])) { 51 | // Hg impl. suports tags & revs. Here "b022617bccfb" is a first revision at that repo: 52 | TestHg.init(); 53 | r.add(new TestHg()); 54 | } else { 55 | Sys.println("hg not found."); 56 | } 57 | if (isCI || cmdSucceed("git", ["version"])) { 58 | // Git impl. suports only tags. Here "0.9.2" is a first revision too ("initial import"): 59 | TestGit.init(); 60 | r.add(new TestGit()); 61 | } else { 62 | Sys.println("git not found."); 63 | } 64 | 65 | r.add(new TestVcsNotFound()); 66 | r.add(new TestSemVer()); 67 | r.add(new TestData()); 68 | r.add(new TestVersionData()); 69 | r.add(new TestRemoveSymlinks()); 70 | r.add(new TestRemoveSymlinksBroken()); 71 | r.add(new TestInstaller()); 72 | r.add(new TestLibFlagData()); 73 | r.add(new TestRepoManager()); 74 | r.add(new TestRepoReformatter()); 75 | r.add(new TestRepoReformatterOnLocal()); 76 | r.add(new TestGlobalScope()); 77 | 78 | r.add(new TestArgs()); 79 | 80 | final success = r.run(); 81 | 82 | TestScope.cleanUpRepo(); 83 | 84 | Sys.exit(success ? 0 : 1); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /www/img/haxe-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 10 | 12 | 14 | 16 | 18 | 20 | 22 | 24 | 26 | 28 | 30 | 32 | 34 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /www/view/project/versionList.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |

@project

4 |

@info.desc
@info.website

5 |
6 | 7 | 11 | 12 | @if (allVersions.length > 1) { 13 |
14 | 15 | 16 | 58 | } 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | @for (v in allVersions) { 71 | 72 | 76 | 77 | 78 | 79 | 80 | } 81 | 82 |
VersionRelease NotesInstallDownloads
73 | @v.name 74 |
@formatDate(v.date) 75 |
@escape(v.comments)haxelib install @project @v.name@v.downloads
83 | -------------------------------------------------------------------------------- /src/haxelib/api/LibraryData.hx: -------------------------------------------------------------------------------- 1 | package haxelib.api; 2 | 3 | import haxe.DynamicAccess; 4 | 5 | import haxelib.VersionData; 6 | 7 | /** Exception thrown upon errors regarding library data, such as invalid versions. **/ 8 | class LibraryDataException extends haxe.Exception {} 9 | 10 | /** 11 | Library version, which can be used in commands. 12 | 13 | This type of library version has a physical folder in the project root directory 14 | (i.e. it is not a dev version) 15 | **/ 16 | abstract Version(String) to String from SemVer from VcsID { 17 | inline function new(s:String) { 18 | this = s; 19 | } 20 | 21 | public static function ofString(s:String):Version { 22 | if (!isValid(s)) 23 | throw new LibraryDataException('`$s` is not a valid library version'); 24 | return new Version(s); 25 | } 26 | 27 | static function ofStringUnsafe(s:String):Version { 28 | return new Version(s); 29 | } 30 | 31 | /** Returns whether `s` constitues a valid library version. **/ 32 | public static function isValid(s:String):Bool { 33 | return VcsID.isValid(s) || SemVer.isValid(s); 34 | } 35 | } 36 | 37 | /** A library version which can only be `dev`. **/ 38 | @:noDoc 39 | enum abstract Dev(String) to String { 40 | final Dev = "dev"; 41 | } 42 | 43 | /** Like `Version`, but also has the possible value of `dev`. **/ 44 | abstract VersionOrDev(String) from VcsID from SemVer from Version from Dev to String {} 45 | 46 | /** Interface which all types of library data implement. **/ 47 | interface ILibraryData { 48 | final version:VersionOrDev; 49 | final dependencies:Array; 50 | } 51 | 52 | /** Data for a library installed from the haxelib server. **/ 53 | @:structInit 54 | class LibraryData implements ILibraryData { 55 | public final version:SemVer; 56 | public final dependencies:Array; 57 | } 58 | 59 | /** Data for a library located in a local development path. **/ 60 | @:structInit 61 | class DevLibraryData implements ILibraryData { 62 | public final version:Dev; 63 | public final dependencies:Array; 64 | public final path:String; 65 | } 66 | 67 | /** Data for a library installed via vcs. **/ 68 | @:structInit 69 | class VcsLibraryData implements ILibraryData { 70 | public final version:VcsID; 71 | public final dependencies:Array; 72 | /** Reproducible vcs information **/ 73 | public final vcs:VcsData; 74 | } 75 | 76 | private final hashRegex = ~/^([a-f0-9]{7,40})$/; 77 | function isCommitHash(str:String) 78 | return hashRegex.match(str); 79 | 80 | typedef LockFormat = DynamicAccess; 81 | -------------------------------------------------------------------------------- /test/tests/TestSemVer.hx: -------------------------------------------------------------------------------- 1 | package tests; 2 | 3 | import haxelib.SemVer; 4 | 5 | class TestSemVer extends TestBase { 6 | static function make(major, minor, patch, ?preview, ?previewNum):SemVer { 7 | return { 8 | major : major, 9 | minor : minor, 10 | patch : patch, 11 | preview : preview, 12 | previewNum : previewNum 13 | }; 14 | } 15 | 16 | public function testToString() { 17 | assertEquals( "0.1.2", make(0,1,2) ); 18 | 19 | // Release Tags 20 | assertEquals( "0.1.2-alpha", make(0,1,2,ALPHA) ); 21 | assertEquals( "0.1.2-beta", make(0,1,2,BETA) ); 22 | assertEquals( "0.1.2-rc", make(0,1,2,RC) ); 23 | 24 | // Release Tag Versions 25 | assertEquals( "0.1.2-alpha.0", make(0,1,2,ALPHA,0) ); 26 | assertEquals( "0.1.2-beta.0", make(0,1,2,BETA,0) ); 27 | assertEquals( "0.1.2-rc.0", make(0,1,2,RC,0) ); 28 | 29 | // Weird input 30 | assertEquals( "0.1.2", make(0,1,2,null,0) ); 31 | 32 | // Multiple characters 33 | assertEquals( "100.200.300-rc.400", make(100,200,300,RC,400) ); 34 | } 35 | 36 | public function testOfString() { 37 | // Normal 38 | assertEquals( "0.1.2", (SemVer.ofString("0.1.2").data : SemVer)); 39 | assertEquals( "100.50.200", (SemVer.ofString("100.50.200").data : SemVer)); 40 | 41 | // Release tags 42 | assertEquals( "0.1.2-alpha", (SemVer.ofString("0.1.2-ALPHA").data : SemVer)); 43 | assertEquals( "0.1.2-alpha", (SemVer.ofString("0.1.2-alpha").data : SemVer)); 44 | assertEquals( "0.1.2-beta", (SemVer.ofString("0.1.2-beta").data : SemVer)); 45 | assertEquals( "0.1.2-rc", (SemVer.ofString("0.1.2-rc").data : SemVer)); 46 | assertEquals( "0.1.2-rc.1", (SemVer.ofString("0.1.2-rc.1").data : SemVer)); 47 | } 48 | 49 | public function testOfStringInvalid() { 50 | assertEquals( "invalid", parseInvalid(null) ); 51 | assertEquals( "invalid", parseInvalid("") ); 52 | assertEquals( "invalid", parseInvalid("1") ); 53 | assertEquals( "invalid", parseInvalid("1.1") ); 54 | assertEquals( "invalid", parseInvalid("1.2.a") ); 55 | assertEquals( "invalid", parseInvalid("a.b.c") ); 56 | assertEquals( "invalid", parseInvalid("1.2.3-") ); 57 | assertEquals( "invalid", parseInvalid("1.2.3-rc.") ); 58 | assertEquals( "invalid", parseInvalid("1.2.3--rc.1") ); 59 | assertEquals( "invalid", parseInvalid("1.2.3-othertag") ); 60 | assertEquals( "invalid", parseInvalid("1.2.3-othertag.1") ); 61 | assertEquals( "invalid", parseInvalid("10.050.02")); 62 | assertEquals( "invalid", parseInvalid("10.50.2-rc.01")); 63 | } 64 | 65 | function parseInvalid( str:String ):String { 66 | return try { 67 | SemVer.ofString(str); 68 | } catch (e:String) { 69 | "invalid"; 70 | } 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /terraform/bitnami/mysql/charts/common/templates/validations/_validations.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Validate values must not be empty. 4 | 5 | Usage: 6 | {{- $validateValueConf00 := (dict "valueKey" "path.to.value" "secret" "secretName" "field" "password-00") -}} 7 | {{- $validateValueConf01 := (dict "valueKey" "path.to.value" "secret" "secretName" "field" "password-01") -}} 8 | {{ include "common.validations.values.empty" (dict "required" (list $validateValueConf00 $validateValueConf01) "context" $) }} 9 | 10 | Validate value params: 11 | - valueKey - String - Required. The path to the validating value in the values.yaml, e.g: "mysql.password" 12 | - secret - String - Optional. Name of the secret where the validating value is generated/stored, e.g: "mysql-passwords-secret" 13 | - field - String - Optional. Name of the field in the secret data, e.g: "mysql-password" 14 | */}} 15 | {{- define "common.validations.values.multiple.empty" -}} 16 | {{- range .required -}} 17 | {{- include "common.validations.values.single.empty" (dict "valueKey" .valueKey "secret" .secret "field" .field "context" $.context) -}} 18 | {{- end -}} 19 | {{- end -}} 20 | 21 | {{/* 22 | Validate a value must not be empty. 23 | 24 | Usage: 25 | {{ include "common.validations.value.empty" (dict "valueKey" "mariadb.password" "secret" "secretName" "field" "my-password" "subchart" "subchart" "context" $) }} 26 | 27 | Validate value params: 28 | - valueKey - String - Required. The path to the validating value in the values.yaml, e.g: "mysql.password" 29 | - secret - String - Optional. Name of the secret where the validating value is generated/stored, e.g: "mysql-passwords-secret" 30 | - field - String - Optional. Name of the field in the secret data, e.g: "mysql-password" 31 | - subchart - String - Optional - Name of the subchart that the validated password is part of. 32 | */}} 33 | {{- define "common.validations.values.single.empty" -}} 34 | {{- $value := include "common.utils.getValueFromKey" (dict "key" .valueKey "context" .context) }} 35 | {{- $subchart := ternary "" (printf "%s." .subchart) (empty .subchart) }} 36 | 37 | {{- if not $value -}} 38 | {{- $varname := "my-value" -}} 39 | {{- $getCurrentValue := "" -}} 40 | {{- if and .secret .field -}} 41 | {{- $varname = include "common.utils.fieldToEnvVar" . -}} 42 | {{- $getCurrentValue = printf " To get the current value:\n\n %s\n" (include "common.utils.secret.getvalue" .) -}} 43 | {{- end -}} 44 | {{- printf "\n '%s' must not be empty, please add '--set %s%s=$%s' to the command.%s" .valueKey $subchart .valueKey $varname $getCurrentValue -}} 45 | {{- end -}} 46 | {{- end -}} 47 | -------------------------------------------------------------------------------- /src/haxelib/ProjectName.hx: -------------------------------------------------------------------------------- 1 | package haxelib; 2 | 3 | import haxe.Json; 4 | import haxe.ds.Option; 5 | 6 | import haxelib.Validator; 7 | 8 | using StringTools; 9 | 10 | /** A valid project name string. **/ 11 | abstract ProjectName(String) to String { 12 | static var RESERVED_NAMES = ["haxe", "all"]; 13 | static var RESERVED_EXTENSIONS = ['.zip', '.hxml']; 14 | 15 | inline function new(s:String) 16 | this = s; 17 | 18 | @:to function toValidatable():Validatable 19 | return { 20 | validate: function():Option { 21 | for (r in rules) 22 | if (!r.check(this)) 23 | return Some(r.msg.replace('%VALUE', '`' + Json.stringify(this) + '`')); 24 | return None; 25 | } 26 | } 27 | 28 | static var rules = { // using an array because order might matter 29 | var a = new Array<{msg:String, check:String->Bool}>(); 30 | function add(m, r) 31 | a.push({msg: m, check: r}); 32 | add("%VALUE is not a String", #if (haxe_ver < 4.1) Std.is .bind(_, String) #else Std.isOfType.bind(_, String) #end 33 | ); 34 | add("%VALUE is too short", function(s) return s.length >= 3); 35 | add("%VALUE contains invalid characters", Data.alphanum.match); 36 | add("%VALUE is a reserved name", function(s) return RESERVED_NAMES.indexOf(s.toLowerCase()) == -1); 37 | add("%VALUE ends with a reserved suffix", function(s) { 38 | s = s.toLowerCase(); 39 | for (ext in RESERVED_EXTENSIONS) 40 | if (s.endsWith(ext)) 41 | return false; 42 | return true; 43 | }); 44 | a; 45 | } 46 | 47 | /** 48 | Validates that the project name is valid. 49 | 50 | If it is invalid, returns `Some(e)` where e is an error 51 | detailing why the project name is invalid. 52 | 53 | If it is valid, returns `None`. 54 | **/ 55 | public function validate() 56 | return toValidatable().validate(); 57 | 58 | public function toLowerCase():ProjectName 59 | return new ProjectName(this.toLowerCase()); 60 | 61 | /** 62 | Returns `s` as a `ProjectName` if it is valid, 63 | otherwise throws an error explaining why it is invalid. 64 | **/ 65 | static public function ofString(s:String) 66 | return switch new ProjectName(s) { 67 | case _.toValidatable().validate() => Some(e): throw e; 68 | case v: v; 69 | } 70 | 71 | /** 72 | If `alias` is just a different capitalization of `correct`, returns `correct`. 73 | 74 | If `alias` is completely different, returns `alias` instead. 75 | **/ 76 | static public function getCorrectOrAlias(correct:ProjectName, alias:ProjectName) { 77 | return if (correct.toLowerCase() == alias.toLowerCase()) correct else alias; 78 | } 79 | 80 | /** Default project name **/ 81 | static public var DEFAULT(default, null) = new ProjectName('unknown'); 82 | } 83 | -------------------------------------------------------------------------------- /terraform/bitnami/mysql/charts/common/templates/_images.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Return the proper image name 4 | {{ include "common.images.image" ( dict "imageRoot" .Values.path.to.the.image "global" $) }} 5 | */}} 6 | {{- define "common.images.image" -}} 7 | {{- $registryName := .imageRoot.registry -}} 8 | {{- $repositoryName := .imageRoot.repository -}} 9 | {{- $tag := .imageRoot.tag | toString -}} 10 | {{- if .global }} 11 | {{- if .global.imageRegistry }} 12 | {{- $registryName = .global.imageRegistry -}} 13 | {{- end -}} 14 | {{- end -}} 15 | {{- if $registryName }} 16 | {{- printf "%s/%s:%s" $registryName $repositoryName $tag -}} 17 | {{- else -}} 18 | {{- printf "%s:%s" $repositoryName $tag -}} 19 | {{- end -}} 20 | {{- end -}} 21 | 22 | {{/* 23 | Return the proper Docker Image Registry Secret Names (deprecated: use common.images.renderPullSecrets instead) 24 | {{ include "common.images.pullSecrets" ( dict "images" (list .Values.path.to.the.image1, .Values.path.to.the.image2) "global" .Values.global) }} 25 | */}} 26 | {{- define "common.images.pullSecrets" -}} 27 | {{- $pullSecrets := list }} 28 | 29 | {{- if .global }} 30 | {{- range .global.imagePullSecrets -}} 31 | {{- $pullSecrets = append $pullSecrets . -}} 32 | {{- end -}} 33 | {{- end -}} 34 | 35 | {{- range .images -}} 36 | {{- range .pullSecrets -}} 37 | {{- $pullSecrets = append $pullSecrets . -}} 38 | {{- end -}} 39 | {{- end -}} 40 | 41 | {{- if (not (empty $pullSecrets)) }} 42 | imagePullSecrets: 43 | {{- range $pullSecrets }} 44 | - name: {{ . }} 45 | {{- end }} 46 | {{- end }} 47 | {{- end -}} 48 | 49 | {{/* 50 | Return the proper Docker Image Registry Secret Names evaluating values as templates 51 | {{ include "common.images.renderPullSecrets" ( dict "images" (list .Values.path.to.the.image1, .Values.path.to.the.image2) "context" $) }} 52 | */}} 53 | {{- define "common.images.renderPullSecrets" -}} 54 | {{- $pullSecrets := list }} 55 | {{- $context := .context }} 56 | 57 | {{- if $context.Values.global }} 58 | {{- range $context.Values.global.imagePullSecrets -}} 59 | {{- $pullSecrets = append $pullSecrets (include "common.tplvalues.render" (dict "value" . "context" $context)) -}} 60 | {{- end -}} 61 | {{- end -}} 62 | 63 | {{- range .images -}} 64 | {{- range .pullSecrets -}} 65 | {{- $pullSecrets = append $pullSecrets (include "common.tplvalues.render" (dict "value" . "context" $context)) -}} 66 | {{- end -}} 67 | {{- end -}} 68 | 69 | {{- if (not (empty $pullSecrets)) }} 70 | imagePullSecrets: 71 | {{- range $pullSecrets }} 72 | - name: {{ . }} 73 | {{- end }} 74 | {{- end }} 75 | {{- end -}} 76 | -------------------------------------------------------------------------------- /src/Package.hx: -------------------------------------------------------------------------------- 1 | import haxe.crypto.Crc32; 2 | import haxe.zip.Entry; 3 | import haxe.zip.Writer; 4 | import haxe.zip.Tools; 5 | 6 | import sys.io.File; 7 | import sys.FileSystem; 8 | import haxelib.Data.Infos; 9 | 10 | using StringTools; 11 | 12 | class Package { 13 | static final outPath = "package.zip"; 14 | 15 | static function main() { 16 | checkVersion(); 17 | switch Sys.systemName() { 18 | case 'Windows': 19 | zipWindows(); 20 | case _: 21 | final exitCode = Sys.command('zip', ['-r', outPath, 'src/haxelib', 'haxelib.json', 'run.n', 'README.md', '-x', 'src/haxelib/server/*']); 22 | Sys.exit(exitCode); 23 | } 24 | } 25 | 26 | static function zipWindows() { 27 | final entries = new List(); 28 | 29 | function add(path:String, ?target:String) { 30 | if (!FileSystem.exists(path)) 31 | throw 'Invalid path: $path'; 32 | 33 | if (target == null) 34 | target = path; 35 | 36 | if (FileSystem.isDirectory(path)) { 37 | for (item in FileSystem.readDirectory(path)) 38 | add(path + "/" + item, target + "/" + item); 39 | } else { 40 | Sys.println("Adding " + target); 41 | final bytes = File.getBytes(path); 42 | final entry:Entry = { 43 | fileName: target, 44 | fileSize: bytes.length, 45 | fileTime: FileSystem.stat(path).mtime, 46 | compressed: false, 47 | dataSize: 0, 48 | data: bytes, 49 | crc32: Crc32.make(bytes), 50 | } 51 | Tools.compress(entry, 9); 52 | entries.add(entry); 53 | } 54 | } 55 | 56 | for (file in FileSystem.readDirectory("src/haxelib")) 57 | if (file != "server") 58 | add('src/haxelib/$file'); 59 | 60 | add("haxelib.json"); 61 | add("run.n"); 62 | add("README.md"); 63 | 64 | Sys.println("Saving to " + outPath); 65 | final out = File.write(outPath, true); 66 | final writer = new Writer(out); 67 | writer.write(entries); 68 | out.close(); 69 | } 70 | 71 | static function checkVersion() { 72 | final runVersion = { 73 | final p = new sys.io.Process("neko", ["run.n", "version"]); 74 | final v = p.stdout.readAll().toString().trim(); 75 | p.close(); 76 | v; 77 | } 78 | final json:Infos = haxe.Json.parse(sys.io.File.getContent("haxelib.json")); 79 | 80 | // Version output examples: 81 | // - 3.4.0 82 | // - 3.4.0 (6b9c8851036fb012c0e188bc27da07999b663b4f - dirty) 83 | if (!runVersion.startsWith(json.version)) { 84 | Sys.println('Error: Version in haxelib.json (${json.version}) does not match `neko run.n version` ($runVersion)'); 85 | Sys.exit(1); 86 | } 87 | 88 | if (runVersion.indexOf("dirty") >= 0) { 89 | Sys.println('Error: run.n was compiled with dirty source'); 90 | #if !debug 91 | Sys.exit(1); 92 | #end 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /test/tests/integration/TestEmpty.hx: -------------------------------------------------------------------------------- 1 | package tests.integration; 2 | 3 | import haxe.Http; 4 | import haxelib.SemVer; 5 | 6 | class TestEmpty extends IntegrationTests { 7 | function testEmpty():Void { 8 | // the initial local and remote repos are empty 9 | 10 | final installResult = haxelib(["install", "foo"]).result(); 11 | assertTrue(installResult.code != 0); 12 | 13 | final upgradeResult = haxelib(["upgrade"]).result(); 14 | assertSuccess(upgradeResult); 15 | 16 | final updateResult = haxelib(["update", "foo"]).result(); 17 | assertTrue(updateResult.code != 0); 18 | 19 | final removeResult = haxelib(["remove", "foo"]).result(); 20 | assertTrue(removeResult.code != 0); 21 | 22 | final upgradeResult = haxelib(["list"]).result(); 23 | assertSuccess(upgradeResult); 24 | 25 | final removeResult = haxelib(["set", "foo", "0.0"], "y\n").result(); 26 | assertTrue(removeResult.code != 0); 27 | 28 | final searchResult = haxelib(["search", "foo"]).result(); 29 | assertSuccess(searchResult); 30 | assertTrue(searchResult.out.indexOf("0") >= 0); 31 | 32 | final infoResult = haxelib(["info", "foo"]).result(); 33 | assertTrue(infoResult.code != 0); 34 | 35 | final userResult = haxelib(["user", "foo"]).result(); 36 | assertTrue(userResult.code != 0); 37 | 38 | final configResult = haxelib(["config"]).result(); 39 | assertSuccess(configResult); 40 | 41 | final pathResult = haxelib(["path", "foo"]).result(); 42 | assertTrue(pathResult.code != 0); 43 | 44 | if (clientVer > SemVer.ofString("3.1.0-rc.4")) { 45 | final versionResult = haxelib(["version"]).result(); 46 | assertSuccess(versionResult); 47 | 48 | final helpResult = haxelib(["help"]).result(); 49 | assertSuccess(helpResult); 50 | } 51 | } 52 | 53 | function testWebsite():Void { 54 | // home page 55 | assertNoError(function() Http.requestUrl(serverUrl)); 56 | 57 | // Haxelib Tags 58 | assertNoError(function() Http.requestUrl(Path.join([serverUrl, "t"]))); 59 | 60 | // All Haxelibs 61 | assertNoError(function() Http.requestUrl(Path.join([serverUrl, "all"]))); 62 | 63 | // Haxelib Contributors 64 | assertNoError(function() Http.requestUrl(Path.join([serverUrl, "u"]))); 65 | 66 | // docs 67 | assertNoError(function() Http.requestUrl(Path.join([serverUrl, "documentation"]))); 68 | assertNoError(function() Http.requestUrl(Path.join([serverUrl, "documentation/using-haxelib"]))); 69 | assertNoError(function() Http.requestUrl(Path.join([serverUrl, "documentation/creating-a-haxelib-package/"]))); 70 | assertNoError(function() Http.requestUrl(Path.join([serverUrl, "documentation/creating-a-haxelib-package/"]))); 71 | 72 | // RSS feed 73 | assertNoError(function() Http.requestUrl(Path.join([serverUrl, "rss"]))); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /.github/workflows/ci-dev.yml: -------------------------------------------------------------------------------- 1 | name: CI-dev 2 | 3 | on: 4 | push: 5 | branches-ignore: 6 | - master 7 | pull_request: 8 | workflow_dispatch: 9 | 10 | env: 11 | EARTHLY_USE_INLINE_CACHE: "true" 12 | EARTHLY_SAVE_INLINE_CACHE: "true" 13 | FORCE_COLOR: 1 14 | 15 | jobs: 16 | test: 17 | runs-on: ubuntu-latest 18 | steps: 19 | - uses: actions/checkout@v3 20 | with: 21 | submodules: recursive 22 | - uses: earthly/actions-setup@v1 23 | with: 24 | version: "v0.6.30" 25 | - name: Login to DockerHub 26 | if: success() && github.repository_owner == 'HaxeFoundation' && github.event_name == 'push' 27 | uses: docker/login-action@v1 28 | with: 29 | username: haxeci 30 | password: ${{ secrets.DOCKERHUB_TOKEN }} 31 | - name: Build images 32 | run: earthly +ci-images --GIT_REF_NAME="${{ github.ref_name }}" --GIT_SHA="${{ github.sha }}" 33 | - name: Run tests 34 | run: earthly --allow-privileged +ci-tests 35 | - name: Push images 36 | run: earthly --push +ci-images --GIT_REF_NAME="${{ github.ref_name }}" --GIT_SHA="${{ github.sha }}" 37 | if: github.repository_owner == 'HaxeFoundation' && github.event_name == 'push' 38 | deploy-development: 39 | if: success() && github.repository_owner == 'HaxeFoundation' && github.event_name == 'push' && github.ref_name == 'development' 40 | needs: test 41 | concurrency: deploy 42 | runs-on: ubuntu-latest 43 | container: haxe/haxelib_devcontainer_workspace:${{ github.sha }} 44 | env: 45 | AWS_DEFAULT_REGION: eu-west-1 46 | AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} 47 | AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} 48 | DIGITALOCEAN_ACCESS_TOKEN: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }} 49 | SPACES_ACCESS_KEY_ID: ${{ secrets.SPACES_ACCESS_KEY_ID }} 50 | SPACES_SECRET_ACCESS_KEY: ${{ secrets.SPACES_SECRET_ACCESS_KEY }} 51 | TF_VAR_HAXELIB_DB_PASS: ${{ secrets.TF_VAR_HAXELIB_DB_PASS }} 52 | TF_INPUT: 0 53 | TF_IN_AUTOMATION: 1 54 | steps: 55 | - uses: actions/checkout@v2 56 | - name: Verify image existence 57 | run: docker manifest inspect haxe/lib.haxe.org:${{ github.sha }} 58 | - name: Initialize Terraform 59 | run: terraform init 60 | working-directory: terraform 61 | - name: Ensure no pending infra changes 62 | run: terraform plan -refresh=false -detailed-exitcode 63 | working-directory: terraform 64 | - name: Set haxelib-server image 65 | run: terraform apply -auto-approve -refresh=false 66 | working-directory: terraform 67 | env: 68 | TF_VAR_HAXELIB_SERVER_IMAGE_DEVELOPMENT: haxe/lib.haxe.org:${{ github.sha }} 69 | -------------------------------------------------------------------------------- /test/website/controller/UserControllerTest.hx: -------------------------------------------------------------------------------- 1 | package website.controller; 2 | 3 | import haxe.crypto.Md5; 4 | import haxelib.server.SiteDb; 5 | import website.controller.*; 6 | import website.api.UserApi; 7 | import ufront.web.result.*; 8 | import ufront.web.result.ViewResult; 9 | import website.Server; 10 | using tink.CoreApi; 11 | 12 | // These imports are common for our various test-suite tools. 13 | import buddy.*; 14 | import mockatoo.Mockatoo.*; 15 | import ufront.test.TestUtils.NaturalLanguageTests.*; 16 | import utest.Assert; 17 | using buddy.Should; 18 | using ufront.test.TestUtils; 19 | using mockatoo.Mockatoo; 20 | 21 | class UserControllerTest extends BuddySuite { 22 | public function new() { 23 | 24 | var haxelibSite = WebsiteTests.getTestApp(); 25 | var mockApi = mock( UserApi ); 26 | haxelibSite.injector.map( UserApi ).toValue( mockApi ); 27 | 28 | function mockUser(user,name,email) { 29 | var u = new User(); 30 | u.name = user; 31 | u.fullname = name; 32 | u.email = email; 33 | var hash = Md5.encode( email ); 34 | return { user:u, emailHash:hash, projects:[], totalDownloads:[] }; 35 | } 36 | var user1 = mockUser( "jason", "Jason O'Neil", "jason@example.org" ); 37 | var user2 = mockUser( "ncanasse", "Nicolas Canasse", "nc@example.org" ); 38 | var projects = []; 39 | 40 | mockApi.getUserProfile(cast anyString).returns( Success(new Pair(user1.user,[])) ); 41 | mockApi.getUserList().returns( Success([user1, user2]) ); 42 | 43 | describe("When I look at the profile of a user", { 44 | it("Should show me that users profile and their projects", function (done) { 45 | whenIVisit( "/u/jason" ) 46 | .onTheApp( haxelibSite ) 47 | .itShouldLoad( UserController, "profile", ["jason"] ) 48 | .itShouldReturn( ViewResult, function (result) { 49 | var title:String = result.data['title']; 50 | (result.data['title']:String).should.be("jason (Jason O'Neil) on Haxelib"); 51 | Assert.same( result.templateSource, TFromEngine("user/profile") ); 52 | Assert.same( result.layoutSource, TFromEngine("layout.html") ); 53 | }) 54 | .andFinishWith( done ); 55 | }); 56 | }); 57 | 58 | describe("When I want to see a list of users", { 59 | it("Should show me that list, sorted by number of projects", function (done) { 60 | whenIVisit( "/u" ) 61 | .onTheApp( haxelibSite ) 62 | .itShouldLoad( UserController, "list", [] ) 63 | .itShouldReturn( ViewResult, function (result) { 64 | var title:String = result.data['title']; 65 | (result.data['title']:String).should.be("Haxelib Contributors"); 66 | Assert.same( result.templateSource, TFromEngine("user/list") ); 67 | Assert.same( result.layoutSource, TFromEngine("layout.html") ); 68 | }) 69 | .andFinishWith( done ); 70 | }); 71 | }); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/haxelib/MetaData.hx: -------------------------------------------------------------------------------- 1 | package haxelib; 2 | /** 3 | Contains definitions of meta data about libraries and their versions used in the Haxelib database 4 | **/ 5 | 6 | /** Information on a `user` in the Haxelib database. **/ 7 | typedef UserInfos = { 8 | /** The user's name. **/ 9 | var name : String; 10 | /** The user's full name. **/ 11 | var fullname : String; 12 | /** The user's email address. **/ 13 | var email : String; 14 | /** An array of projects for which the user is a contributor. **/ 15 | var projects : Array; 16 | } 17 | 18 | /** Information on a specific version of a project in the Haxelib database. **/ 19 | typedef VersionInfos = { 20 | /** The release date of the version. **/ 21 | var date : String; 22 | /** The version "name" in SemVer form. **/ 23 | var name : SemVer;//TODO: this should eventually be called `number` 24 | /** The number of downloads this version of the library has had. **/ 25 | var downloads : Int; 26 | /** The release note that came with this release. **/ 27 | var comments : String; 28 | } 29 | 30 | /** Information on a project in the Haxelib database. **/ 31 | typedef ProjectInfos = { 32 | /** The project name. **/ 33 | var name : String; 34 | /** The project's description. **/ 35 | var desc : String; 36 | /** A link to the project's website. **/ 37 | var website : String; 38 | /** The username of the owner of the project. **/ 39 | var owner : String; 40 | /** An array of contributor's user names and full names. **/ 41 | var contributors : Array<{ name:String, fullname:String }>; 42 | /** The license under which the project is released. **/ 43 | var license : String; 44 | /** The current version of the project. **/ 45 | var curversion : String; 46 | /** The total number of downloads the project has. **/ 47 | var downloads : Int; 48 | /** An array of `VersionInfos` for each release of the library. **/ 49 | var versions : Array; 50 | /** The project's tags. **/ 51 | var tags : List; 52 | } 53 | 54 | class MetaData { 55 | /** 56 | Returns the latest version from `info`, or `null` if no releases are found. 57 | 58 | By default preview versions are ignored. If `preview` is passed in, 59 | preview versions will be checked first and will only be skipped 60 | if calling `preview` with the `Preview` type of the version, 61 | and it is only skipped if the call returns `false`. 62 | **/ 63 | public static function getLatest(info:ProjectInfos, ?preview:SemVer.Preview->Bool):Null { 64 | if (info.versions.length == 0) 65 | return null; 66 | if (preview == null) 67 | preview = function(p) return p == null; 68 | 69 | var versions = info.versions.copy(); 70 | versions.sort(function(a, b) return -SemVer.compare(a.name, b.name)); 71 | 72 | for (v in versions) 73 | if (preview(v.name.preview)) 74 | return v.name; 75 | 76 | return versions[0].name; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /terraform/bitnami/mysql/charts/common/templates/validations/_cassandra.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Validate Cassandra required passwords are not empty. 4 | 5 | Usage: 6 | {{ include "common.validations.values.cassandra.passwords" (dict "secret" "secretName" "subchart" false "context" $) }} 7 | Params: 8 | - secret - String - Required. Name of the secret where Cassandra values are stored, e.g: "cassandra-passwords-secret" 9 | - subchart - Boolean - Optional. Whether Cassandra is used as subchart or not. Default: false 10 | */}} 11 | {{- define "common.validations.values.cassandra.passwords" -}} 12 | {{- $existingSecret := include "common.cassandra.values.existingSecret" . -}} 13 | {{- $enabled := include "common.cassandra.values.enabled" . -}} 14 | {{- $dbUserPrefix := include "common.cassandra.values.key.dbUser" . -}} 15 | {{- $valueKeyPassword := printf "%s.password" $dbUserPrefix -}} 16 | 17 | {{- if and (or (not $existingSecret) (eq $existingSecret "\"\"")) (eq $enabled "true") -}} 18 | {{- $requiredPasswords := list -}} 19 | 20 | {{- $requiredPassword := dict "valueKey" $valueKeyPassword "secret" .secret "field" "cassandra-password" -}} 21 | {{- $requiredPasswords = append $requiredPasswords $requiredPassword -}} 22 | 23 | {{- include "common.validations.values.multiple.empty" (dict "required" $requiredPasswords "context" .context) -}} 24 | 25 | {{- end -}} 26 | {{- end -}} 27 | 28 | {{/* 29 | Auxiliary function to get the right value for existingSecret. 30 | 31 | Usage: 32 | {{ include "common.cassandra.values.existingSecret" (dict "context" $) }} 33 | Params: 34 | - subchart - Boolean - Optional. Whether Cassandra is used as subchart or not. Default: false 35 | */}} 36 | {{- define "common.cassandra.values.existingSecret" -}} 37 | {{- if .subchart -}} 38 | {{- .context.Values.cassandra.dbUser.existingSecret | quote -}} 39 | {{- else -}} 40 | {{- .context.Values.dbUser.existingSecret | quote -}} 41 | {{- end -}} 42 | {{- end -}} 43 | 44 | {{/* 45 | Auxiliary function to get the right value for enabled cassandra. 46 | 47 | Usage: 48 | {{ include "common.cassandra.values.enabled" (dict "context" $) }} 49 | */}} 50 | {{- define "common.cassandra.values.enabled" -}} 51 | {{- if .subchart -}} 52 | {{- printf "%v" .context.Values.cassandra.enabled -}} 53 | {{- else -}} 54 | {{- printf "%v" (not .context.Values.enabled) -}} 55 | {{- end -}} 56 | {{- end -}} 57 | 58 | {{/* 59 | Auxiliary function to get the right value for the key dbUser 60 | 61 | Usage: 62 | {{ include "common.cassandra.values.key.dbUser" (dict "subchart" "true" "context" $) }} 63 | Params: 64 | - subchart - Boolean - Optional. Whether Cassandra is used as subchart or not. Default: false 65 | */}} 66 | {{- define "common.cassandra.values.key.dbUser" -}} 67 | {{- if .subchart -}} 68 | cassandra.dbUser 69 | {{- else -}} 70 | dbUser 71 | {{- end -}} 72 | {{- end -}} 73 | --------------------------------------------------------------------------------