From 4c14806f36328f783943b04c742e33fb6ad1bfab Mon Sep 17 00:00:00 2001 From: Craig Everett Date: Thu, 31 May 2018 20:33:53 +0900 Subject: [PATCH 1/4] add realm --- zomp/lib/otpr/zx/0.1.0/src/zx_key.erl | 16 ++++++++-------- zomp/lib/otpr/zx/0.1.0/src/zx_lib.erl | 3 ++- zomp/lib/otpr/zx/0.1.0/src/zx_local.erl | 8 ++++---- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/zomp/lib/otpr/zx/0.1.0/src/zx_key.erl b/zomp/lib/otpr/zx/0.1.0/src/zx_key.erl index ca59de2..8eac4f2 100644 --- a/zomp/lib/otpr/zx/0.1.0/src/zx_key.erl +++ b/zomp/lib/otpr/zx/0.1.0/src/zx_key.erl @@ -12,7 +12,7 @@ -copyright("Craig Everett "). -license("GPL-3.0"). --export([ensure_keypair/1, have_key/2, keypath/2, +-export([ensure_keypair/1, have_key/2, path/2, prompt_keygen/0, generate_rsa/1, load/2, verify/3]). @@ -51,19 +51,19 @@ ensure_keypair(KeyID = {Realm, KeyName}) -> %% Determine whether the indicated key is present. have_key(Type, KeyID) -> - filelib:is_regular(keypath(Type, KeyID)). + filelib:is_regular(path(Type, KeyID)). --spec keypath(Type, KeyID) -> Path +-spec path(Type, KeyID) -> Path when Type :: public | private, KeyID :: zx:key_id(), Path :: file:filename(). %% @private %% Given KeyID, return the path to the key type indicated. -keypath(public, {Realm, KeyName}) -> +path(public, {Realm, KeyName}) -> filename:join(zx_lib:path(key, Realm), KeyName ++ ".pub.der"); -keypath(private, {Realm, KeyName}) -> +path(private, {Realm, KeyName}) -> filename:join(zx_lib:path(key, Realm), KeyName ++ ".key.der"). @@ -116,8 +116,8 @@ prompt_keygen() -> generate_rsa(KeyID = {Realm, KeyName}) -> PemFile = filename:join(zx_lib:path(key, Realm), KeyName ++ ".pub.pem"), - KeyFile = keypath(private, KeyID), - PubFile = keypath(public, KeyID), + KeyFile = path(private, KeyID), + PubFile = path(public, KeyID), ok = lists:foreach(fun zx_lib:halt_if_exists/1, [PemFile, KeyFile, PubFile]), ok = log(info, "Generating ~p and ~p. Please be patient...", [KeyFile, PubFile]), ok = gen_p_key(KeyFile), @@ -234,7 +234,7 @@ load(Type, KeyID) -> private -> 'RSAPrivateKey'; public -> 'RSAPublicKey' end, - Path = keypath(Type, KeyID), + Path = path(Type, KeyID), ok = log(info, "Loading key from file ~ts", [Path]), case file:read_file(Path) of {ok, Bin} -> {ok, public_key:der_decode(DerType, Bin)}; diff --git a/zomp/lib/otpr/zx/0.1.0/src/zx_lib.erl b/zomp/lib/otpr/zx/0.1.0/src/zx_lib.erl index e0dc405..a394168 100644 --- a/zomp/lib/otpr/zx/0.1.0/src/zx_lib.erl +++ b/zomp/lib/otpr/zx/0.1.0/src/zx_lib.erl @@ -786,7 +786,8 @@ rm(Path) -> b_to_t(Binary) -> try - binary_to_term(Binary) + Term = binary_to_term(Binary), + {ok, Term} catch error:badarg -> error end. diff --git a/zomp/lib/otpr/zx/0.1.0/src/zx_local.erl b/zomp/lib/otpr/zx/0.1.0/src/zx_local.erl index bbb9a09..985a504 100644 --- a/zomp/lib/otpr/zx/0.1.0/src/zx_local.erl +++ b/zomp/lib/otpr/zx/0.1.0/src/zx_local.erl @@ -464,7 +464,7 @@ add_realm(Path) -> {ok, Data} -> Digest = crypto:hash(sha512, Data), Text = integer_to_list(binary:decode_unsigned(Digest, big), 16), - ok = log(info, "SHA512 of ~ts: ~ts", [Path, Text]), + ok = log(info, "SHA-512 of ~ts: ~ts", [Path, Text]), add_realm2(Data); {error, enoent} -> {error, "Realm bundle (.zrf) does not exist.", 2}; @@ -482,9 +482,9 @@ add_realm2(Data) -> Realm = maps:get(realm, RealmConf), ok = make_realm_dirs(Realm), ConfPath = zx_lib:realm_conf(Realm), - zx_lib:write_terms(ConfPath, maps:to_list(RealmConf)), + ok = zx_lib:write_terms(ConfPath, maps:to_list(RealmConf)), KeyName = maps:get(key, RealmConf), - KeyPath = zx_lib:keypath(public, {Realm, KeyName}), + KeyPath = zx_key:path(public, {Realm, KeyName}), ok = file:write_file(KeyPath, KeyDER), log(info, "Added realm ~tp.", [Realm]); error -> @@ -1050,7 +1050,7 @@ create_realmfile(Realm, Dir) -> {ok, RealmConf} = zx_lib:load_realm_conf(Realm), ok = log(info, "Realm found, creating realm file..."), KeyName = maps:get(key, RealmConf), - PubKeyPath = zx_key:keypath(public, {Realm, KeyName}), + PubKeyPath = zx_key:path(public, {Realm, KeyName}), {ok, PubDER} = file:read_file(PubKeyPath), Blob = term_to_binary({RealmConf, PubDER}), ZRF = filename:join(Dir, Realm ++ ".zrf"), From 948040cdcdfa6be8f52b9a17fde0dc477c17a4df Mon Sep 17 00:00:00 2001 From: Craig Everett Date: Thu, 31 May 2018 20:52:23 +0900 Subject: [PATCH 2/4] Add Emakefile to init app|lib --- zomp/lib/otpr/zx/0.1.0/src/zx_local.erl | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/zomp/lib/otpr/zx/0.1.0/src/zx_local.erl b/zomp/lib/otpr/zx/0.1.0/src/zx_local.erl index 985a504..8c869da 100644 --- a/zomp/lib/otpr/zx/0.1.0/src/zx_local.erl +++ b/zomp/lib/otpr/zx/0.1.0/src/zx_local.erl @@ -105,6 +105,15 @@ initialize(Type, PackageID, Prefix, AppStart) -> {appmod, AppStart}], Meta = maps:from_list(MetaList), ok = zx_lib:write_project_meta(Meta), + ok = + case filelib:is_regular("Emakefile") of + true -> + ok; + false -> + EM = [{"src/*", [debug_info, {i, "include/"}, {outdir, "ebin/"}]}, + {"test/*", [debug_info, {i, "include/"}, {outdir, "ebin/"}]}], + zx_lib:write_terms("Emakefile", EM) + end, {ok, PackageString} = zx_lib:package_string(PackageID), ok = log(info, "Project ~tp initialized.", [PackageString]), Message = From 3410bbbffb75601ef6abb6fbbf37ca084188b4fa Mon Sep 17 00:00:00 2001 From: Craig Everett Date: Thu, 31 May 2018 21:09:34 +0900 Subject: [PATCH 3/4] set dep --- zomp/lib/otpr/zx/0.1.0/src/zx_local.erl | 32 ++++++++++++------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/zomp/lib/otpr/zx/0.1.0/src/zx_local.erl b/zomp/lib/otpr/zx/0.1.0/src/zx_local.erl index 8c869da..8e08a41 100644 --- a/zomp/lib/otpr/zx/0.1.0/src/zx_local.erl +++ b/zomp/lib/otpr/zx/0.1.0/src/zx_local.erl @@ -286,28 +286,28 @@ assimilate2(CWD, PackageID) -> log(info, Message, [PackageString]). --spec set_dep(Identifier :: string()) -> zx:outcome(). +-spec set_dep(PackageString :: string()) -> zx:outcome(). %% @private -%% Set a specific dependency in the current project. If the project currently has a -%% dependency on the same package then the version of that dependency is updated to -%% reflect that in the PackageString argument. The AppString is permitted to be -%% incomplete. Incomplete elements of the VersionString (if included) will default to -%% the latest version available at the indicated level. +%% Set a dependency in the current project. If the project currently has a dependency +%% on the same package then the version of that dependency is updated to reflect that +%% in the PackageString argument. -set_dep(Identifier) -> - {ok, {Realm, Name, FuzzyVersion}} = zx_lib:package_id(Identifier), - case FuzzyVersion of - {X, Y, Z} when is_integer(X), is_integer(Y), is_integer(Z) -> - set_dep({Realm, Name}, {X, Y, Z}); - _ -> - {error, "Incompelte version tuple.", 22} +set_dep(PackageString) -> + case zx_lib:package_id(PackageString) of + {ok, {_, _, {_, _, z}}} -> + Message = + "Incomplete version tuple. Dependencies must be fully specified.", + {error, Message, 22}; + {ok, PackageID} -> + set_dep2(PackageID); + {error, invalid_package_string} -> + {error, "Invalid package string", 22} end. --spec set_dep(zx:package(), zx:version()) -> ok. +-spec set_dep2(zx:package_id()) -> ok. -set_dep({Realm, Name}, Version) -> - PackageID = {Realm, Name, Version}, +set_dep2(PackageID) -> {ok, Meta} = zx_lib:read_project_meta(), Deps = maps:get(deps, Meta), case lists:member(PackageID, Deps) of From aaf4ec124c5bebf8280f4e59c3a991405acaa494 Mon Sep 17 00:00:00 2001 From: Craig Everett Date: Thu, 31 May 2018 21:42:22 +0900 Subject: [PATCH 4/4] list_deps/0 --- zomp/lib/otpr/zx/0.1.0/src/zx.erl | 4 + zomp/lib/otpr/zx/0.1.0/src/zx_local.erl | 160 +++++++++++++++--------- 2 files changed, 103 insertions(+), 61 deletions(-) diff --git a/zomp/lib/otpr/zx/0.1.0/src/zx.erl b/zomp/lib/otpr/zx/0.1.0/src/zx.erl index b824ce2..9031436 100644 --- a/zomp/lib/otpr/zx/0.1.0/src/zx.erl +++ b/zomp/lib/otpr/zx/0.1.0/src/zx.erl @@ -99,6 +99,10 @@ do(["init", "app", PackageString]) -> do(["init", "lib", PackageString]) -> ok = compatibility_check([unix]), done(zx_local:initialize(lib, PackageString)); +do(["list", "deps"]) -> + done(zx_local:list_deps()); +do(["list", "deps", PackageString]) -> + done(zx_local:list_deps(PackageString)); do(["install", PackageFile]) -> done(zx_local:assimilate(PackageFile)); do(["set", "dep", PackageString]) -> diff --git a/zomp/lib/otpr/zx/0.1.0/src/zx_local.erl b/zomp/lib/otpr/zx/0.1.0/src/zx_local.erl index 8e08a41..abf3b86 100644 --- a/zomp/lib/otpr/zx/0.1.0/src/zx_local.erl +++ b/zomp/lib/otpr/zx/0.1.0/src/zx_local.erl @@ -10,9 +10,9 @@ -copyright("Craig Everett "). -license("GPL-3.0"). --export([initialize/2, assimilate/1, set_dep/1, set_version/1, +-export([initialize/2, assimilate/1, set_version/1, list_realms/0, list_packages/1, list_versions/1, - drop_dep/1, verup/1, package/1, + set_dep/1, list_deps/0, list_deps/1, drop_dep/1, verup/1, package/1, add_realm/1, drop_realm/1, takeover/1, abdicate/1, create_plt/0, dialyze/0, @@ -286,65 +286,6 @@ assimilate2(CWD, PackageID) -> log(info, Message, [PackageString]). --spec set_dep(PackageString :: string()) -> zx:outcome(). -%% @private -%% Set a dependency in the current project. If the project currently has a dependency -%% on the same package then the version of that dependency is updated to reflect that -%% in the PackageString argument. - -set_dep(PackageString) -> - case zx_lib:package_id(PackageString) of - {ok, {_, _, {_, _, z}}} -> - Message = - "Incomplete version tuple. Dependencies must be fully specified.", - {error, Message, 22}; - {ok, PackageID} -> - set_dep2(PackageID); - {error, invalid_package_string} -> - {error, "Invalid package string", 22} - end. - - --spec set_dep2(zx:package_id()) -> ok. - -set_dep2(PackageID) -> - {ok, Meta} = zx_lib:read_project_meta(), - Deps = maps:get(deps, Meta), - case lists:member(PackageID, Deps) of - true -> ok; - false -> set_dep(PackageID, Deps, Meta) - end. - - --spec set_dep(PackageID, Deps, Meta) -> ok - when PackageID :: zx:package_id(), - Deps :: [zx:package_id()], - Meta :: [term()]. -%% @private -%% Given the PackageID, list of Deps and the current contents of the project Meta, add -%% or update Deps to include (or update) Deps to reflect a dependency on PackageID, if -%% such a dependency is not already present. Then write the project meta back to its -%% file and exit. - -set_dep(PackageID = {Realm, Name, NewVersion}, Deps, Meta) -> - ExistingPackageIDs = fun({R, N, _}) -> {R, N} == {Realm, Name} end, - NewDeps = - case lists:partition(ExistingPackageIDs, Deps) of - {[{Realm, Name, OldVersion}], Rest} -> - Message = "Updating dep ~ts to ~ts", - {ok, OldPS} = zx_lib:package_string({Realm, Name, OldVersion}), - {ok, NewPS} = zx_lib:package_string({Realm, Name, NewVersion}), - ok = log(info, Message, [OldPS, NewPS]), - [PackageID | Rest]; - {[], Deps} -> - {ok, PackageString} = zx_lib:package_string(PackageID), - ok = log(info, "Adding dep ~ts", [PackageString]), - [PackageID | Deps] - end, - NewMeta = maps:put(deps, NewDeps, Meta), - zx_lib:write_project_meta(NewMeta). - - -spec set_version(VersionString) -> zx:outcome() when VersionString :: string(). %% @private @@ -501,6 +442,103 @@ add_realm2(Data) -> end. +-spec set_dep(PackageString :: string()) -> zx:outcome(). +%% @private +%% Set a dependency in the current project. If the project currently has a dependency +%% on the same package then the version of that dependency is updated to reflect that +%% in the PackageString argument. + +set_dep(PackageString) -> + case zx_lib:package_id(PackageString) of + {ok, {_, _, {_, _, z}}} -> + Message = + "Incomplete version tuple. Dependencies must be fully specified.", + {error, Message, 22}; + {ok, PackageID} -> + set_dep2(PackageID); + {error, invalid_package_string} -> + {error, "Invalid package string", 22} + end. + + +-spec set_dep2(zx:package_id()) -> ok. + +set_dep2(PackageID) -> + {ok, Meta} = zx_lib:read_project_meta(), + Deps = maps:get(deps, Meta), + case lists:member(PackageID, Deps) of + true -> ok; + false -> set_dep(PackageID, Deps, Meta) + end. + + +-spec set_dep(PackageID, Deps, Meta) -> ok + when PackageID :: zx:package_id(), + Deps :: [zx:package_id()], + Meta :: [term()]. +%% @private +%% Given the PackageID, list of Deps and the current contents of the project Meta, add +%% or update Deps to include (or update) Deps to reflect a dependency on PackageID, if +%% such a dependency is not already present. Then write the project meta back to its +%% file and exit. + +set_dep(PackageID = {Realm, Name, NewVersion}, Deps, Meta) -> + ExistingPackageIDs = fun({R, N, _}) -> {R, N} == {Realm, Name} end, + NewDeps = + case lists:partition(ExistingPackageIDs, Deps) of + {[{Realm, Name, OldVersion}], Rest} -> + Message = "Updating dep ~ts to ~ts", + {ok, OldPS} = zx_lib:package_string({Realm, Name, OldVersion}), + {ok, NewPS} = zx_lib:package_string({Realm, Name, NewVersion}), + ok = log(info, Message, [OldPS, NewPS]), + [PackageID | Rest]; + {[], Deps} -> + {ok, PackageString} = zx_lib:package_string(PackageID), + ok = log(info, "Adding dep ~ts", [PackageString]), + [PackageID | Deps] + end, + NewMeta = maps:put(deps, NewDeps, Meta), + zx_lib:write_project_meta(NewMeta). + + +-spec list_deps() -> zx:outcome(). +%% @private +%% List deps in the current (local) project directory. +%% This is very different from list_deps/1, which makes a remote query to a Zomp +%% realm to discover deps for potentially unknown or locally uncached packages. + +list_deps() -> + case zx_lib:read_project_meta() of + {ok, Meta} -> + Deps = maps:get(deps, Meta), + Print = + fun(P) -> + {ok, PackageString} = zx_lib:package_string(P), + io:format("~ts~n", [PackageString]) + end, + lists:foreach(Print, Deps); + Error -> + Error + end. + + +-spec list_deps(zx:package_id()) -> zx:outcome(). +%% @private +%% List deps for the specified package. This quite often requires a query to a Zomp +%% realm over the network, but not if the referenced package happens to be cached +%% locally. + +list_deps(PackageString) -> + case zx_lib:package_id(PackageString) of + {ok, {_, _, {_, _, z}}} -> + {error, "Packages must be fully specified; no partial versions.", 22}; + {ok, PackageID} -> + log(info, "Phooey! list_deps(~tp) isn't yet implemented!", [PackageID]); + {error, invalid_package_string} -> + {error, "Invalid package string.", 22} + end. + + -spec drop_dep(zx:package_id()) -> ok. %% @private %% Remove the indicate dependency from the local project's zomp.meta record.