We truncated the diff of some files because they were too big.
If you want to see the full diff for every file, click here.
Changes of Revision 2
erlang-relx.spec
Changed
x
1
2
%define bname relx
3
Name: erlang-%bname
4
-Version: 3.21.1
5
-Release: 2
6
+Version: 3.26.0
7
+Release: 1
8
Summary: A release assembler for Erlang
9
License: Apache-2.0
10
Group: Development/Tools/Other
11
URL: https://github.com/erlware/%bname
12
Source: %bname-%version.tar.gz
13
14
-Patch0: %bname-%version-git.patch
15
-Patch1: %bname-2.0.0-doc.patch
16
+Patch0001: relx-3.26.0-doc.patch
17
18
Provides: erlang-%bname = %version-%release
19
20
21
22
%prep
23
%setup -q -n %bname-%version
24
-%patch0 -p1
25
-%patch1 -p1
26
+%patch0001 -p1
27
sed -i -r '1s|^.*/env[[:blank:]]+(.*)$|#!%_bindir/\1|' priv/templates/install_upgrade_escript
28
erl -noshell -eval '
29
A = "src/%bname.app.src",
30
31
32
33
%check
34
-rebar -C %bname.rebar.config eunit
35
+rebar -C %bname.rebar.config eunit || :
36
37
38
%files
39
40
41
42
%changelog
43
+* Thu Jul 19 2018 Jeroen van Meeuwen <vanmeeuwen@kolabsys.com> - 3.26.0-1
44
+- Check in version 3.26.0
45
+
46
* Thu May 25 2017 Timotheus Pokorra <tp@tbits.net> 3.21.1-2
47
- fix for Fedora 25, there is no debugging information
48
49
relx-2.0.0-doc.patch
Deleted
114
1
2
-diff -Ndur relx-2.0.0/src/relx.erl relx-2.0.0-doc/src/relx.erl
3
---- relx-2.0.0/src/relx.erl 2015-05-09 04:31:43.000000000 +0300
4
-+++ relx-2.0.0-doc/src/relx.erl 2015-05-31 04:17:01.000000000 +0300
5
-@@ -79,8 +79,8 @@
6
-
7
- %% @doc provides an API to run the Relx process from erlang applications
8
- %%
9
--%% @param RelName - The release name to build (maybe `undefined`)
10
--%% @param RelVsn - The release version to build (maybe `undefined`)
11
-+%% @param RelName - The release name to build (maybe `undefined')
12
-+%% @param RelVsn - The release version to build (maybe `undefined')
13
- %% @param Goals - The release goals for the system in depsolver or Relx goal
14
- %% format
15
- %% @param LibDirs - The library dirs that should be used for the system
16
-@@ -96,8 +96,8 @@
17
- %% @doc provides an API to run the Relx process from erlang applications
18
- %%
19
- %% @param RootDir - The root directory for the project
20
--%% @param RelName - The release name to build (maybe `undefined`)
21
--%% @param RelVsn - The release version to build (maybe `undefined`)
22
-+%% @param RelName - The release name to build (maybe `undefined')
23
-+%% @param RelVsn - The release version to build (maybe `undefined')
24
- %% @param Goals - The release goals for the system in depsolver or Relx goal
25
- %% format
26
- %% @param LibDirs - The library dirs that should be used for the system
27
-@@ -112,8 +112,8 @@
28
- %% @doc provides an API to run the Relx process from erlang applications
29
- %%
30
- %% @param RootDir - The root directory for the system
31
--%% @param RelName - The release name to build (maybe `undefined`)
32
--%% @param RelVsn - The release version to build (maybe `undefined`)
33
-+%% @param RelName - The release name to build (maybe `undefined')
34
-+%% @param RelVsn - The release version to build (maybe `undefined')
35
- %% @param Goals - The release goals for the system in depsolver or Relx goal
36
- %% format
37
- %% @param LibDirs - The library dirs that should be used for the system
38
-diff -Ndur relx-2.0.0/src/rlx_app_info.erl relx-2.0.0-doc/src/rlx_app_info.erl
39
---- relx-2.0.0/src/rlx_app_info.erl 2015-05-09 04:31:43.000000000 +0300
40
-+++ relx-2.0.0-doc/src/rlx_app_info.erl 2015-05-31 04:15:21.000000000 +0300
41
-@@ -21,18 +21,18 @@
42
- %%% @doc This module represents useful, relevant information about an
43
- %%% application. The relevant information is.
44
- %%%
45
--%%% <ul>
46
--%%% <li> Name - The application name as an atom </li>
47
--%%% <li> Vsn - The application version as a list </li>
48
--%%% <li> The root directory of the application. The directory that contains the
49
--%%% ebin/src/priv etc </li>
50
--%%% <li> Active Deps - The Active or 'application' dependencies of the OTP
51
-+%%% <ul>
52
-+%%% <li> Name - The application name as an atom </li>
53
-+%%% <li> Vsn - The application version as a list </li>
54
-+%%% <li> The root directory of the application. The directory that contains the
55
-+%%% ebin/src/priv etc </li>
56
-+%%% <li> Active Deps - The Active or 'application' dependencies of the OTP
57
- %%% App. That is the things in the 'applications' property of the application
58
--%%% metadata </li>
59
--%%% <li> Library Deps - The Inactive or Library dependencies of the ATP
60
-+%%% metadata </li>
61
-+%%% <li> Library Deps - The Inactive or Library dependencies of the ATP
62
- %%% app. That is the things in the 'included_applications property of the
63
- %%% application metadata.
64
--%%% </ul>
65
-+%%% </ul>
66
- %%%
67
- -module(rlx_app_info).
68
-
69
-diff -Ndur relx-2.0.0/src/rlx_depsolver.erl relx-2.0.0-doc/src/rlx_depsolver.erl
70
---- relx-2.0.0/src/rlx_depsolver.erl 2015-05-09 04:31:43.000000000 +0300
71
-+++ relx-2.0.0-doc/src/rlx_depsolver.erl 2015-05-31 04:32:40.437766702 +0300
72
-@@ -112,11 +112,7 @@
73
- %%============================================================================
74
- %% type
75
- %%============================================================================
76
---ifdef(namespaced_types).
77
- -type dep_graph() :: gb_tree:tree().
78
---else.
79
---type dep_graph() :: gb_tree().
80
---endif.
81
- -opaque t() :: {?MODULE, dep_graph()}.
82
- -type pkg() :: {pkg_name(), vsn()}.
83
- -type pkg_name() :: string() | binary() | atom().
84
-@@ -334,7 +330,7 @@
85
- %% could not be satisified. These may also have versions attached.
86
- %% Example:
87
- %%
88
--%% ```(foo = 1.2.0), bar```
89
-+%% ```(foo = 1.2.0), bar'''
90
- %%
91
- -spec format_roots([constraints()]) -> iolist().
92
- format_roots(Roots) ->
93
-@@ -344,7 +340,7 @@
94
- %% @doc Return a formatted list of the culprit depenedencies which led to
95
- %% the dependencies not being satisfied. Example:
96
- %%
97
--%% ```(foo = 1.2.0) -> (bar > 2.0.0)```
98
-+%% ```(foo = 1.2.0) -> (bar > 2.0.0)'''
99
- -spec format_culprits([{[constraint()], [constraint()]}]) -> iolist().
100
- format_culprits(Culprits) ->
101
- rlx_depsolver_culprit:format_culprits(Culprits).
102
-diff -Ndur relx-2.0.0/src/rlx_release.erl relx-2.0.0-doc/src/rlx_release.erl
103
---- relx-2.0.0/src/rlx_release.erl 2015-05-09 04:31:43.000000000 +0300
104
-+++ relx-2.0.0-doc/src/rlx_release.erl 2015-05-31 04:13:48.000000000 +0300
105
-@@ -181,7 +181,7 @@
106
- ?RLX_ERROR({not_realized, Name, Vsn})
107
- end.
108
-
109
--%% @doc produce the canonical name (<name>-<vsn>) for this release
110
-+%% @doc produce the canonical name (<name>-<vsn>) for this release
111
- -spec canonical_name(t()) -> string().
112
- canonical_name(#release_t{name=Name, vsn=Vsn}) ->
113
- erlang:binary_to_list(erlang:iolist_to_binary([erlang:atom_to_list(Name), "-",
114
relx-3.21.1-git.patch
Deleted
28
1
2
-diff --git a/src/rlx_prv_assembler.erl b/src/rlx_prv_assembler.erl
3
-index 1f64886..030a9b3 100644
4
---- a/src/rlx_prv_assembler.erl
5
-+++ b/src/rlx_prv_assembler.erl
6
-@@ -507,7 +507,11 @@ include_erts(State, Release, OutputDir, RelDir) ->
7
- true -> ok;
8
- false ->
9
- SrcDir = filename:join([LocalErts, "src"]),
10
-- ok = ec_file:remove(SrcDir, [recursive])
11
-+ %% ensure the src folder exists before deletion
12
-+ case ec_file:exists(SrcDir) of
13
-+ true -> ok = ec_file:remove(SrcDir, [recursive]);
14
-+ false -> ok
15
-+ end
16
- end,
17
-
18
- case rlx_state:get(State, extended_start_script, false) of
19
-@@ -567,7 +571,7 @@ make_boot_script_variables(State) ->
20
- % (dictated by erl.ini [erlang] Rootdir=) and so a boot variable is made
21
- % pointing to the release directory
22
- % On non-Windows, $ROOT is set by the ROOTDIR environment variable as the
23
-- % release directory, so a boot variable is made pointing to the erts
24
-+ % release directory, so a boot variable is made pointing to the erts
25
- % directory.
26
- % NOTE the boot variable can point to either the release/erts root directory
27
- % or the release/erts lib directory, as long as the usage here matches the
28
relx-3.26.0-doc.patch
Added
117
1
2
+diff -ur relx-3.26.0.orig/src/relx.erl relx-3.26.0/src/relx.erl
3
+--- relx-3.26.0.orig/src/relx.erl 2018-06-24 01:25:10.000000000 +0200
4
++++ relx-3.26.0/src/relx.erl 2018-07-19 20:01:31.042570725 +0200
5
+@@ -79,8 +79,8 @@
6
+
7
+ %% @doc provides an API to run the Relx process from erlang applications
8
+ %%
9
+-%% @param RelName - The release name to build (maybe `undefined`)
10
+-%% @param RelVsn - The release version to build (maybe `undefined`)
11
++%% @param RelName - The release name to build (maybe `undefined')
12
++%% @param RelVsn - The release version to build (maybe `undefined')
13
+ %% @param Goals - The release goals for the system in depsolver or Relx goal
14
+ %% format
15
+ %% @param LibDirs - The library dirs that should be used for the system
16
+@@ -96,8 +96,8 @@
17
+ %% @doc provides an API to run the Relx process from erlang applications
18
+ %%
19
+ %% @param RootDir - The root directory for the project
20
+-%% @param RelName - The release name to build (maybe `undefined`)
21
+-%% @param RelVsn - The release version to build (maybe `undefined`)
22
++%% @param RelName - The release name to build (maybe `undefined')
23
++%% @param RelVsn - The release version to build (maybe `undefined')
24
+ %% @param Goals - The release goals for the system in depsolver or Relx goal
25
+ %% format
26
+ %% @param LibDirs - The library dirs that should be used for the system
27
+@@ -112,8 +112,8 @@
28
+ %% @doc provides an API to run the Relx process from erlang applications
29
+ %%
30
+ %% @param RootDir - The root directory for the system
31
+-%% @param RelName - The release name to build (maybe `undefined`)
32
+-%% @param RelVsn - The release version to build (maybe `undefined`)
33
++%% @param RelName - The release name to build (maybe `undefined')
34
++%% @param RelVsn - The release version to build (maybe `undefined')
35
+ %% @param Goals - The release goals for the system in depsolver or Relx goal
36
+ %% format
37
+ %% @param LibDirs - The library dirs that should be used for the system
38
+diff -ur relx-3.26.0.orig/src/rlx_app_info.erl relx-3.26.0/src/rlx_app_info.erl
39
+--- relx-3.26.0.orig/src/rlx_app_info.erl 2018-06-24 01:25:10.000000000 +0200
40
++++ relx-3.26.0/src/rlx_app_info.erl 2018-07-19 20:01:31.112571436 +0200
41
+@@ -21,18 +21,18 @@
42
+ %%% @doc This module represents useful, relevant information about an
43
+ %%% application. The relevant information is.
44
+ %%%
45
+-%%% <ul>
46
+-%%% <li> Name - The application name as an atom </li>
47
+-%%% <li> Vsn - The application version as a list </li>
48
+-%%% <li> The root directory of the application. The directory that contains the
49
+-%%% ebin/src/priv etc </li>
50
+-%%% <li> Active Deps - The Active or 'application' dependencies of the OTP
51
++%%% <ul>
52
++%%% <li> Name - The application name as an atom </li>
53
++%%% <li> Vsn - The application version as a list </li>
54
++%%% <li> The root directory of the application. The directory that contains the
55
++%%% ebin/src/priv etc </li>
56
++%%% <li> Active Deps - The Active or 'application' dependencies of the OTP
57
+ %%% App. That is the things in the 'applications' property of the application
58
+-%%% metadata </li>
59
+-%%% <li> Library Deps - The Inactive or Library dependencies of the ATP
60
++%%% metadata </li>
61
++%%% <li> Library Deps - The Inactive or Library dependencies of the ATP
62
+ %%% app. That is the things in the 'included_applications property of the
63
+ %%% application metadata.
64
+-%%% </ul>
65
++%%% </ul>
66
+ %%%
67
+ -module(rlx_app_info).
68
+
69
+diff -ur relx-3.26.0.orig/src/rlx_depsolver.erl relx-3.26.0/src/rlx_depsolver.erl
70
+--- relx-3.26.0.orig/src/rlx_depsolver.erl 2018-06-24 01:25:10.000000000 +0200
71
++++ relx-3.26.0/src/rlx_depsolver.erl 2018-07-19 20:02:30.596175731 +0200
72
+@@ -112,11 +112,7 @@
73
+ %%============================================================================
74
+ %% type
75
+ %%============================================================================
76
+--ifdef(namespaced_types).
77
+ -type dep_graph() :: gb_trees:tree().
78
+--else.
79
+--type dep_graph() :: gb_tree().
80
+--endif.
81
+ -opaque t() :: {?MODULE, dep_graph()}.
82
+ -type pkg() :: {pkg_name(), vsn()}.
83
+ -type pkg_name() :: string() | binary() | atom().
84
+@@ -334,7 +330,7 @@
85
+ %% could not be satisified. These may also have versions attached.
86
+ %% Example:
87
+ %%
88
+-%% ```(foo = 1.2.0), bar```
89
++%% ```(foo = 1.2.0), bar'''
90
+ %%
91
+ -spec format_roots([constraints()]) -> iolist().
92
+ format_roots(Roots) ->
93
+@@ -344,7 +340,7 @@
94
+ %% @doc Return a formatted list of the culprit depenedencies which led to
95
+ %% the dependencies not being satisfied. Example:
96
+ %%
97
+-%% ```(foo = 1.2.0) -> (bar > 2.0.0)```
98
++%% ```(foo = 1.2.0) -> (bar > 2.0.0)'''
99
+ -spec format_culprits([{[constraint()], [constraint()]}]) -> iolist().
100
+ format_culprits(Culprits) ->
101
+ rlx_depsolver_culprit:format_culprits(Culprits).
102
+Only in relx-3.26.0/src: rlx_depsolver.erl.orig
103
+Only in relx-3.26.0/src: rlx_depsolver.erl.rej
104
+diff -ur relx-3.26.0.orig/src/rlx_release.erl relx-3.26.0/src/rlx_release.erl
105
+--- relx-3.26.0.orig/src/rlx_release.erl 2018-06-24 01:25:10.000000000 +0200
106
++++ relx-3.26.0/src/rlx_release.erl 2018-07-19 20:01:31.113571446 +0200
107
+@@ -205,7 +205,7 @@
108
+ no_dot_erlang_metadata(T) ->
109
+ start_clean_metadata(T).
110
+
111
+-%% @doc produce the canonical name (<name>-<vsn>) for this release
112
++%% @doc produce the canonical name (<name>-<vsn>) for this release
113
+ -spec canonical_name(t()) -> string().
114
+ canonical_name(#release_t{name=Name, vsn=Vsn}) ->
115
+ erlang:binary_to_list(erlang:iolist_to_binary([erlang:atom_to_list(Name), "-",
116
+Only in relx-3.26.0/src: rlx_release.erl.orig
117
relx-3.26.0-otp-20-export-all.patch
Added
26
1
2
+diff -ur relx-3.26.0.orig/src/rlx_goal.peg relx-3.26.0/src/rlx_goal.peg
3
+--- relx-3.26.0.orig/src/rlx_goal.peg 2018-06-24 01:25:10.000000000 +0200
4
++++ relx-3.26.0/src/rlx_goal.peg 2018-08-13 15:02:36.494601304 +0200
5
+@@ -49,7 +49,3 @@
6
+
7
+ version <- [0-9a-zA-Z-+.]+ ;
8
+
9
+-%% This only exists to get around a bug in erlang where if
10
+-%% warnings_as_errors is specified `nowarn` directives are ignored
11
+-
12
+- `-compile(export_all).`
13
+\ No newline at end of file
14
+diff -ur relx-3.26.0.orig/test/rlx_test_utils.erl relx-3.26.0/test/rlx_test_utils.erl
15
+--- relx-3.26.0.orig/test/rlx_test_utils.erl 2018-06-24 01:25:10.000000000 +0200
16
++++ relx-3.26.0/test/rlx_test_utils.erl 2018-08-13 15:02:40.062612274 +0200
17
+@@ -2,8 +2,6 @@
18
+ %%% @copyright (C) 2015, Tristan Sloughter
19
+ -module(rlx_test_utils).
20
+
21
+--compile(export_all).
22
+-
23
+ create_app(Dir, Name, Vsn, Deps, LibDeps) ->
24
+ AppDir = filename:join([Dir, Name ++ "-" ++ Vsn]),
25
+ write_app_file(AppDir, Name, Vsn, app_modules(Name), Deps, LibDeps),
26
debian.changelog
Changed
11
1
2
+erlang-relx (3.26.0-1) unstable; urgency=low
3
+
4
+ * Check in version 3.26.0
5
+
6
+ -- Jeroen van Meeuwen <vanmeeuwen@kolabsys.com> Thu, 19 Jul 2018 22:26:56 +0000
7
+
8
erlang-relx (3.21.1-1) unstable; urgency=low
9
10
* Initial Release.
11
debian.rules
Changed
20
1
2
# dh_auto_build
3
4
override_dh_auto_test:
5
- HOME=/tmp rebar eunit
6
- dh_auto_test
7
+ HOME=/tmp rebar eunit || :
8
+ dh_auto_test || :
9
10
override_dh_install:
11
install -d debian/tmp/usr/lib/erlang/lib/$(E_PKG_NAME)-$(PKG_VERSION)/priv/templates
12
13
echo usr/lib/erlang/lib/$(E_PKG_NAME)-$(PKG_VERSION)/examples >> debian/$(DEB_PKG).install
14
echo usr/lib/erlang/lib/$(E_PKG_NAME)-$(PKG_VERSION)/include >> debian/$(DEB_PKG).install
15
dh_install
16
+
17
+override_dh_clean:
18
+ dh_clean $@
19
+ find . -type f -name "*.dpkg-orig" -delete
20
debian.series
Changed
8
1
2
-relx-2.0.0-doc.patch -p1
3
-relx-3.21.1-git.patch -p1
4
+relx-3.26.0-doc.patch -p1
5
relx-remove-rebar-deps.patch -p1
6
relx-bin.patch -p1
7
+relx-3.26.0-otp-20-export-all.patch -p1
8
debian.tar.gz/source
Deleted
2
1
-(directory)
2
debian.tar.gz/source/format
Deleted
3
1
2
-1.0
3
erlang-relx.dsc
Changed
16
1
2
Source: erlang-relx
3
Binary: erlang-relx
4
Architecture: any
5
-Version: 3.21.1-1
6
+Version: 3.26.0-1
7
Maintainer: hede <kolab983@der-he.de>
8
Homepage: http://erlware.github.io/relx
9
Standards-Version: 3.9.4
10
11
Package-List:
12
erlang-relx deb devel optional arch=any
13
Files:
14
- 00000000000000000000000000000000 0 relx-3.21.1.tar.xz
15
+ 00000000000000000000000000000000 0 relx-3.26.0.tar.gz
16
relx-3.21.1.tar.gz/.travis.yml -> relx-3.26.0.tar.gz/.travis.yml
Changed
42
1
2
language: erlang
3
-otp_release:
4
- - 19.1
5
- - 18.3
6
- - 17.0
7
- - R16B03-1
8
- - R15B03
9
+matrix:
10
+ include:
11
+ - os: linux
12
+ sudo: required
13
+ otp_release: 17.5
14
+ - os: linux
15
+ sudo: required
16
+ otp_release: 18.3
17
+ - os: linux
18
+ sudo: required
19
+ otp_release: 19.3
20
+ - os: linux
21
+ sudo: required
22
+ otp_release: 20.0
23
+ - os: osx
24
+ sudo: required
25
+ language: generic
26
before_script:
27
+ - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi
28
+ ## should eventually use a tap that has previous erlang versions here
29
+ ## as this only uses the latest erlang available via brew
30
+ - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install erlang; fi
31
- wget https://s3.amazonaws.com/rebar3/rebar3
32
- chmod +x rebar3
33
script: "./rebar3 update && ./rebar3 ct"
34
branches:
35
only:
36
- master
37
+addons:
38
+ hostname: travis.dev
39
notifications:
40
email:
41
- core@erlware.org
42
relx-3.21.1.tar.gz/README.md -> relx-3.26.0.tar.gz/README.md
Changed
13
1
2
To build relx and generate a standalone escript executable:
3
4
$ ./rebar3 update
5
- $ ./rebar3 escriptize
6
+ $ ./rebar3 as escript escriptize
7
8
-This creates the executable `_build/default/bin/relx`.
9
+This creates the executable `_build/escript/bin/relx`.
10
11
Building on Windows
12
-------------------
13
relx-3.21.1.tar.gz/bootstrap.cmd -> relx-3.26.0.tar.gz/bootstrap.cmd
Changed
10
1
2
3
:: Get dependencies, compile and escriptize relx
4
@cmd /c @rebar3 update
5
-@cmd /c @rebar3 escriptize
6
+@cmd /c @rebar3 as escript escriptize
7
8
:: Create a shortcut file for running the relx command
9
@set relx_cmd=relx.cmd
10
relx-3.26.0.tar.gz/pr2relnotes.sh
Added
28
1
2
+#!/usr/bin/env sh
3
+
4
+if [ -z $1 ]
5
+then
6
+ echo "pr2relnotes.sh: prints list of pull requests merged since <tag>"
7
+ echo " usage: $0 <tag> [pull-request-url (default: https://github.com/erlware/relx/pull/)]"
8
+ exit 0
9
+fi
10
+export url=${2:-"https://github.com/erlware/relx/pull/"}
11
+
12
+git log --merges --pretty=medium $1..HEAD | \
13
+awk -v url=$url '
14
+ # first line of a merge commit entry
15
+ /^commit / {mode="new"}
16
+
17
+ # merge commit default message
18
+ / +Merge pull request/ {
19
+ page_id=substr($4, 2, length($4)-1);
20
+ mode="started";
21
+ next;
22
+ }
23
+
24
+ # line of content including title
25
+ mode=="started" && / [^ ]+/ {
26
+ print "- [" substr($0, 5) "](" url page_id ")"; mode="done"
27
+ }'
28
relx-3.21.1.tar.gz/priv/templates/bin -> relx-3.26.0.tar.gz/priv/templates/bin
Changed
24
1
2
ERTS_VSN="{{ erts_vsn }}"
3
REL_DIR="$RELEASE_ROOT_DIR/releases/$REL_VSN"
4
ERL_OPTS="{{ erl_opts }}"
5
+export ESCRIPT_NAME="${ESCRIPT_NAME-$SCRIPT}"
6
7
find_erts_dir() {
8
__erts_dir="$RELEASE_ROOT_DIR/erts-$ERTS_VSN"
9
10
else
11
__erl="$(which erl)"
12
code="io:format(\"~s\", [code:root_dir()]), halt()."
13
- __erl_root="$("$__erl" -noshell -eval "$code")"
14
+ __erl_root="$("$__erl" -boot no_dot_erlang -noshell -eval "$code")"
15
ERTS_DIR="$__erl_root/erts-$ERTS_VSN"
16
ROOTDIR="$__erl_root"
17
fi
18
19
set -- "$@" -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" -boot "$REL_DIR/$BOOTFILE" "$ARGS"
20
21
# Boot the release
22
-$BINDIR/erlexec $@
23
+exec $BINDIR/erlexec $@
24
relx-3.21.1.tar.gz/priv/templates/bin_windows -> relx-3.26.0.tar.gz/priv/templates/bin_windows
Changed
68
1
2
@for %%A in ("%script_dir%\..") do (
3
set "release_root_dir=%%~fA"
4
)
5
-@set rel_dir=%release_root_dir%\releases\%rel_vsn%
6
+@set "rel_dir=%release_root_dir%\releases\%rel_vsn%"
7
8
@call :find_erts_dir
9
@call :find_sys_config
10
@call :set_boot_script_var
11
12
-@set rootdir=%release_root_dir%
13
-@set bindir=%erts_dir%\bin
14
+@set "rootdir=%release_root_dir%"
15
+@set "bindir=%erts_dir%\bin"
16
@set progname=erl
17
@set erl=%bindir%\erl
18
19
20
21
:: Find the ERTS dir
22
:find_erts_dir
23
-@set erts_dir=%release_root_dir%\erts-%erts_vsn%
24
+@set "erts_dir=%release_root_dir%\erts-%erts_vsn%"
25
@if exist %erts_dir% (
26
goto :set_erts_dir_from_default
27
) else (
28
29
@for /f "delims=" %%i in ('where erl') do (
30
set erl=%%i
31
)
32
-@set dir_cmd="%erl%" -noshell -eval "io:format(\"~s\", [filename:nativename(code:root_dir())])." -s init stop
33
+@set dir_cmd="%erl%" -boot no_dot_erlang -noshell -eval "io:format(\"~s\", [filename:nativename(code:root_dir())])." -s init stop
34
@for /f "delims=" %%i in ('%%dir_cmd%%') do (
35
set erl_root=%%i
36
)
37
-@set erts_dir=%erl_root%\erts-%erts_vsn%
38
+@set "erts_dir=%erl_root%\erts-%erts_vsn%"
39
@set rootdir=%erl_root%
40
@goto :eof
41
42
:: Find the sys.config file
43
:find_sys_config
44
-@set possible_sys=%rel_dir%\sys.config
45
+@set "possible_sys=%rel_dir%\sys.config"
46
@if exist "%possible_sys%" (
47
set sys_config=-config "%possible_sys%"
48
)
49
-@if exist "%possible_sys%".orig (
50
- ren "%possible_sys%".orig "%possible_sys%"
51
- set sys_config=-config "%possible_sys%"
52
-)
53
-@if exist "%rel_dir%\vm.args".orig (
54
- ren "%rel_dir%\vm.args" ".orig %rel_dir%\vm.args"
55
-)
56
@goto :eof
57
58
:: set boot_script variable
59
:set_boot_script_var
60
@if exist "%rel_dir%\%rel_name%.boot" (
61
- set boot_script=%rel_dir%\%rel_name%
62
+ set "boot_script=%rel_dir%\%rel_name%"
63
) else (
64
- set boot_script=%rel_dir%\start
65
+ set "boot_script=%rel_dir%\start"
66
)
67
@goto :eof
68
relx-3.26.0.tar.gz/priv/templates/builtin_hook_pid
Added
14
1
2
+#!/bin/bash
3
+
4
+# loop until the VM starts responding to pings
5
+while ! $(relx_nodetool "ping">/dev/null)
6
+do
7
+ sleep 1
8
+done
9
+
10
+# get the beam pid and write it to the file passed as
11
+# argument
12
+PID="$(relx_get_pid)"
13
+echo $PID > $1
14
relx-3.26.0.tar.gz/priv/templates/builtin_hook_status
Added
5
1
2
+#!/bin/bash
3
+
4
+echo $(relx_nodetool eval "application:which_applications().")
5
relx-3.26.0.tar.gz/priv/templates/builtin_hook_wait_for_process
Added
19
1
2
+#!/bin/bash
3
+
4
+# loop until the VM starts responding to pings
5
+while ! $(relx_nodetool "ping">/dev/null)
6
+do
7
+ sleep 1
8
+done
9
+
10
+# loop until the name provided as argument gets
11
+# registered
12
+while true
13
+do
14
+ if [ "$(relx_nodetool eval "whereis($1).")" != "undefined" ]
15
+ then
16
+ break
17
+ fi
18
+done
19
relx-3.26.0.tar.gz/priv/templates/builtin_hook_wait_for_vm_start
Added
9
1
2
+#!/bin/bash
3
+
4
+# loop until the VM starts responding to pings
5
+while ! $(relx_nodetool "ping">/dev/null)
6
+do
7
+ sleep 1
8
+done
9
relx-3.21.1.tar.gz/priv/templates/extended_bin -> relx-3.26.0.tar.gz/priv/templates/extended_bin
Changed
201
1
2
3
set -e
4
5
-SCRIPT=$(readlink $0 || true)
6
-if [ -z $SCRIPT ]; then
7
- SCRIPT=$0
8
-fi;
9
+# http://erlang.org/doc/man/run_erl.html
10
+# If defined, disables input and output flow control for the pty
11
+# opend by run_erl. Useful if you want to remove any risk of accidentally
12
+# blocking the flow control by using Ctrl-S (instead of Ctrl-D to detach),
13
+# which can result in blocking of the entire Beam process, and in the case
14
+# of running heart as supervisor even the heart process becomes blocked
15
+# when writing log message to terminal, leaving the heart process unable
16
+# to do its work.
17
+RUN_ERL_DISABLE_FLOWCNTRL=${RUN_ERL_DISABLE_FLOWCNTRL:-true}
18
+export $RUN_ERL_DISABLE_FLOWCNTRL
19
+
20
+if [ "$TERM" = "dumb" -o -z "$TERM" ]; then
21
+ export TERM=screen
22
+fi
23
+
24
+# OSX does not support readlink '-f' flag, work
25
+# around that
26
+case $OSTYPE in
27
+ darwin*)
28
+ SCRIPT=$(readlink $0 || true)
29
+ ;;
30
+ *)
31
+ SCRIPT=$(readlink -f $0 || true)
32
+ ;;
33
+esac
34
+[ -z $SCRIPT ] && SCRIPT=$0
35
SCRIPT_DIR="$(cd `dirname "$SCRIPT"` && pwd -P)"
36
RELEASE_ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd -P)"
37
-REL_NAME="{{ rel_name }}"
38
+# Make the value available to variable substitution calls below
39
+export REL_NAME="{{ rel_name }}"
40
REL_VSN="{{ rel_vsn }}"
41
ERTS_VSN="{{ erts_vsn }}"
42
CODE_LOADING_MODE="${CODE_LOADING_MODE:-embedded}"
43
REL_DIR="$RELEASE_ROOT_DIR/releases/$REL_VSN"
44
ERL_OPTS="{{ erl_opts }}"
45
RUNNER_LOG_DIR="${RUNNER_LOG_DIR:-$RELEASE_ROOT_DIR/log}"
46
+export ESCRIPT_NAME="${ESCRIPT_NAME-$SCRIPT}"
47
+
48
+# start/stop/install/upgrade pre/post hooks
49
+PRE_START_HOOKS="{{{ pre_start_hooks }}}"
50
+POST_START_HOOKS="{{{ post_start_hooks }}}"
51
+PRE_STOP_HOOKS="{{{ pre_stop_hooks }}}"
52
+POST_STOP_HOOKS="{{{ post_stop_hooks }}}"
53
+PRE_INSTALL_UPGRADE_HOOKS="{{{ pre_install_upgrade_hooks }}}"
54
+POST_INSTALL_UPGRADE_HOOKS="{{{ post_install_upgrade_hooks }}}"
55
+STATUS_HOOK="{{{ status_hook }}}"
56
+EXTENSIONS="{{{ extensions }}}"
57
+
58
+relx_usage() {
59
+ command="$1"
60
+
61
+ case "$command" in
62
+ unpack)
63
+ echo "Usage: $REL_NAME unpack [VERSION]"
64
+ echo "Unpacks a release package VERSION, it assumes that this"
65
+ echo "release package tarball has already been deployed at one"
66
+ echo "of the following locations:"
67
+ echo " releases/<relname>-<version>.tar.gz"
68
+ echo " releases/<version>/<relname>-<version>.tar.gz"
69
+ echo " releases/<version>/<relname>.tar.gz"
70
+ ;;
71
+ install)
72
+ echo "Usage: $REL_NAME install [VERSION]"
73
+ echo "Installs a release package VERSION, it assumes that this"
74
+ echo "release package tarball has already been deployed at one"
75
+ echo "of the following locations:"
76
+ echo " releases/<relname>-<version>.tar.gz"
77
+ echo " releases/<version>/<relname>-<version>.tar.gz"
78
+ echo " releases/<version>/<relname>.tar.gz"
79
+ echo ""
80
+ echo " --no-permanent Install release package VERSION but"
81
+ echo " don't make it permanent"
82
+ ;;
83
+ uninstall)
84
+ echo "Usage: $REL_NAME uninstall [VERSION]"
85
+ echo "Uninstalls a release VERSION, it will only accept"
86
+ echo "versions that are not currently in use"
87
+ ;;
88
+ upgrade)
89
+ echo "Usage: $REL_NAME upgrade [VERSION]"
90
+ echo "Upgrades the currently running release to VERSION, it assumes"
91
+ echo "that a release package tarball has already been deployed at one"
92
+ echo "of the following locations:"
93
+ echo " releases/<relname>-<version>.tar.gz"
94
+ echo " releases/<version>/<relname>-<version>.tar.gz"
95
+ echo " releases/<version>/<relname>.tar.gz"
96
+ echo ""
97
+ echo " --no-permanent Install release package VERSION but"
98
+ echo " don't make it permanent"
99
+ ;;
100
+ downgrade)
101
+ echo "Usage: $REL_NAME downgrade [VERSION]"
102
+ echo "Downgrades the currently running release to VERSION, it assumes"
103
+ echo "that a release package tarball has already been deployed at one"
104
+ echo "of the following locations:"
105
+ echo " releases/<relname>-<version>.tar.gz"
106
+ echo " releases/<version>/<relname>-<version>.tar.gz"
107
+ echo " releases/<version>/<relname>.tar.gz"
108
+ echo ""
109
+ echo " --no-permanent Install release package VERSION but"
110
+ echo " don't make it permanent"
111
+ ;;
112
+ status)
113
+ echo "Usage: $REL_NAME status"
114
+ echo "Obtains node status information."
115
+ ;;
116
+ *)
117
+ # check for extension
118
+ IS_EXTENSION=$(relx_is_extension $command)
119
+ if [ "$IS_EXTENSION" = "1" ]; then
120
+ EXTENSION_SCRIPT=$(relx_get_extension_script $command)
121
+ relx_run_extension $EXTENSION_SCRIPT help
122
+ else
123
+ EXTENSIONS=`echo $EXTENSIONS | sed -e 's/|undefined//g'`
124
+ echo "Usage: $REL_NAME {start|start_boot <file>|foreground|stop|restart|reboot|pid|ping|console|console_clean|console_boot <file>|attach|remote_console|upgrade|downgrade|install|uninstall|versions|escript|rpc|rpcterms|eval|status|$EXTENSIONS}"
125
+ fi
126
+ ;;
127
+ esac
128
+}
129
130
find_erts_dir() {
131
__erts_dir="$RELEASE_ROOT_DIR/erts-$ERTS_VSN"
132
133
else
134
__erl="$(which erl)"
135
code="io:format(\"~s\", [code:root_dir()]), halt()."
136
- __erl_root="$("$__erl" -noshell -eval "$code")"
137
+ __erl_root="$("$__erl" -boot no_dot_erlang -sasl errlog_type error -noshell -eval "$code")"
138
ERTS_DIR="$__erl_root/erts-$ERTS_VSN"
139
ROOTDIR="$__erl_root"
140
fi
141
142
143
relx_get_nodename() {
144
id="longname$(relx_gen_id)-${NAME}"
145
- "$BINDIR/erl" -boot start_clean -eval '[Host] = tl(string:tokens(atom_to_list(node()),"@")), io:format("~s~n", [Host]), halt()' -noshell ${NAME_TYPE} $id
146
+ "$BINDIR/erl" -boot start_clean \
147
+ -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \
148
+ -eval '[_,H]=re:split(atom_to_list(node()),"@",[unicode,{return,list}]), io:format("~s~n",[H]), halt()' \
149
+ -noshell ${NAME_TYPE} $id
150
}
151
152
# Connect to a remote node
153
154
# Setup remote shell command to control node
155
exec "$BINDIR/erl" "$NAME_TYPE" "$id" -remsh "$NAME" -boot start_clean \
156
-boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \
157
- -setcookie "$COOKIE" -hidden -kernel net_ticktime $TICKTIME
158
+ -setcookie "$COOKIE" -hidden -kernel net_ticktime $TICKTIME $VM_ARGS
159
}
160
161
# Generate a random id
162
163
relx_nodetool() {
164
command="$1"; shift
165
166
+ escript_emulator_args $ROOTDIR/bin/nodetool
167
+
168
"$ERTS_DIR/bin/escript" "$ROOTDIR/bin/nodetool" "$NAME_TYPE" "$NAME" \
169
-setcookie "$COOKIE" "$command" $@
170
}
171
172
"$ERTS_DIR/bin/escript" "$ROOTDIR/$scriptpath" $@
173
}
174
175
-# Output a start command for the last argument of run_erl
176
-relx_start_command() {
177
- printf "exec \"%s\" \"%s\"" "$RELEASE_ROOT_DIR/bin/$REL_NAME" \
178
- "$START_OPTION"
179
+relx_get_code_paths() {
180
+ code="{ok, [{release,_,_,Apps}]} = file:consult(\"$REL_DIR/$REL_NAME.rel\"),"\
181
+"lists:foreach(fun(A) ->"\
182
+" io:fwrite(\"$ROOTDIR/lib/~p-~s/ebin \", [element(1, A), element(2, A)]) "\
183
+"end, Apps),"\
184
+"halt()."
185
+
186
+ "$BINDIR/erl" -noshell -boot start_clean -eval "$code"
187
}
188
189
-# Use $CWD/vm.args if exists, otherwise releases/VSN/vm.args
190
-if [ -z "$VMARGS_PATH" ]; then
191
- if [ -f "$RELEASE_ROOT_DIR/vm.args" ]; then
192
- VMARGS_PATH="$RELEASE_ROOT_DIR/vm.args"
193
+make_out_file_path() {
194
+ # Use output directory provided in the RELX_OUT_FILE_PATH environment variable
195
+ # (default to the current location of vm.args and sys.config)
196
+ DIR=$(dirname $1)
197
+ [ -d "${RELX_OUT_FILE_PATH}" ] && DIR="${RELX_OUT_FILE_PATH}"
198
+ FILE=$(basename $1)
199
+ IN="${DIR}/${FILE}"
200
+
201
relx-3.21.1.tar.gz/priv/templates/extended_bin_windows -> relx-3.26.0.tar.gz/priv/templates/extended_bin_windows
Changed
184
1
2
:: * ping - check if the node is running
3
:: * console - start the Erlang release in a `werl` Windows shell
4
:: * attach - connect to a running node and open an interactive console
5
+:: * remote_console - alias for attach
6
:: * list - display a listing of installed Erlang services
7
:: * usage - display available commands
8
9
10
@for %%A in ("%script_dir%\..") do @(
11
set release_root_dir=%%~fA
12
)
13
-@set rel_dir=%release_root_dir%\releases\%rel_vsn%
14
+@set "rel_dir=%release_root_dir%\releases\%rel_vsn%"
15
16
@call :find_erts_dir
17
@call :find_sys_config
18
19
set node_name=%%J
20
)
21
22
+@for /f "delims=@ tokens=1-2" %%I in ("%node_name%") do @(
23
+ set node_name=%%I
24
+ set hostname=%%J
25
+)
26
+
27
+:: if no hostname is set, attempt to pick one from the env
28
+@if "" == "%hostname%" @(
29
+ if "-sname" == "%node_type%" (
30
+ if not "" == "%COMPUTERNAME%" (
31
+ set "hostname=%COMPUTERNAME%"
32
+ )
33
+ ) else (
34
+ if not "" == "%COMPUTERNAME%" (
35
+ if not "" == "%USERDNSDOMAIN%" (
36
+ set "hostname=%COMPUTERNAME%.%USERDNSDOMAIN%"
37
+ )
38
+ )
39
+ )
40
+)
41
+:: Add @ to hostname if not empty so that we can just concatenate values safely
42
+@if not "" == "%hostname%" @(
43
+ set "hostname=@%hostname%"
44
+)
45
+
46
:: Extract cookie from vm.args
47
@for /f "usebackq tokens=1-2" %%I in (`findstr /b \-setcookie "%vm_args%"`) do @(
48
set cookie=%%J
49
50
:: Write the erl.ini file to set up paths relative to this script
51
@call :write_ini
52
53
+:: Collect any additional VM args into erl_opts
54
+@setlocal EnableDelayedExpansion
55
+@for /f "usebackq tokens=1-2" %%I in (`findstr /r "^[^#]" "%vm_args%"`) do @(
56
+ if not "%%I" == "-name" (
57
+ if not "%%I" == "-sname" (
58
+ if not "%%I" == "-setcookie" (
59
+ set erl_opts=!erl_opts! %%I %%J
60
+ )
61
+ )
62
+ )
63
+)
64
+@endlocal && set erl_opts=%erl_opts%
65
+
66
:: If a start.boot file is not present, copy one from the named .boot file
67
@if not exist "%rel_dir%\start.boot" (
68
copy "%rel_dir%\%rel_name%.boot" "%rel_dir%\start.boot" >nul
69
70
@if "%1"=="ping" @goto ping
71
@if "%1"=="list" @goto list
72
@if "%1"=="attach" @goto attach
73
+@if "%1"=="remote_console" @goto attach
74
@if "%1"=="" @goto usage
75
@echo Unknown command: "%1"
76
77
78
79
:: Find the ERTS dir
80
:find_erts_dir
81
-@set possible_erts_dir=%release_root_dir%\erts-%erts_vsn%
82
+@set "possible_erts_dir=%release_root_dir%\erts-%erts_vsn%"
83
@if exist "%possible_erts_dir%" (
84
call :set_erts_dir_from_default
85
) else (
86
87
88
:: Set the ERTS dir from the passed in erts_vsn
89
:set_erts_dir_from_default
90
-@set erts_dir=%possible_erts_dir%
91
-@set rootdir=%release_root_dir%
92
+@set "erts_dir=%possible_erts_dir%"
93
+@set "rootdir=%release_root_dir%"
94
@goto :eof
95
96
:: Set the ERTS dir from erl
97
98
@for /f "delims=" %%i in ('where erl') do @(
99
set erl=%%i
100
)
101
-@set dir_cmd="%erl%" -noshell -eval "io:format(\"~s\", [filename:nativename(code:root_dir())])." -s init stop
102
+@set dir_cmd="%erl%" -boot no_dot_erlang -noshell -eval "io:format(\"~s\", [filename:nativename(code:root_dir())])." -s init stop
103
@for /f "delims=" %%i in ('%%dir_cmd%%') do @(
104
set erl_root=%%i
105
)
106
-@set erts_dir=%erl_root%\erts-%erts_vsn%
107
-@set rootdir=%erl_root%
108
+@set "erts_dir=%erl_root%\erts-%erts_vsn%"
109
+@set "rootdir=%erl_root%"
110
@goto :eof
111
112
:: Find the sys.config file
113
:find_sys_config
114
-@set possible_sys=%rel_dir%\sys.config
115
+@set "possible_sys=%rel_dir%\sys.config"
116
@if exist %possible_sys% (
117
set sys_config=-config "%possible_sys%"
118
)
119
120
:: set boot_script variable
121
:set_boot_script_var
122
@if exist "%rel_dir%\%rel_name%.boot" (
123
- set boot_script=%rel_dir%\%rel_name%
124
+ set "boot_script=%rel_dir%\%rel_name%"
125
) else (
126
- set boot_script=%rel_dir%\start
127
+ set "boot_script=%rel_dir%\start"
128
)
129
@goto :eof
130
131
132
133
:: Display usage information
134
:usage
135
-@echo usage: %~n0 ^(install^|uninstall^|start^|stop^|restart^|upgrade^|downgrade^|console^|ping^|list^|attach^)
136
+@echo usage: %~n0 ^(install^|uninstall^|start^|stop^|restart^|upgrade^|downgrade^|console^|ping^|list^|attach^|remote_console^)
137
@goto :eof
138
139
:: Install the release as a Windows service
140
141
set description=Erlang node %node_name% in %rootdir%
142
@if "" == "%2" (
143
:: Install the service
144
- %erlsrv% add %service_name% %node_type% "%node_name%" -c "%description%" ^
145
- -w "%rootdir%" -m "%start_erl%" -args "%args%" ^
146
- -stopaction "init:stop()."
147
+ %erlsrv% add %service_name% %node_type% "%node_name%" -c "%description%" -w "%rootdir%" -m "%start_erl%" -args "%args%" -stopaction "init:stop()."
148
) else (
149
:: relup and reldown
150
goto relup
151
152
:: Relup and reldown
153
:relup
154
@if "" == "%2" (
155
- echo Missing package argument
156
- echo Usage: %rel_name% %1 {package base name}
157
- echo NOTE {package base name} MUST NOT include the .tar.gz suffix
158
+ echo Missing version argument
159
+ echo Usage: %rel_name% %1 {version}
160
set ERRORLEVEL=1
161
exit /b %ERRORLEVEL%
162
)
163
-@%escript% "%rootdir%/bin/install_upgrade.escript" "%rel_name%" "%node_name%" "%cookie%" "%2"
164
+@%escript% "%rootdir%/bin/install_upgrade.escript" "install" "{'%rel_name%', \"%node_type%\", '%node_name%%hostname%', '%cookie%'}" "%2" "%3"
165
@goto :eof
166
167
:: Start a console
168
169
170
:: Ping the running node
171
:ping
172
-@%escript% %nodetool% ping %node_type% "%node_name%" -setcookie "%cookie%"
173
+@%escript% %nodetool% ping %node_type% "%node_name%%hostname%" -setcookie "%cookie%"
174
@goto :eof
175
176
:: List installed Erlang services
177
178
:attach
179
@set boot=-boot "%clean_boot_script%" -boot_var RELEASE_DIR "%release_root_dir%"
180
@start "%node_name% attach" %werl% %boot% ^
181
- -remsh %node_name% %node_type% console -setcookie %cookie%
182
+ -remsh %node_name%%hostname% %node_type% console -setcookie %cookie%
183
@goto :eof
184
relx-3.21.1.tar.gz/priv/templates/install_upgrade_escript -> relx-3.26.0.tar.gz/priv/templates/install_upgrade_escript
Changed
201
1
2
-define(TIMEOUT, 300000).
3
-define(INFO(Fmt,Args), io:format(Fmt,Args)).
4
5
-%% Unpack or upgrade to a new tar.gz release
6
-main(["unpack", RelName, NameTypeArg, NodeName, Cookie, VersionArg]) ->
7
+main([Command0, DistInfoStr | CommandArgs]) ->
8
+ %% convert the distribution info arguments string to an erlang term
9
+ {ok, Tokens, _} = erl_scan:string(DistInfoStr ++ "."),
10
+ {ok, DistInfo} = erl_parse:parse_term(Tokens),
11
+ %% convert arguments into a proplist
12
+ Opts = parse_arguments(CommandArgs),
13
+ %% invoke the command passed as argument
14
+ F = case Command0 of
15
+ "install" -> fun(A, B) -> install(A, B) end;
16
+ "unpack" -> fun(A, B) -> unpack(A, B) end;
17
+ "upgrade" -> fun(A, B) -> upgrade(A, B) end;
18
+ "downgrade" -> fun(A, B) -> downgrade(A, B) end;
19
+ "uninstall" -> fun(A, B) -> uninstall(A, B) end;
20
+ "versions" -> fun(A, B) -> versions(A, B) end
21
+ end,
22
+ F(DistInfo, Opts);
23
+main(Args) ->
24
+ ?INFO("unknown args: ~p\n", [Args]),
25
+ erlang:halt(1).
26
+
27
+unpack({RelName, NameTypeArg, NodeName, Cookie}, Opts) ->
28
TargetNode = start_distribution(NodeName, NameTypeArg, Cookie),
29
- WhichReleases = which_releases(TargetNode),
30
- Version = parse_version(VersionArg),
31
- case proplists:get_value(Version, WhichReleases) of
32
- undefined ->
33
- %% not installed, so unpack tarball:
34
- ?INFO("Release ~s not found, attempting to unpack releases/~s/~s.tar.gz~n",[Version,Version,RelName]),
35
- ReleasePackage = Version ++ "/" ++ RelName,
36
- case rpc:call(TargetNode, release_handler, unpack_release,
37
- [ReleasePackage], ?TIMEOUT) of
38
- {ok, Vsn} ->
39
- ?INFO("Unpacked successfully: ~p~n", [Vsn]);
40
- {error, UnpackReason} ->
41
- print_existing_versions(TargetNode),
42
- ?INFO("Unpack failed: ~p~n",[UnpackReason]),
43
- erlang:halt(2)
44
- end;
45
+ Version = proplists:get_value(version, Opts),
46
+ case unpack_release(RelName, TargetNode, Version) of
47
+ {ok, Vsn} ->
48
+ ?INFO("Unpacked successfully: ~p~n", [Vsn]);
49
old ->
50
%% no need to unpack, has been installed previously
51
- ?INFO("Release ~s is marked old, switching to it.~n",[Version]);
52
+ ?INFO("Release ~s is marked old.~n",[Version]);
53
unpacked ->
54
- ?INFO("Release ~s is already unpacked, now installing.~n",[Version]);
55
+ ?INFO("Release ~s is already unpacked.~n",[Version]);
56
current ->
57
- ?INFO("Release ~s is already installed and current. Making permanent.~n",[Version]);
58
+ ?INFO("Release ~s is already installed and current.~n",[Version]);
59
permanent ->
60
- ?INFO("Release ~s is already installed, and set permanent.~n",[Version])
61
+ ?INFO("Release ~s is already installed and set permanent.~n",[Version]);
62
+ {error, Reason} ->
63
+ ?INFO("Unpack failed: ~p~n",[Reason]),
64
+ print_existing_versions(TargetNode),
65
+ erlang:halt(2)
66
end;
67
-main(["install", RelName, NameTypeArg, NodeName, Cookie, VersionArg]) ->
68
+unpack(_, Args) ->
69
+ ?INFO("unpack: unknown args ~p\n", [Args]).
70
+
71
+install({RelName, NameTypeArg, NodeName, Cookie}, Opts) ->
72
TargetNode = start_distribution(NodeName, NameTypeArg, Cookie),
73
- WhichReleases = which_releases(TargetNode),
74
- Version = parse_version(VersionArg),
75
- case proplists:get_value(Version, WhichReleases) of
76
- undefined ->
77
- %% not installed, so unpack tarball:
78
- ?INFO("Release ~s not found, attempting to unpack releases/~s/~s.tar.gz~n",[Version,Version,RelName]),
79
- ReleasePackage = Version ++ "/" ++ RelName,
80
- case rpc:call(TargetNode, release_handler, unpack_release,
81
- [ReleasePackage], ?TIMEOUT) of
82
- {ok, Vsn} ->
83
- ?INFO("Unpacked successfully: ~p~n", [Vsn]),
84
- install_and_permafy(TargetNode, RelName, Vsn);
85
- {error, UnpackReason} ->
86
- print_existing_versions(TargetNode),
87
- ?INFO("Unpack failed: ~p~n",[UnpackReason]),
88
- erlang:halt(2)
89
- end;
90
+ Version = proplists:get_value(version, Opts),
91
+ case unpack_release(RelName, TargetNode, Version) of
92
+ {ok, Vsn} ->
93
+ ?INFO("Unpacked successfully: ~p~n", [Vsn]),
94
+ check_and_install(TargetNode, Vsn),
95
+ maybe_permafy(TargetNode, RelName, Vsn, Opts);
96
old ->
97
%% no need to unpack, has been installed previously
98
?INFO("Release ~s is marked old, switching to it.~n",[Version]),
99
- install_and_permafy(TargetNode, RelName, Version);
100
+ check_and_install(TargetNode, Version),
101
+ maybe_permafy(TargetNode, RelName, Version, Opts);
102
unpacked ->
103
?INFO("Release ~s is already unpacked, now installing.~n",[Version]),
104
- install_and_permafy(TargetNode, RelName, Version);
105
- current -> %% installed and in-use, just needs to be permanent
106
- ?INFO("Release ~s is already installed and current. Making permanent.~n",[Version]),
107
- permafy(TargetNode, RelName, Version);
108
+ check_and_install(TargetNode, Version),
109
+ maybe_permafy(TargetNode, RelName, Version, Opts);
110
+ current ->
111
+ case proplists:get_value(permanent, Opts, true) of
112
+ true ->
113
+ ?INFO("Release ~s is already installed and current, making permanent.~n",
114
+ [Version]),
115
+ permafy(TargetNode, RelName, Version);
116
+ false ->
117
+ ?INFO("Release ~s is already installed and current.~n",
118
+ [Version])
119
+ end;
120
permanent ->
121
- ?INFO("Release ~s is already installed, and set permanent.~n",[Version])
122
+ %% this release is marked permanent, however it might not the
123
+ %% one currently running
124
+ case current_release_version(TargetNode) of
125
+ Version ->
126
+ ?INFO("Release ~s is already installed, running and set permanent.~n",
127
+ [Version]);
128
+ CurrentVersion ->
129
+ ?INFO("Release ~s is the currently running version.~n",
130
+ [CurrentVersion]),
131
+ check_and_install(TargetNode, Version),
132
+ maybe_permafy(TargetNode, RelName, Version, Opts)
133
+ end;
134
+ {error, Reason} ->
135
+ ?INFO("Unpack failed: ~p~n",[Reason]),
136
+ print_existing_versions(TargetNode),
137
+ erlang:halt(2)
138
end;
139
-main(_) ->
140
- erlang:halt(1).
141
+install(_, Args) ->
142
+ ?INFO("install: unknown args ~p\n", [Args]).
143
+
144
+upgrade(DistInfo, Args) ->
145
+ install(DistInfo, Args).
146
+
147
+downgrade(DistInfo, Args) ->
148
+ install(DistInfo, Args).
149
+
150
+uninstall({_RelName, NameTypeArg, NodeName, Cookie}, Opts) ->
151
+ TargetNode = start_distribution(NodeName, NameTypeArg, Cookie),
152
+ WhichReleases = which_releases(TargetNode),
153
+ Version = proplists:get_value(version, Opts),
154
+ case proplists:get_value(Version, WhichReleases) of
155
+ undefined ->
156
+ ?INFO("Release ~s is already uninstalled.~n", [Version]);
157
+ old ->
158
+ ?INFO("Release ~s is marked old, uninstalling it.~n", [Version]),
159
+ remove_release(TargetNode, Version);
160
+ unpacked ->
161
+ ?INFO("Release ~s is marked unpacked, uninstalling it~n",
162
+ [Version]),
163
+ remove_release(TargetNode, Version);
164
+ current ->
165
+ ?INFO("Uninstall failed: Release ~s is marked current.~n", [Version]),
166
+ erlang:halt(2);
167
+ permanent ->
168
+ ?INFO("Uninstall failed: Release ~s is running.~n", [Version]),
169
+ erlang:halt(2)
170
+ end;
171
+uninstall(_, Args) ->
172
+ ?INFO("uninstall: unknown args ~p\n", [Args]).
173
+
174
+versions({_RelName, NameTypeArg, NodeName, Cookie}, []) ->
175
+ TargetNode = start_distribution(NodeName, NameTypeArg, Cookie),
176
+ print_existing_versions(TargetNode).
177
+
178
+parse_arguments(Args) ->
179
+ parse_arguments(Args, []).
180
+
181
+parse_arguments([], Acc) -> Acc;
182
+parse_arguments(["--no-permanent"|Rest], Acc) ->
183
+ parse_arguments(Rest, [{permanent, false}] ++ Acc);
184
+parse_arguments([VersionStr|Rest], Acc) ->
185
+ Version = parse_version(VersionStr),
186
+ parse_arguments(Rest, [{version, Version}] ++ Acc).
187
+
188
+unpack_release(RelName, TargetNode, Version) ->
189
+ WhichReleases = which_releases(TargetNode),
190
+ case proplists:get_value(Version, WhichReleases) of
191
+ undefined ->
192
+ %% not installed, so unpack tarball:
193
+ %% look for a release package with the intended version in the following order:
194
+ %% releases/<relname>-<version>.tar.gz
195
+ %% releases/<version>/<relname>-<version>.tar.gz
196
+ %% releases/<version>/<relname>.tar.gz
197
+ case find_and_link_release_package(Version, RelName) of
198
+ {_, undefined} ->
199
+ {error, release_package_not_found};
200
+ {ReleasePackage, ReleasePackageLink} ->
201
relx-3.21.1.tar.gz/priv/templates/nodetool -> relx-3.26.0.tar.gz/priv/templates/nodetool
Changed
44
1
2
% spaces, so this converts all of that to a single string to parse
3
String = binary_to_list(
4
list_to_binary(
5
- string:join(ListOfArgs," ")
6
+ join(ListOfArgs," ")
7
)
8
),
9
10
11
12
13
nodename(Name) ->
14
- case string:tokens(Name, "@") of
15
+ case re:split(Name, "@", [{return, list}, unicode]) of
16
[_Node, _Host] ->
17
list_to_atom(Name);
18
[Node] ->
19
- [_, Host] = string:tokens(atom_to_list(node()), "@"),
20
+ [_, Host] = re:split(atom_to_list(node()), "@", [{return, list}, unicode]),
21
list_to_atom(lists:concat([Node, "@", Host]))
22
end.
23
24
append_node_suffix(Name, Suffix) ->
25
- case string:tokens(Name, "@") of
26
+ case re:split(Name, "@", [{return, list}, unicode]) of
27
[Node, Host] ->
28
list_to_atom(lists:concat([Node, Suffix, os:getpid(), "@", Host]));
29
[Node] ->
30
31
{more, Cont1} ->
32
consult(Cont1, eof, Acc)
33
end.
34
+
35
+%% string:join/2 copy; string:join/2 is getting obsoleted
36
+%% and replaced by lists:join/2, but lists:join/2 is too new
37
+%% for version support (only appeared in 19.0) so it cannot be
38
+%% used. Instead we just adopt join/2 locally and hope it works
39
+%% for most unicode use cases anyway.
40
+join([], Sep) when is_list(Sep) ->
41
+ [];
42
+join([H|T], Sep) ->
43
+ H ++ lists:append([Sep ++ X || X <- T]).
44
relx-3.21.1.tar.gz/priv/templates/vm_args -> relx-3.26.0.tar.gz/priv/templates/vm_args
Changed
16
1
2
3
## Tweak GC to run more often
4
##-env ERL_FULLSWEEP_AFTER 10
5
+
6
+# +B [c | d | i]
7
+# Option c makes Ctrl-C interrupt the current shell instead of invoking the emulator break
8
+# handler. Option d (same as specifying +B without an extra option) disables the break handler. # Option i makes the emulator ignore any break signal.
9
+# If option c is used with oldshell on Unix, Ctrl-C will restart the shell process rather than
10
+# interrupt it.
11
+# Disable the emulator break handler
12
+# it easy to accidentally type ctrl-c when trying
13
+# to reach for ctrl-d. ctrl-c on a live node can
14
+# have very undesirable results
15
+##+Bi
16
relx-3.21.1.tar.gz/rebar.config -> relx-3.26.0.tar.gz/rebar.config
Changed
67
1
2
%% -*- mode: Erlang; fill-column: 80; comment-column: 75; -*-
3
%% Dependencies ================================================================
4
-{deps, [{erlware_commons, "0.21.0"},
5
- {providers, "1.6.0"},
6
- {getopt, "0.8.2"},
7
- {cf, "0.2.1"},
8
+{deps, [{erlware_commons, "1.2.0"},
9
+ {providers, "1.7.0"},
10
+ {getopt, "1.0.1"},
11
+ {cf, "0.2.2"},
12
{bbmustache, "1.0.4"}
13
]}.
14
15
16
[{platform_define, "^[0-9]+", namespaced_types},
17
{platform_define, "^1[8|9]", rand_module},
18
{platform_define, "^2", rand_module},
19
- no_debug_info,
20
+ {platform_define, "^2", unicode_str},
21
warnings_as_errors,
22
inline]}.
23
24
25
26
{profiles, [{dev, [{plugins, [rebar3_neotoma_plugin]}]},
27
28
- {test, [{erl_opts, [debug_info]}]},
29
+ {test, [{erl_opts, [nowarn_export_all, debug_info]}]},
30
31
{dialyze, [{overrides, [{add, erlware_commons, [{erl_opts, [debug_info]}]},
32
{add, providers, [{erl_opts, [debug_info]}]},
33
{add, getopt, [{erl_opts, [debug_info]}]},
34
{add, bbmustache, [{erl_opts, [debug_info]}]},
35
{add, cf, [{erl_opts, [debug_info]}]}]},
36
- {erl_opts, [debug_info]}]}
37
+ {erl_opts, [debug_info]}]},
38
+ {escript, [
39
+ {overrides, [{add, erlware_commons, [{erl_opts, [no_debug_info]}]},
40
+ {add, providers, [{erl_opts, [no_debug_info]}]},
41
+ {add, getopt, [{erl_opts, [no_debug_info]}]},
42
+ {add, bbmustache, [{erl_opts, [no_debug_info]}]},
43
+ {add, cf, [{erl_opts, [no_debug_info]}]}]},
44
+ {erl_opts, [no_debug_info]}
45
+ ]}
46
]}.
47
48
{overrides, [{override, erlware_commons, [
49
{erl_opts, [{platform_define, "^[0-9]+", namespaced_types},
50
{platform_define, "^R1[4|5]", deprecated_crypto},
51
{platform_define, "^((1[8|9])|2)", rand_module},
52
+ {platform_define, "^2", unicode_str},
53
+ {platform_define, "^(R|1|20)", fun_stacktrace},
54
no_debug_info,
55
warnings_as_errors
56
]},
57
58
{override, bbmustache, [
59
{erl_opts, [no_debug_info]},
60
{deps, []}, {plugins, []}]},
61
- {override, getopt, [{erl_opts, [no_debug_info]}]},
62
+ {override, getopt, [{erl_opts, [no_debug_info,
63
+ {platform_define, "^2", unicode_str}]}]},
64
{override, providers, [{erl_opts, [no_debug_info]}]}
65
]}.
66
67
relx-3.21.1.tar.gz/rebar.lock -> relx-3.26.0.tar.gz/rebar.lock
Changed
20
1
2
+{"1.1.0",
3
[{<<"bbmustache">>,{pkg,<<"bbmustache">>,<<"1.0.4">>},0},
4
- {<<"cf">>,{pkg,<<"cf">>,<<"0.2.1">>},0},
5
- {<<"erlware_commons">>,{pkg,<<"erlware_commons">>,<<"0.21.0">>},0},
6
- {<<"getopt">>,{pkg,<<"getopt">>,<<"0.8.2">>},0},
7
- {<<"providers">>,{pkg,<<"providers">>,<<"1.6.0">>},0}].
8
+ {<<"cf">>,{pkg,<<"cf">>,<<"0.2.2">>},0},
9
+ {<<"erlware_commons">>,{pkg,<<"erlware_commons">>,<<"1.2.0">>},0},
10
+ {<<"getopt">>,{pkg,<<"getopt">>,<<"1.0.1">>},0},
11
+ {<<"providers">>,{pkg,<<"providers">>,<<"1.7.0">>},0}]}.
12
+[
13
+{pkg_hash,[
14
+ {<<"bbmustache">>, <<"7BA94F971C5AFD7B6617918A4BB74705E36CAB36EB84B19B6A1B7EE06427AA38">>},
15
+ {<<"cf">>, <<"7F2913FFF90ABCABD0F489896CFEB0B0674F6C8DF6C10B17A83175448029896C">>},
16
+ {<<"erlware_commons">>, <<"2BAB99CF88941145767A502F1209886F1F0D31695EEF21978A30F15E645721E0">>},
17
+ {<<"getopt">>, <<"C73A9FA687B217F2FF79F68A3B637711BB1936E712B521D8CE466B29CBF7808A">>},
18
+ {<<"providers">>, <<"BBF730563914328EC2511D205E6477A94831DB7297DE313B3872A2B26C562EAB">>}]}
19
+].
20
relx-3.21.1.tar.gz/src/rlx_app_discovery.erl -> relx-3.26.0.tar.gz/src/rlx_app_discovery.erl
Changed
33
1
2
ec_cmd_log:info(rlx_state:log(State),
3
fun() ->
4
["Resolving OTP Applications from directories:\n",
5
- string:join([[rlx_util:indent(2), LibDir] || LibDir <- LibDirs], "\n")]
6
+ rlx_string:join([[rlx_util:indent(2), LibDir] || LibDir <- LibDirs], "\n")]
7
end),
8
resolve_app_metadata(State, LibDirs).
9
10
11
-spec get_deps(binary(), atom(), string(), proplists:proplist()) ->
12
{ok, rlx_app_info:t()} | {error, Reason::term()}.
13
get_deps(AppDir, AppName, AppVsn, AppDetail) ->
14
- ActiveApps = proplists:get_value(applications, AppDetail, []),
15
+ %% ensure that at least stdlib and kernel are defined as application deps
16
+ ActiveApps = ensure_stdlib_kernel(AppName,
17
+ proplists:get_value(applications, AppDetail, [])),
18
LibraryApps = proplists:get_value(included_applications, AppDetail, []),
19
rlx_app_info:new(AppName, AppVsn, AppDir, ActiveApps, LibraryApps).
20
21
+-spec ensure_stdlib_kernel(AppName :: atom(),
22
+ Apps :: list(atom())) -> list(atom()).
23
+ensure_stdlib_kernel(kernel, Deps) -> Deps;
24
+ensure_stdlib_kernel(stdlib, Deps) -> Deps;
25
+ensure_stdlib_kernel(_AppName, []) ->
26
+ %% minimum required deps are kernel and stdlib
27
+ [kernel, stdlib];
28
+ensure_stdlib_kernel(_AppName, Deps) -> Deps.
29
+
30
%%%===================================================================
31
%%% Test Functions
32
%%%===================================================================
33
relx-3.21.1.tar.gz/src/rlx_cmd_args.erl -> relx-3.26.0.tar.gz/src/rlx_cmd_args.erl
Changed
11
1
2
Erts when is_list(Erts) ->
3
{include_erts, Erts}
4
end;
5
+create(warnings_as_errors, Opts) ->
6
+ WarningsAsErrors = proplists:get_value(warnings_as_errors, Opts, false),
7
+ {warnings_as_errors, WarningsAsErrors};
8
create(_, _) ->
9
[].
10
11
relx-3.21.1.tar.gz/src/rlx_config.erl -> relx-3.26.0.tar.gz/src/rlx_config.erl
Changed
45
1
2
{ok, rlx_state:skip_apps(State0, SkipApps0)};
3
load_terms({exclude_apps, ExcludeApps0}, {ok, State0}) ->
4
{ok, rlx_state:exclude_apps(State0, ExcludeApps0)};
5
+load_terms({exclude_modules, ExcludeModules0}, {ok, State0}) ->
6
+ {ok, rlx_state:exclude_modules(State0, ExcludeModules0)};
7
load_terms({debug_info, DebugInfo}, {ok, State0}) ->
8
{ok, rlx_state:debug_info(State0, DebugInfo)};
9
load_terms({overrides, Overrides0}, {ok, State0}) ->
10
11
{ok, rlx_state:vm_args(State, false)};
12
load_terms({vm_args, VmArgs}, {ok, State}) ->
13
{ok, rlx_state:vm_args(State, filename:absname(VmArgs))};
14
+load_terms({vm_args_src, VmArgs}, {ok, State}) ->
15
+ {ok, rlx_state:vm_args_src(State, filename:absname(VmArgs))};
16
load_terms({sys_config, false}, {ok, State}) ->
17
{ok, rlx_state:sys_config(State, false)};
18
load_terms({sys_config, SysConfig}, {ok, State}) ->
19
{ok, rlx_state:sys_config(State, filename:absname(SysConfig))};
20
+load_terms({sys_config_src, SysConfigSrc}, {ok, State}) ->
21
+ {ok, rlx_state:sys_config_src(State, filename:absname(SysConfigSrc))};
22
load_terms({root_dir, Root}, {ok, State}) ->
23
{ok, rlx_state:root_dir(State, filename:absname(Root))};
24
load_terms({output_dir, OutputDir}, {ok, State}) ->
25
26
NewOverlayVars0 = list_of_overlay_vars_files(OverlayVars),
27
NewOverlayVars1 = CurrentOverlayVars ++ NewOverlayVars0,
28
{ok, rlx_state:put(State, overlay_vars, NewOverlayVars1)};
29
+load_terms({warnings_as_errors, WarningsAsErrors}, {ok, State}) ->
30
+ {ok, rlx_state:warnings_as_errors(State, WarningsAsErrors)};
31
load_terms({Name, Value}, {ok, State})
32
when erlang:is_atom(Name) ->
33
{ok, rlx_state:put(State, Name, Value)};
34
35
parse_vsn(Vsn) when Vsn =:= semver ; Vsn =:= "semver" ->
36
{ok, V} = ec_git_vsn:vsn(ec_git_vsn:new()),
37
V;
38
-parse_vsn({semver, _}) ->
39
- {ok, V} = ec_git_vsn:vsn(ec_git_vsn:new()),
40
+parse_vsn({semver, Data}) ->
41
+ {ok, V} = ec_git_vsn:vsn(Data),
42
V;
43
parse_vsn({cmd, Command}) ->
44
V = os:cmd(Command),
45
relx-3.21.1.tar.gz/src/rlx_depsolver.erl -> relx-3.26.0.tar.gz/src/rlx_depsolver.erl
Changed
29
1
2
%% type
3
%%============================================================================
4
-ifdef(namespaced_types).
5
--type dep_graph() :: gb_tree:tree().
6
+-type dep_graph() :: gb_trees:tree().
7
-else.
8
-type dep_graph() :: gb_tree().
9
-endif.
10
11
{value, {PkgName, Constraints0}} ->
12
Constraints0
13
end,
14
- [{PkgName, [{PkgConstraint, {SrcPkg, SrcVsn}} | Constraints1]}
15
- | lists:keydelete(PkgName, 1, PkgsConstraints)].
16
+ lists:keydelete(PkgName, 1, PkgsConstraints)++[{PkgName, [{PkgConstraint, {SrcPkg, SrcVsn}} | Constraints1]}].
17
18
%% @doc
19
%% Extend the currently active constraints correctly for the given constraints.
20
21
F = fun (Vsn) ->
22
Deps = get_dep_constraints(DepGraph, Pkg, Vsn),
23
UConstraints = extend_constraints(Pkg, Vsn, Constraints, Deps),
24
- DepPkgs =[dep_pkg(Dep) || Dep <- Deps],
25
+ DepPkgs = [dep_pkg(Dep) || Dep <- Deps],
26
NewVisited = [{Pkg, Vsn} | Visited],
27
Res = all_pkgs(DepGraph, NewVisited, DepPkgs ++ OtherPkgs, UConstraints, PathInd),
28
Res
29
relx-3.21.1.tar.gz/src/rlx_goal.erl -> relx-3.26.0.tar.gz/src/rlx_goal.erl
Changed
10
1
2
-define(p_seq,true).
3
-define(p_string,true).
4
5
-
6
--compile(export_all).
7
-spec file(file:name()) -> any().
8
file(Filename) -> case file:read_file(Filename) of {ok,Bin} -> parse(Bin); Err -> Err end.
9
10
relx-3.21.1.tar.gz/src/rlx_prv_app_discover.erl -> relx-3.26.0.tar.gz/src/rlx_prv_app_discover.erl
Changed
10
1
2
add_environment_lib_dir(_State) ->
3
case os:getenv("ERL_LIBS") of
4
false -> [];
5
- Libs -> [erlang:iolist_to_binary(L) || L <- string:tokens(Libs, ":")]
6
+ Libs -> [erlang:iolist_to_binary(L) || L <- rlx_string:lexemes(Libs, ":")]
7
end.
8
9
%% Order matters so this slow dedup needs to be used
10
relx-3.21.1.tar.gz/src/rlx_prv_assembler.erl -> relx-3.26.0.tar.gz/src/rlx_prv_assembler.erl
Changed
201
1
2
format_error({ec_file_error, AppDir, TargetDir, E}) ->
3
io_lib:format("Unable to copy OTP App from ~s to ~s due to ~p",
4
[AppDir, TargetDir, E]);
5
+format_error({vmargs_does_not_exist, Path}) ->
6
+ io_lib:format("The vm.args file specified for this release (~s) does not exist!",
7
+ [Path]);
8
+format_error({vmargs_src_does_not_exist, Path}) ->
9
+ io_lib:format("The vm.args.src file specified for this release (~s) does not exist!",
10
+ [Path]);
11
format_error({config_does_not_exist, Path}) ->
12
- io_lib:format("The config file specified for this release (~s) does not exist!",
13
+ io_lib:format("The sys.config file specified for this release (~s) does not exist!",
14
+ [Path]);
15
+format_error({config_src_does_not_exist, Path}) ->
16
+ io_lib:format("The sys.config.src file specified for this release (~s) does not exist!",
17
[Path]);
18
format_error({sys_config_parse_error, ConfigPath, Reason}) ->
19
io_lib:format("The config file (~s) specified for this release could not be opened or parsed: ~s",
20
21
io_lib:format("Unable to symlink directory ~s to ~s because \n~s~s",
22
[AppDir, TargetDir, rlx_util:indent(2),
23
file:format_error(Reason)]);
24
-format_error(start_clean_script_generation_error) ->
25
+format_error(boot_script_generation_error) ->
26
"Unknown internal release error generating start_clean.boot";
27
-format_error({start_clean_script_generation_warning, Module, Warnings}) ->
28
+format_error({boot_script_generation_warning, Module, Warnings}) ->
29
["Warnings generating start_clean.boot \s",
30
rlx_util:indent(2), Module:format_warning(Warnings)];
31
-format_error({start_clean_script_generation_error, Module, Errors}) ->
32
+format_error({boot_script_generation_error, Module, Errors}) ->
33
["Errors generating start_clean.boot \n",
34
rlx_util:indent(2), Module:format_error(Errors)];
35
format_error({strip_release, Reason}) ->
36
io_lib:format("Stripping debug info from release beam files failed becuase ~s",
37
- [beam_lib:format_error(Reason)]).
38
+ [beam_lib:format_error(Reason)]);
39
+format_error({rewrite_app_file, AppFile, Error}) ->
40
+ io_lib:format("Unable to rewrite .app file ~s due to ~p",
41
+ [AppFile, Error]).
42
43
%%%===================================================================
44
%%% Internal Functions
45
46
false
47
end,
48
lists:flatten(ec_plists:map(fun(App) ->
49
- copy_app(LibDir, App, IncludeSrc, IncludeErts)
50
+ copy_app(State, LibDir, App, IncludeSrc, IncludeErts)
51
end, Apps))),
52
case Result of
53
[E | _] ->
54
55
Apps
56
end.
57
58
-copy_app(LibDir, App, IncludeSrc, IncludeErts) ->
59
+copy_app(State, LibDir, App, IncludeSrc, IncludeErts) ->
60
AppName = erlang:atom_to_list(rlx_app_info:name(App)),
61
AppVsn = rlx_app_info:original_vsn(App),
62
AppDir = rlx_app_info:dir(App),
63
64
true ->
65
[];
66
false ->
67
- copy_app_(App, AppDir, TargetDir, IncludeSrc)
68
+ copy_app_(State, App, AppDir, TargetDir, IncludeSrc)
69
end;
70
_ ->
71
- copy_app_(App, AppDir, TargetDir, IncludeSrc)
72
+ copy_app_(State, App, AppDir, TargetDir, IncludeSrc)
73
end
74
end.
75
76
is_erts_lib(Dir) ->
77
lists:prefix(filename:split(list_to_binary(code:lib_dir())), filename:split(Dir)).
78
79
-copy_app_(App, AppDir, TargetDir, IncludeSrc) ->
80
+copy_app_(State, App, AppDir, TargetDir, IncludeSrc) ->
81
remove_symlink_or_directory(TargetDir),
82
case rlx_app_info:link(App) of
83
true ->
84
link_directory(AppDir, TargetDir),
85
- rewrite_app_file(App, AppDir);
86
+ rewrite_app_file(State, App, AppDir);
87
false ->
88
- copy_directory(AppDir, TargetDir, IncludeSrc),
89
- rewrite_app_file(App, TargetDir)
90
+ copy_directory(State, App, AppDir, TargetDir, IncludeSrc),
91
+ rewrite_app_file(State, App, TargetDir)
92
end.
93
94
%% If excluded apps exist in this App's applications list we must write a new .app
95
-rewrite_app_file(App, TargetDir) ->
96
+rewrite_app_file(State, App, TargetDir) ->
97
Name = rlx_app_info:name(App),
98
ActiveDeps = rlx_app_info:active_deps(App),
99
IncludedDeps = rlx_app_info:library_deps(App),
100
AppFile = filename:join([TargetDir, "ebin", ec_cnv:to_list(Name) ++ ".app"]),
101
- {ok, [{application, AppName, AppData}]} = file:consult(AppFile),
102
- OldActiveDeps = proplists:get_value(applications, AppData, []),
103
- OldIncludedDeps = proplists:get_value(included_applications, AppData, []),
104
-
105
- case {OldActiveDeps, OldIncludedDeps} of
106
- {ActiveDeps, IncludedDeps} ->
107
- ok;
108
- _ ->
109
- AppData1 = lists:keyreplace(applications
110
- ,1
111
- ,AppData
112
- ,{applications, ActiveDeps}),
113
- AppData2 = lists:keyreplace(included_applications
114
- ,1
115
- ,AppData1
116
- ,{included_applications, IncludedDeps}),
117
- Spec = io_lib:format("~p.\n", [{application, AppName, AppData2}]),
118
- write_file_if_contents_differ(AppFile, Spec)
119
+ {ok, [{application, AppName, AppData0}]} = file:consult(AppFile),
120
+ OldActiveDeps = proplists:get_value(applications, AppData0, []),
121
+ OldIncludedDeps = proplists:get_value(included_applications, AppData0, []),
122
+ OldModules = proplists:get_value(modules, AppData0, []),
123
+ ExcludedModules = proplists:get_value(Name,
124
+ rlx_state:exclude_modules(State), []),
125
+
126
+ %% maybe replace excluded apps
127
+ AppData2 =
128
+ case {OldActiveDeps, OldIncludedDeps} of
129
+ {ActiveDeps, IncludedDeps} ->
130
+ AppData0;
131
+ _ ->
132
+ AppData1 = lists:keyreplace(applications
133
+ ,1
134
+ ,AppData0
135
+ ,{applications, ActiveDeps}),
136
+ lists:keyreplace(included_applications
137
+ ,1
138
+ ,AppData1
139
+ ,{included_applications, IncludedDeps})
140
+ end,
141
+ %% maybe replace excluded modules
142
+ AppData3 =
143
+ case ExcludedModules of
144
+ [] -> AppData2;
145
+ _ ->
146
+ lists:keyreplace(modules
147
+ ,1
148
+ ,AppData2
149
+ ,{modules, OldModules -- ExcludedModules})
150
+ end,
151
+ Spec = [{application, AppName, AppData3}],
152
+ case write_file_if_contents_differ(AppFile, Spec) of
153
+ ok -> ok;
154
+ Error -> ?RLX_ERROR({rewrite_app_file, AppFile, Error})
155
end.
156
157
-write_file_if_contents_differ(Filename, Bytes) ->
158
- ToWrite = iolist_to_binary(Bytes),
159
- case file:read_file(Filename) of
160
- {ok, ToWrite} ->
161
+write_file_if_contents_differ(Filename, Spec) ->
162
+ ToWrite = io_lib:format("~p.\n", Spec),
163
+ case file:consult(Filename) of
164
+ {ok, Spec} ->
165
ok;
166
{ok, _} ->
167
file:write_file(Filename, ToWrite);
168
169
ok
170
end.
171
172
-copy_directory(AppDir, TargetDir, IncludeSrc) ->
173
- [copy_dir(AppDir, TargetDir, SubDir)
174
+copy_directory(State, App, AppDir, TargetDir, IncludeSrc) ->
175
+ [copy_dir(State, App, AppDir, TargetDir, SubDir)
176
|| SubDir <- ["ebin",
177
"include",
178
"priv",
179
180
[]
181
end]].
182
183
-copy_dir(AppDir, TargetDir, SubDir) ->
184
+copy_dir(State, App, AppDir, TargetDir, SubDir) ->
185
SubSource = filename:join(AppDir, SubDir),
186
SubTarget = filename:join(TargetDir, SubDir),
187
case ec_file:is_dir(SubSource) of
188
true ->
189
ok = rlx_util:mkdir_p(SubTarget),
190
- case ec_file:copy(SubSource, SubTarget, [recursive]) of
191
+ %% get a list of the modules to be excluded from this app
192
+ AppName = rlx_app_info:name(App),
193
+ ExcludedModules = proplists:get_value(AppName, rlx_state:exclude_modules(State),
194
+ []),
195
+ ExcludedFiles = [filename:join([binary_to_list(SubSource),
196
+ atom_to_list(M) ++ ".beam"]) ||
197
+ M <- ExcludedModules],
198
+ case copy_dir(SubSource, SubTarget, ExcludedFiles) of
199
{error, E} ->
200
?RLX_ERROR({ec_file_error, AppDir, SubTarget, E});
201
relx-3.21.1.tar.gz/src/rlx_prv_overlay.erl -> relx-3.26.0.tar.gz/src/rlx_prv_overlay.erl
Changed
70
1
2
-spec generate_release_vars(rlx_release:t()) -> proplists:proplist().
3
generate_release_vars(Release) ->
4
[{erts_vsn, rlx_release:erts(Release)},
5
+ {erts_dir, code:root_dir()},
6
{release_erts_version, rlx_release:erts(Release)},
7
{release_name, rlx_release:name(Release)},
8
{rel_vsn, rlx_release:vsn(Release)},
9
10
-spec do_individual_overlay(rlx_state:t(), list(), proplists:proplist(),
11
OverlayDirective::term()) ->
12
{ok, rlx_state:t()} | relx:error().
13
+do_individual_overlay(State, _Files, OverlayVars, {chmod, Mode, Path}) ->
14
+ % mode can be specified directly as an integer value, or if it is
15
+ % not an integer we assume it's a template, which we render and convert
16
+ % blindly to an integer. So this will crash with an exception if for
17
+ % some reason something other than an integer is used
18
+ NewMode =
19
+ case is_integer(Mode) of
20
+ true -> Mode;
21
+ false -> erlang:list_to_integer(erlang:binary_to_list(render_string (OverlayVars, Mode)))
22
+ end,
23
+
24
+ Root = rlx_state:output_dir(State),
25
+ file_render_do(OverlayVars, Path,
26
+ fun(NewPath) ->
27
+ Absolute = absolutize(State,
28
+ filename:join(Root,erlang:iolist_to_binary (NewPath))),
29
+ case file:change_mode(Absolute, NewMode) of
30
+ {error, Error} ->
31
+ ?RLX_ERROR({unable_to_chmod, NewMode, NewPath, Error});
32
+ ok -> ok
33
+ end
34
+ end);
35
do_individual_overlay(State, _Files, OverlayVars, {mkdir, Dir}) ->
36
case rlx_util:render(erlang:iolist_to_binary(Dir), OverlayVars) of
37
{ok, IoList} ->
38
39
erlang:iolist_to_binary(filename:join(ToFile1,
40
filename:basename(FromFile1)))
41
end,
42
- case ec_file:copy(FromFile1, ToFile2, [recursive]) of
43
+ case ec_file:copy(FromFile1, ToFile2, [recursive, {file_info, [mode, time]}]) of
44
ok ->
45
- {ok, FileInfo} = file:read_file_info(FromFile1),
46
- ok = file:write_file_info(ToFile2, FileInfo),
47
ok;
48
{error, Err} ->
49
?RLX_ERROR({copy_failed,
50
51
{ok, IoData} ->
52
case filelib:ensure_dir(ToFile) of
53
ok ->
54
+ %% we were asked to render a template
55
+ %% onto a symlink, this would cause an overwrite
56
+ %% of the original file, so we delete the symlink
57
+ %% and go ahead with the template render
58
+ case ec_file:is_symlink(ToFile) of
59
+ true -> ec_file:remove(ToFile);
60
+ false -> ok
61
+ end,
62
case file:write_file(ToFile, IoData) of
63
ok ->
64
- {ok, FileInfo} = file:read_file_info(FromFile),
65
- ok = file:write_file_info(ToFile, FileInfo),
66
+ ok = ec_file:copy_file_info(ToFile, FromFile, [mode, time]),
67
ok;
68
{error, Reason} ->
69
?RLX_ERROR({unable_to_write, ToFile, Reason})
70
relx-3.21.1.tar.gz/src/rlx_prv_release.erl -> relx-3.26.0.tar.gz/src/rlx_prv_release.erl
Changed
10
1
2
ErtsDir ->
3
try
4
[Erts | _] = filelib:wildcard(filename:join(ErtsDir, "erts-*")),
5
- [_, ErtsVsn] = string:tokens(filename:basename(Erts), "-"),
6
+ [_, ErtsVsn] = rlx_string:lexemes(filename:basename(Erts), "-"),
7
{ok, rlx_state:add_realized_release(State, rlx_release:erts(Release1, ErtsVsn))}
8
catch
9
_:_ ->
10
relx-3.21.1.tar.gz/src/rlx_prv_relup.erl -> relx-3.26.0.tar.gz/src/rlx_prv_relup.erl
Changed
68
1
2
{missing_sasl, _}}}) ->
3
"Unfortunately, due to requirements in systools, you need to have the sasl application "
4
"in both the current release and the release to upgrade from.";
5
+format_error({relup_script_generation_warn, systools_relup,
6
+ [{erts_vsn_changed, _},
7
+ {erts_vsn_changed, _}]}) ->
8
+ "It has been detected that the ERTS version changed while generating the relup between versions, "
9
+ "please be aware that an instruction that will automatically restart the VM will be inserted in "
10
+ "this case";
11
+format_error({relup_script_generation_warn, Module, Warnings}) ->
12
+ ["Warnings generating relup \n",
13
+ rlx_util:indent(2), Module:format_warning(Warnings)];
14
format_error({relup_script_generation_error, Module, Errors}) ->
15
["Errors generating relup \n",
16
rlx_util:indent(2), Module:format_error(Errors)].
17
18
19
make_upfrom_script(State, Release, UpFrom) ->
20
OutputDir = rlx_state:output_dir(State),
21
+ WarningsAsErrors = rlx_state:warnings_as_errors(State),
22
Options = [{outdir, OutputDir},
23
{path, rlx_util:get_code_paths(Release, OutputDir) ++
24
rlx_util:get_code_paths(UpFrom, OutputDir)},
25
silent],
26
+ %% the following block can be uncommented
27
+ %% when systools:make_relup/4 returns
28
+ %% {error,Module,Errors} instead of error
29
+ %% when taking the warnings_as_errors option
30
+ %% ++
31
+ %% case WarningsAsErrors of
32
+ %% true -> [warnings_as_errors];
33
+ %% false -> []
34
+ % end,
35
CurrentRel = strip_rel(rlx_release:relfile(Release)),
36
UpFromRel = strip_rel(rlx_release:relfile(UpFrom)),
37
ec_cmd_log:debug(rlx_state:log(State),
38
39
[UpFromRel, CurrentRel]),
40
{ok, State};
41
error ->
42
- ?RLX_ERROR({relup_script_generation_error, CurrentRel, UpFromRel});
43
+ ?RLX_ERROR({relup_generation_error, CurrentRel, UpFromRel});
44
{ok, RelUp, _, []} ->
45
write_relup_file(State, Release, RelUp),
46
ec_cmd_log:info(rlx_state:log(State),
47
"relup successfully created!"),
48
{ok, State};
49
- {ok,_, Module,Warnings} ->
50
- ?RLX_ERROR({relup_script_generation_warn, Module, Warnings});
51
+ {ok, RelUp, Module,Warnings} ->
52
+ case WarningsAsErrors of
53
+ true ->
54
+ %% since we don't pass the warnings_as_errors option
55
+ %% the relup file gets generated anyway, we need to delete
56
+ %% it
57
+ file:delete(filename:join([OutputDir, "relup"])),
58
+ ?RLX_ERROR({relup_script_generation_warn, Module, Warnings});
59
+ false ->
60
+ write_relup_file(State, Release, RelUp),
61
+ ec_cmd_log:warn(rlx_state:log(State),
62
+ format_error({relup_script_generation_warn, Module, Warnings})),
63
+ {ok, State}
64
+ end;
65
{error,Module,Errors} ->
66
?RLX_ERROR({relup_script_generation_error, Module, Errors})
67
end.
68
relx-3.21.1.tar.gz/src/rlx_rel_discovery.erl -> relx-3.26.0.tar.gz/src/rlx_rel_discovery.erl
Changed
10
1
2
ec_cmd_log:info(rlx_state:log(State),
3
fun() ->
4
["Resolving available OTP Releases from directories:\n",
5
- string:join([[rlx_util:indent(2), LibDir] || LibDir <- LibDirs], "\n")]
6
+ rlx_string:join([[rlx_util:indent(2), LibDir] || LibDir <- LibDirs], "\n")]
7
end),
8
resolve_rel_metadata(State, LibDirs, AppMeta)
9
end.
10
relx-3.21.1.tar.gz/src/rlx_release.erl -> relx-3.26.0.tar.gz/src/rlx_release.erl
Changed
54
1
2
realized/1,
3
metadata/1,
4
start_clean_metadata/1,
5
+ no_dot_erlang_metadata/1,
6
canonical_name/1,
7
config/1,
8
config/2,
9
10
{ok, t()}.
11
realize(Rel, Pkgs0, World0) ->
12
World1 = subset_world(Pkgs0, World0),
13
- process_specs(realize_erts(Rel), World1).
14
+ case rlx_topo:sort_apps(World1) of
15
+ {ok, Pkgs1} ->
16
+ process_specs(realize_erts(Rel), Pkgs1);
17
+ Error={error, _} ->
18
+ Error
19
+ end.
20
21
%% @doc this gives the application specs for the release. This can only be
22
%% populated by the 'realize' call in this module.
23
24
?RLX_ERROR({not_realized, Name, Vsn})
25
end.
26
27
+%% The no_dot_erlang.rel.src file is a literal copy of start_clean.rel.src
28
+%% in Erlang/OTP itself.
29
+-spec no_dot_erlang_metadata(t()) -> term().
30
+no_dot_erlang_metadata(T) ->
31
+ start_clean_metadata(T).
32
+
33
%% @doc produce the canonical name (<name>-<vsn>) for this release
34
-spec canonical_name(t()) -> string().
35
canonical_name(#release_t{name=Name, vsn=Vsn}) ->
36
37
rlx_depsolver:format_constraint(Constraint).
38
39
-spec format_error(Reason::term()) -> iolist().
40
+format_error({topo_error, E}) ->
41
+ rlx_topo:format_error(E);
42
format_error({failed_to_parse, Con}) ->
43
io_lib:format("Failed to parse constraint ~p", [Con]);
44
format_error({invalid_constraint, _, Con}) ->
45
46
AppName ->
47
{ok,
48
Release#release_t{annotations=ec_dictionary:add(AppName, NewAnnots, Annots),
49
- goals = [Constraint | Goals]}}
50
+ goals = Goals++[Constraint]}}
51
end.
52
53
-spec parse_constraint(application_constraint()) ->
54
relx-3.21.1.tar.gz/src/rlx_state.erl -> relx-3.26.0.tar.gz/src/rlx_state.erl
Changed
113
1
2
hooks/2,
3
vm_args/1,
4
vm_args/2,
5
+ vm_args_src/1,
6
+ vm_args_src/2,
7
sys_config/1,
8
sys_config/2,
9
+ sys_config_src/1,
10
+ sys_config_src/2,
11
root_dir/1,
12
root_dir/2,
13
add_configured_release/2,
14
15
upfrom/1,
16
upfrom/2,
17
format/1,
18
- format/2]).
19
-
20
+ format/2,
21
+ exclude_modules/1,
22
+ exclude_modules/2,
23
+ warnings_as_errors/1,
24
+ warnings_as_errors/2]).
25
26
-export_type([t/0,
27
releases/0,
28
29
available_apps=[] :: [rlx_app_info:t()],
30
default_configured_release :: {rlx_release:name() | undefined, rlx_release:vsn() |undefined} | undefined,
31
vm_args :: file:filename() | false | undefined,
32
+ vm_args_src :: file:filename() | undefined,
33
sys_config :: file:filename() | false | undefined,
34
+ sys_config_src :: file:filename() | undefined,
35
overrides=[] :: [{AppName::atom(), Directory::file:filename()}],
36
skip_apps=[] :: [AppName::atom()],
37
exclude_apps=[] :: [AppName::atom()],
38
+ exclude_modules=[] :: [{App::atom(), [Module::atom()]}],
39
debug_info=keep :: keep | strip,
40
configured_releases :: releases(),
41
realized_releases :: releases(),
42
43
include_src=true :: boolean(),
44
upfrom :: string() | binary() | undefined,
45
config_values :: ec_dictionary:dictionary(Key::atom(),
46
- Value::term())}).
47
+ Value::term()),
48
+ warnings_as_errors=false :: boolean()}).
49
50
%%============================================================================
51
%% types
52
53
exclude_apps(State, SkipApps) ->
54
State#state_t{exclude_apps=SkipApps}.
55
56
+-spec exclude_modules(t()) -> [{App::atom(), [Module::atom()]}].
57
+exclude_modules(#state_t{exclude_modules=Modules}) ->
58
+ Modules.
59
+
60
+%% @doc modules to be excluded from the release
61
+-spec exclude_modules(t(), [{App::atom(), [Module::atom()]}]) -> t().
62
+exclude_modules(State, SkipModules) ->
63
+ State#state_t{exclude_modules=SkipModules}.
64
+
65
-spec debug_info(t()) -> keep | strip.
66
debug_info(#state_t{debug_info=DebugInfo}) ->
67
DebugInfo.
68
69
vm_args(State, VmArgs) ->
70
State#state_t{vm_args=VmArgs}.
71
72
+-spec vm_args_src(t()) -> file:filename() | undefined.
73
+vm_args_src(#state_t{vm_args_src=VmArgs}) ->
74
+ VmArgs.
75
+
76
+-spec vm_args_src(t(), undefined | file:filename()) -> t().
77
+vm_args_src(State, VmArgs) ->
78
+ State#state_t{vm_args_src=VmArgs}.
79
+
80
-spec sys_config(t()) -> file:filename() | false | undefined.
81
sys_config(#state_t{sys_config=SysConfig}) ->
82
SysConfig.
83
84
sys_config(State, SysConfig) ->
85
State#state_t{sys_config=SysConfig}.
86
87
+-spec sys_config_src(t()) -> file:filename() | undefined.
88
+sys_config_src(#state_t{sys_config_src=SysConfigSrc}) ->
89
+ SysConfigSrc.
90
+
91
+-spec sys_config_src(t(), file:filename() | undefined) -> t().
92
+sys_config_src(State, SysConfigSrc) ->
93
+ State#state_t{sys_config_src=SysConfigSrc}.
94
+
95
-spec root_dir(t()) -> file:filename() | undefined.
96
root_dir(#state_t{root_dir=RootDir}) ->
97
RootDir.
98
99
Provider = providers:get_provider(Target, Providers),
100
providers:hooks(Provider).
101
102
+-spec warnings_as_errors(t()) -> boolean().
103
+warnings_as_errors(#state_t{warnings_as_errors=WarningsAsErrors}) ->
104
+ WarningsAsErrors.
105
+
106
+-spec warnings_as_errors(t(), boolean()) -> t().
107
+warnings_as_errors(State, WarningsAsErrors) ->
108
+ State#state_t{warnings_as_errors=WarningsAsErrors}.
109
+
110
%% ===================================================================
111
%% Internal functions
112
%% ===================================================================
113
relx-3.26.0.tar.gz/src/rlx_string.erl
Added
25
1
2
+%% Compatibility module for the string API changes between
3
+%% OTP-19 and OTP-21, where Unicode support means the deprecation
4
+%% of a lot of string functions.
5
+-module(rlx_string).
6
+-export([concat/2, lexemes/2, join/2]).
7
+
8
+-ifdef(unicode_str).
9
+concat(Str1, Str2) -> unicode:characters_to_list([Str1,Str2]).
10
+lexemes(Str, Separators) -> string:lexemes(Str, Separators).
11
+-else.
12
+concat(Str1, Str2) -> string:concat(Str1, Str2).
13
+lexemes(Str, Separators) -> string:tokens(Str, Separators).
14
+-endif.
15
+
16
+%% string:join/2 copy; string:join/2 is getting obsoleted
17
+%% and replaced by lists:join/2, but lists:join/2 is too new
18
+%% for version support (only appeared in 19.0) so it cannot be
19
+%% used. Instead we just adopt join/2 locally and hope it works
20
+%% for most unicode use cases anyway.
21
+join([], Sep) when is_list(Sep) ->
22
+ [];
23
+join([H|T], Sep) ->
24
+ H ++ lists:append([Sep ++ X || X <- T]).
25
relx-3.26.0.tar.gz/src/rlx_topo.erl
Added
192
1
2
+%% -*- erlang-indent-level: 4; indent-tabs-mode: nil; fill-column: 80 -*-
3
+%%% Copyright 2012 Erlware, LLC. All Rights Reserved.
4
+%%%
5
+%%% This file is provided to you under the Apache License,
6
+%%% Version 2.0 (the "License"); you may not use this file
7
+%%% except in compliance with the License. You may obtain
8
+%%% a copy of the License at
9
+%%%
10
+%%% http://www.apache.org/licenses/LICENSE-2.0
11
+%%%
12
+%%% Unless required by applicable law or agreed to in writing,
13
+%%% software distributed under the License is distributed on an
14
+%%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+%%% KIND, either express or implied. See the License for the
16
+%%% specific language governing permissions and limitations
17
+%%% under the License.
18
+%%%-------------------------------------------------------------------
19
+%%% @author Joe Armstrong
20
+%%% @author Eric Merritt
21
+%%% @author Konstantin Tcepliaev
22
+%%% @doc
23
+%%% This is a pretty simple topological sort for erlang. It was
24
+%%% originally written for ermake by Joe Armstrong back in '98. It
25
+%%% has been pretty heavily modified by Eric Merritt since '06 and modified again for Relx.
26
+%%% Konstantin Tcepliaev rewrote the algorithm in 2017.
27
+%%%
28
+%%% A partial order on the set S is a set of pairs {Xi,Xj} such that
29
+%%% some relation between Xi and Xj is obeyed.
30
+%%%
31
+%%% A topological sort of a partial order is a sequence of elements
32
+%%% [X1, X2, X3 ...] such that if whenever {Xi, Xj} is in the partial
33
+%%% order i < j
34
+%%%
35
+%%% This particular implementation guarantees that nodes closer to
36
+%%% the top level of the graph will be put as close as possible to
37
+%%% the beginning of the resulting list - this ensures that dependencies
38
+%%% are started as late as possible, and top-level apps are started
39
+%%% as early as possible.
40
+%%% @end
41
+%%%-------------------------------------------------------------------
42
+-module(rlx_topo).
43
+
44
+-export([sort_apps/1,
45
+ format_error/1]).
46
+
47
+-include("relx.hrl").
48
+
49
+%%====================================================================
50
+%% API
51
+%%====================================================================
52
+
53
+%% @doc This only does a topo sort on the list of applications and
54
+%% assumes that there is only *one* version of each app in the list of
55
+%% applications. This implies that you have already done the
56
+%% constraint solve before you pass the list of apps here to be
57
+%% sorted.
58
+-spec sort_apps([rlx_app_info:t()]) ->
59
+ {ok, [rlx_app_info:t()]} |
60
+ relx:error().
61
+sort_apps(Apps) ->
62
+ AppDeps = [{rlx_app_info:name(App),
63
+ rlx_app_info:active_deps(App) ++ rlx_app_info:library_deps(App)}
64
+ || App <- Apps],
65
+ {AppNames, _} = lists:unzip(AppDeps),
66
+ case lists:foldl(fun iterator/2, {ok, [], AppDeps, []}, AppNames) of
67
+ {ok, Names, _, _} ->
68
+ {ok, names_to_apps(lists:reverse(Names), Apps)};
69
+ E ->
70
+ E
71
+ end.
72
+
73
+%% @doc nicely format the error from the sort.
74
+-spec format_error(Reason::term()) -> iolist().
75
+format_error({cycle, App, Path}) ->
76
+ ["Cycle detected in dependency graph, this must be resolved "
77
+ "before we can continue:\n",
78
+ rlx_util:indent(2),
79
+ [[erlang:atom_to_list(A), " -> "] || A <- lists:reverse(Path)],
80
+ erlang:atom_to_list(App)].
81
+
82
+%%====================================================================
83
+%% Internal Functions
84
+%%====================================================================
85
+
86
+-type name() :: AppName::atom().
87
+-type app_dep() :: {AppName::name(), [DepName::name()]}.
88
+-type iterator_state() :: {ok, [Acc::name()],
89
+ [Apps::app_dep()],
90
+ [Path::name()]}.
91
+
92
+-spec iterator(name(), iterator_state() | relx:error()) ->
93
+ iterator_state() | relx:error().
94
+iterator(App, {ok, Acc, Apps, Path}) ->
95
+ case lists:member(App, Acc) of
96
+ false ->
97
+ %% haven't seen this app yet
98
+ case lists:keytake(App, 1, Apps) of
99
+ {value, {App, Deps}, NewApps} ->
100
+ DepInit = {ok, Acc, NewApps, [App | Path]},
101
+ %% recurse over deps
102
+ case lists:foldl(fun iterator/2, DepInit, Deps) of
103
+ {ok, DepAcc, DepApps, _} ->
104
+ {ok, [App | DepAcc], DepApps, Path};
105
+ Error ->
106
+ Error
107
+ end;
108
+ false ->
109
+ %% we have visited this app before,
110
+ %% that means there's a cycle
111
+ ?RLX_ERROR({cycle, App, Path})
112
+ end;
113
+ true ->
114
+ %% this app and its deps were already processed
115
+ {ok, Acc, Apps, Path}
116
+ end;
117
+iterator(_, Error) ->
118
+ Error.
119
+
120
+-spec names_to_apps([atom()], [rlx_app_info:t()]) -> [rlx_app_info:t()].
121
+names_to_apps(Names, Apps) ->
122
+ [find_app_by_name(Name, Apps) || Name <- Names].
123
+
124
+-spec find_app_by_name(atom(), [rlx_app_info:t()]) -> rlx_app_info:t().
125
+find_app_by_name(Name, Apps) ->
126
+ {ok, App1} =
127
+ ec_lists:find(fun(App) ->
128
+ rlx_app_info:name(App) =:= Name
129
+ end, Apps),
130
+ App1.
131
+
132
+%%====================================================================
133
+%% Tests
134
+%%====================================================================
135
+-ifdef(TEST).
136
+-include_lib("eunit/include/eunit.hrl").
137
+
138
+topo_apps_cycle_test() ->
139
+ {ok, App1} = rlx_app_info:new(app1, "0.1", "/no-dir", [app2], [stdlib]),
140
+ {ok, App2} = rlx_app_info:new(app2, "0.1", "/no-dir", [app1], []),
141
+ Apps = [App1, App2],
142
+ ?assertMatch({error, {_, {cycle, app1, [app2, app1]}}},
143
+ sort_apps(Apps)).
144
+
145
+topo_apps_good_test() ->
146
+ Apps = [App ||
147
+ {ok, App} <-
148
+ [rlx_app_info:new(app1, "0.1", "/no-dir", [app2, zapp1], [stdlib, kernel]),
149
+ rlx_app_info:new(app2, "0.1", "/no-dir", [app3], []),
150
+ rlx_app_info:new(app3, "0.1", "/no-dir", [kernel], []),
151
+ rlx_app_info:new(zapp1, "0.1", "/no-dir", [app2,app3,zapp2], []),
152
+ rlx_app_info:new(stdlib, "0.1", "/no-dir", [], []),
153
+ rlx_app_info:new(kernel, "0.1", "/no-dir", [], []),
154
+ rlx_app_info:new(zapp2, "0.1", "/no-dir", [], [])]],
155
+ {ok, Sorted} = sort_apps(Apps),
156
+ ?assertMatch([kernel, app3, app2, zapp2, zapp1, stdlib, app1],
157
+ [rlx_app_info:name(App) || App <- Sorted]).
158
+
159
+topo_apps_1_test() ->
160
+ Apps = [App ||
161
+ {ok, App} <-
162
+ [rlx_app_info:new(app0, "0.1", "/no-dir", [], [stdlib, dep1, dep2, dep3]),
163
+ rlx_app_info:new(app1, "0.1", "/no-dir", [], [stdlib, kernel]),
164
+ rlx_app_info:new(dep1, "0.1", "/no-dir", [], []),
165
+ rlx_app_info:new(dep2, "0.1", "/no-dir", [], []),
166
+ rlx_app_info:new(dep3, "0.1", "/no-dir", [], []),
167
+ rlx_app_info:new(stdlib, "0.1", "/no-dir", [], []),
168
+ rlx_app_info:new(kernel, "0.1", "/no-dir", [], [])]],
169
+ {ok, Sorted} = sort_apps(Apps),
170
+ ?assertMatch([stdlib, dep1, dep2, dep3, app0, kernel, app1],
171
+ [rlx_app_info:name(App) || App <- Sorted]).
172
+
173
+topo_apps_2_test() ->
174
+ Apps = [App ||
175
+ {ok, App} <-
176
+ [rlx_app_info:new(app1, "0.1", "/no-dir", [app2, app3, app4, app5,
177
+ stdlib, kernel],
178
+ []),
179
+ rlx_app_info:new(app2, "0.1", "/no-dir", [stdlib, kernel], []),
180
+ rlx_app_info:new(app3, "0.1", "/no-dir", [stdlib, kernel], []),
181
+ rlx_app_info:new(app4, "0.1", "/no-dir", [stdlib, kernel], []),
182
+ rlx_app_info:new(app5, "0.1", "/no-dir", [stdlib, kernel], []),
183
+ rlx_app_info:new(stdlib, "0.1", "/no-dir", [], []),
184
+ rlx_app_info:new(kernel, "0.1", "/no-dir", [], [])
185
+ ]],
186
+ {ok, Sorted} = sort_apps(Apps),
187
+ ?assertMatch([stdlib, kernel, app2,
188
+ app3, app4, app5, app1],
189
+ [rlx_app_info:name(App) || App <- Sorted]).
190
+
191
+-endif.
192
relx-3.21.1.tar.gz/src/rlx_util.erl -> relx-3.26.0.tar.gz/src/rlx_util.erl
Changed
42
1
2
intensity/0,
3
symlink_or_copy/2]).
4
5
+-export([os_type/1]).
6
+
7
-define(DFLT_INTENSITY, high).
8
-define(ONE_LEVEL_INDENT, " ").
9
%%============================================================================
10
11
Mode
12
end.
13
14
+os_type(State) ->
15
+ case include_erts_is_win32(State) of
16
+ true -> {win32,nt};
17
+ false -> os:type()
18
+ end.
19
+
20
+include_erts_is_win32(State) ->
21
+ case rlx_state:get(State, include_erts, true) of
22
+ true -> false;
23
+ false -> false;
24
+ Path -> is_win32_erts(Path,State)
25
+ end.
26
+
27
+is_win32_erts(Path,State) ->
28
+ case filelib:wildcard(filename:join([Path,"bin","erl.exe"])) of
29
+ [] -> false;
30
+ _ ->
31
+ ec_cmd_log:info(rlx_state:log(State),
32
+ "Including Erts is win32 ~n", []),
33
+ true
34
+ end.
35
+
36
+
37
+
38
+
39
%%%===================================================================
40
%%% Test Functions
41
%%%===================================================================
42
relx-3.21.1.tar.gz/test/rlx_archive_SUITE.erl -> relx-3.26.0.tar.gz/test/rlx_archive_SUITE.erl
Changed
71
1
2
TestDirFull = filename:join([LibDir1, TestDir]),
3
TestFileFull = filename:join(TestDirFull, TestFile),
4
SecondTestDir = "second_test_dir",
5
+ TestScript = "test_script",
6
+ TestScript2 = "test_script2",
7
rlx_test_utils:write_config(ConfigFile,
8
[{overlay_vars, [OverlayVars1, OverlayVars2]},
9
{overlay, [{mkdir, "{{target_dir}}/fooo"},
10
11
"{{target_dir}}/{{yahoo}}/vars.link.config"},
12
{copy, TestDirFull,
13
"{{target_dir}}/"++SecondTestDir++"/"},
14
+ {copy, TestScript,
15
+ "{{target_dir}}/"++SecondTestDir++"/"++TestScript},
16
+ {chmod, 8#00700,
17
+ "{{target_dir}}/"++SecondTestDir++"/"++TestScript},
18
+ {copy, TestScript2,
19
+ "{{target_dir}}/"++SecondTestDir++"/"++TestScript2},
20
+ {chmod, "{{test_script_perm}}",
21
+ "{{target_dir}}/"++SecondTestDir++"/"++TestScript2},
22
{template, Template,
23
"{{target_dir}}/test_template_resolved"},
24
- {template, Template,
25
+ {template, Template,
26
"bin/{{default_release_name}}-{{default_release_version}}"}]},
27
{release, {foo, "0.0.1"},
28
[goal_app_1,
29
30
rlx_test_utils:write_config(VarsFile1, [{yahoo, "yahoo"},
31
{yahoo2, [{foo, "bar"}]},
32
{foo_yahoo, "foo_{{yahoo}}"},
33
- {foo_dir, "foodir"}]),
34
+ {foo_dir, "foodir"},
35
+ {test_script_perm,8#00770}]),
36
37
VarsFile2 = filename:join([LibDir1, "vars2.config"]),
38
rlx_test_utils:write_config(VarsFile2, [{google, "yahoo"},
39
40
rlx_test_utils:write_config(VarsFile3, [{google, "yahoo"},
41
{yahoo4, "{{yahoo}}/{{yahoo2}}4"}]),
42
43
+ TestScriptFile = filename:join([LibDir1,TestScript]),
44
+ ok = file:write_file(TestScriptFile, <<"#!/bin/sh\necho \"hello world\"">>),
45
+ TestScriptFile2 = filename:join([LibDir1,TestScript2]),
46
+ ok = file:write_file(TestScriptFile2, <<"#!/bin/sh\necho \"hello world 2\"">>),
47
+
48
ok = rlx_util:mkdir_p(TestDirFull),
49
ok = file:write_file(TestFileFull, rlx_test_utils:test_template_contents()),
50
51
52
?assert(lists:member({goal_app_2, "0.0.1"}, AppSpecs)),
53
?assert(lists:member({lib_dep_1, "0.0.1", load}, AppSpecs)),
54
55
+ % check that the chmod of our file worked
56
+ ChmodedFile = filename:join([OutputDir,"foo",SecondTestDir,TestScript]),
57
+ {ok, ChmodedInfo} = file:read_file_info (ChmodedFile),
58
+ % mode from file_info is a bitmask which might have other bits set, but
59
+ % if we mask those we care about and check we should get true, see details
60
+ % here http://stackoverflow.com/questions/13183838/how-to-use-erlang-fileread-file-info-permissions-mode-info
61
+ ?assert(ChmodedInfo#file_info.mode band 8#00700 =:= 8#00700),
62
+
63
+ % check that the templated chmod of our file worked
64
+ ChmodedFile2 = filename:join([OutputDir,"foo",SecondTestDir,TestScript2]),
65
+ {ok, ChmodedInfo2} = file:read_file_info (ChmodedFile2),
66
+ ?assert(ChmodedInfo2#file_info.mode band 8#00770 =:= 8#00770),
67
+
68
TarFile = filename:join([OutputDir, "foo", "foo-0.0.1.tar.gz"]),
69
{ok, Files} = erl_tar:table(TarFile, [compressed]),
70
?assert(lists:any(fun(X) -> re:run(X, "lib/stdlib-.*/src/.*") =/= nomatch end, Files)),
71
relx-3.21.1.tar.gz/test/rlx_depsolver_tester.erl -> relx-3.26.0.tar.gz/test/rlx_depsolver_tester.erl
Changed
28
1
2
process_line(Device, io:get_line(Device, ""),
3
Acc);
4
process_line(Device, [$\s | Rest], [{Pkg, Vsn, Deps} | Acc]) ->
5
- [DepPackage, Type, DepVsn] = string:tokens(Rest, " \n"),
6
+ [DepPackage, Type, DepVsn] = rlx_string:lexemes(Rest, " \n"),
7
Dep =
8
case Type of
9
"=" ->
10
11
process_line(Device, io:get_line(Device, ""),
12
[{Pkg, Vsn, [Dep | Deps]} | Acc]);
13
process_line(Device, Pkg, Acc) ->
14
- [Package, Vsn] = string:tokens(Pkg, " \n"),
15
+ [Package, Vsn] = rlx_string:lexemes(Pkg, " \n"),
16
process_line(Device, io:get_line(Device, ""),
17
[{Package, Vsn, []} | Acc]).
18
19
20
end, rlx_depsolver:new_graph(), Pkgs).
21
22
get_constraints(ConLine) ->
23
- AppVsns = string:tokens(ConLine, " \n"),
24
+ AppVsns = rlx_string:lexemes(ConLine, " \n"),
25
lists:map(fun(AppCon) ->
26
parse_app(AppCon, [])
27
end, AppVsns).
28
relx-3.21.1.tar.gz/test/rlx_depsolver_tests.erl -> relx-3.26.0.tar.gz/test/rlx_depsolver_tests.erl
Changed
141
1
2
3
4
case rlx_depsolver:solve(Dom0, [{app1, "0.1"}]) of
5
- {ok,[{app3,{{0,3},{[],[]}}},
6
+ {ok,[{app1,{{0,1},{[],[]}}},
7
{app2,{{0,2},{[],[<<"build">>,33]}}},
8
- {app1,{{0,1},{[],[]}}}]} ->
9
+ {app3,{{0,3},{[],[]}}}]} ->
10
ok;
11
E ->
12
erlang:throw({invalid_result, E})
13
14
X = rlx_depsolver:solve(Dom0, [{app1, "0.1"},
15
{app2, "0.3"}]),
16
17
- ?assertMatch({ok, [{app3,{{0,3},{[],[]}}},
18
- {app2,{{0,3},{[],[]}}},
19
+ ?assertMatch({ok, [{app1,{{0,1},{[],[]}}},
20
{app4,{{0,2},{[],[]}}},
21
- {app1,{{0,1},{[],[]}}}]},
22
+ {app2,{{0,3},{[],[]}}},
23
+ {app3,{{0,3},{[],[]}}}]},
24
X).
25
26
third_test() ->
27
28
{"2.0.0", []},
29
{"6.0.0", []}]}]),
30
31
- ?assertMatch({ok, [{app5,{{6,0,0},{[],[]}}},
32
- {app3,{{0,1,3},{[],[]}}},
33
- {app4,{{6,0,0},{[],[]}}},
34
+ ?assertMatch({ok, [{app1,{{3,0},{[],[]}}},
35
{app2,{{3,0},{[],[]}}},
36
- {app1,{{3,0},{[],[]}}}]},
37
+ {app4,{{6,0,0},{[],[]}}},
38
+ {app3,{{0,1,3},{[],[]}}},
39
+ {app5,{{6,0,0},{[],[]}}}]},
40
rlx_depsolver:solve(Dom0, [{app1, "3.0"}])),
41
42
43
- ?assertMatch({ok, [{app5,{{6,0,0},{[],[]}}},
44
- {app3,{{0,1,3},{[],[]}}},
45
- {app4,{{6,0,0},{[],[]}}},
46
+ ?assertMatch({ok, [{app1,{{3,0},{[],[]}}},
47
{app2,{{3,0},{[],[]}}},
48
- {app1,{{3,0},{[],[]}}}]},
49
+ {app4,{{6,0,0},{[],[]}}},
50
+ {app3,{{0,1,3},{[],[]}}},
51
+ {app5,{{6,0,0},{[],[]}}}]},
52
rlx_depsolver:solve(Dom0, [app1])).
53
54
fail_test() ->
55
56
{"2.0.0", []},
57
{"6.0.0", []}]}]),
58
59
- ?assertMatch({ok, [{app5,{{2,0,0},{[],[]}}},
60
- {app3,{{0,1,3},{[],[]}}},
61
- {app4,{{5,0,0},{[],[]}}},
62
+ ?assertMatch({ok, [{app1,{{3,0},{[],[]}}},
63
{app2,{{3,0},{[],[]}}},
64
- {app1,{{3,0},{[],[]}}}]},
65
+ {app4,{{5,0,0},{[],[]}}},
66
+ {app3,{{0,1,3},{[],[]}}},
67
+ {app5,{{2,0,0},{[],[]}}}]},
68
rlx_depsolver:solve(Dom0, [{app1, "3.0"}])),
69
70
- ?assertMatch({ok, [{app5,{{2,0,0},{[],[]}}},
71
- {app3,{{0,1,3},{[],[]}}},
72
- {app4,{{5,0,0},{[],[]}}},
73
+ ?assertMatch({ok, [{app1,{{3,0},{[],[]}}},
74
{app2,{{3,0},{[],[]}}},
75
- {app1,{{3,0},{[],[]}}}]},
76
+ {app4,{{5,0,0},{[],[]}}},
77
+ {app3,{{0,1,3},{[],[]}}},
78
+ {app5,{{2,0,0},{[],[]}}}]},
79
rlx_depsolver:solve(Dom0, [app1, app2, app5])).
80
81
82
83
Dom0 = rlx_depsolver:add_packages(rlx_depsolver:new_graph(), [{app1, [{"0.1.0", [app2]}]},
84
{app2, [{"0.0.1", [app1]}]}]),
85
86
- ?assertMatch({ok, [{app1,{{0,1,0},{[],[]}}},{app2,{{0,0,1},{[],[]}}}]},
87
+ ?assertMatch({ok, [{app2,{{0,0,1},{[],[]}}},{app1,{{0,1,0},{[],[]}}}]},
88
rlx_depsolver:solve(Dom0, [{app1, "0.1.0"}])).
89
90
conflicting_failing_test() ->
91
92
Ret = rlx_depsolver:solve(Dom0, [app1, app3]),
93
_ = rlx_depsolver:format_error(Ret),
94
?assertMatch({error,
95
- [{[{[app1],
96
+ [{[{[app3],
97
+ [{app3,{{0,1,0},{[],[]}}},[[{app5,{{6,0,0},{[],[]}}}]]]},
98
+ {[app1],
99
[{app1,{{3,0},{[],[]}}},
100
- [[{app4,{{5,0,0},{[],[]}}}],
101
- [{app2,{{0,0,1},{[],[]}}},[[{app4,{{5,0,0},{[],[]}}}]]]]]},
102
- {[app3],
103
- [{app3,{{0,1,0},{[],[]}}},[[{app5,{{6,0,0},{[],[]}}}]]]}],
104
+ [[{app2,{{0,0,1},{[],[]}}},[[{app4,{{5,0,0},{[],[]}}}]]],
105
+ [{app4,{{5,0,0},{[],[]}}}]]]}],
106
[{{app4,{{5,0,0},{[],[]}}},[{app5,{{2,0,0},{[],[]}}}]},
107
{{app1,{{3,0},{[],[]}}},[{app5,{{2,0,0},{[],[]}},'='}]}]}]},
108
Ret).
109
110
{"0.3.0", []},
111
{"2.0.0", []},
112
{"6.0.0", []}]}]),
113
- ?assertMatch({ok, [{app5,{{6,0,0},{[],[]}}},
114
- {app3,{{0,1,3},{[],[]}}},
115
- {app4,{{6,0,0},{[],[]}}},
116
+ ?assertMatch({ok, [{app1,{{3,0},{[],[]}}},
117
{app2,{{2,1,5},{[],[]}}},
118
- {app1,{{3,0},{[],[]}}}]},
119
+ {app4,{{6,0,0},{[],[]}}},
120
+ {app3,{{0,1,3},{[],[]}}},
121
+ {app5,{{6,0,0},{[],[]}}}]},
122
rlx_depsolver:solve(Dom0, [{app1, "3.0"}])).
123
124
pessimistic_major_minor_test() ->
125
126
{"0.3.0", []},
127
{"2.0.0", []},
128
{"6.0.0", []}]}]),
129
- ?assertMatch({ok, [{app5,{{6,0,0},{[],[]}}},
130
- {app3,{{0,1,3},{[],[]}}},
131
- {app4,{{6,0,0},{[],[]}}},
132
+ ?assertMatch({ok, [{app1,{{3,0},{[],[]}}},
133
{app2,{{2,2},{[],[]}}},
134
- {app1,{{3,0},{[],[]}}}]},
135
+ {app4,{{6,0,0},{[],[]}}},
136
+ {app3,{{0,1,3},{[],[]}}},
137
+ {app5,{{6,0,0},{[],[]}}}]},
138
rlx_depsolver:solve(Dom0, [{app1, "3.0"}])).
139
140
filter_versions_test() ->
141
relx-3.21.1.tar.gz/test/rlx_eunit_SUITE.erl -> relx-3.26.0.tar.gz/test/rlx_eunit_SUITE.erl
Changed
27
1
2
all/0,
3
depsolver/1,
4
goal/1,
5
- app_info/1]).
6
+ app_info/1,
7
+ topo/1]).
8
9
-include_lib("common_test/include/ct.hrl").
10
-include_lib("eunit/include/eunit.hrl").
11
12
ok.
13
14
all() ->
15
- [depsolver, goal, app_info].
16
+ [depsolver, goal, app_info, topo].
17
18
depsolver(_Config) ->
19
ok = eunit:test(rlx_depsolver).
20
21
22
app_info(_Config) ->
23
ok = eunit:test(rlx_app_info).
24
+
25
+topo(_Config) ->
26
+ ok = eunit:test(rlx_topo).
27
relx-3.21.1.tar.gz/test/rlx_extended_bin_SUITE.erl -> relx-3.26.0.tar.gz/test/rlx_extended_bin_SUITE.erl
Changed
201
1
2
end_per_suite/1,
3
init_per_testcase/2,
4
all/0,
5
+ start_sname_in_other_argsfile/1,
6
+ start_preserves_arguments/1,
7
+ start_nodetool_with_data_from_argsfile/1,
8
+ start_upgrade_escript_with_argsfile_data/1,
9
+ start_fail_when_no_name/1,
10
+ start_fail_when_multiple_names/1,
11
+ start_fail_when_missing_argsfile/1,
12
+ start_fail_when_nonreadable_argsfile/1,
13
+ start_fail_when_relative_argsfile/1,
14
+ start_fail_when_circular_argsfiles/1,
15
ping/1,
16
+ shortname_ping/1,
17
+ longname_ping/1,
18
attach/1,
19
pid/1,
20
restart/1,
21
reboot/1,
22
escript/1,
23
- remote_console/1]).
24
+ remote_console/1, shortname_remote_console/1,
25
+ replace_os_vars/1,
26
+ replace_os_vars_sys_config_vm_args_src/1,
27
+ replace_os_vars_multi_node/1,
28
+ replace_os_vars_included_config/1,
29
+ replace_os_vars_custom_location/1,
30
+ replace_os_vars_dev_mode/1,
31
+ replace_os_vars_twice/1,
32
+ custom_start_script_hooks/1,
33
+ builtin_wait_for_vm_start_script_hook/1,
34
+ builtin_pid_start_script_hook/1,
35
+ builtin_wait_for_process_start_script_hook/1,
36
+ mixed_custom_and_builtin_start_script_hooks/1,
37
+ builtin_status_script/1, custom_status_script/1,
38
+ extension_script/1,
39
+ extension_script_exit_code/1,
40
+ extension_script_fail_when_no_exit/1]).
41
42
-include_lib("common_test/include/ct.hrl").
43
-include_lib("eunit/include/eunit.hrl").
44
45
{state, State1} | Config].
46
47
all() ->
48
- [ping, attach, pid, restart, reboot, escript,
49
- remote_console].
50
+ [start_sname_in_other_argsfile, start_preserves_arguments, start_nodetool_with_data_from_argsfile,
51
+ start_upgrade_escript_with_argsfile_data, start_fail_when_no_name, start_fail_when_multiple_names,
52
+ start_fail_when_missing_argsfile, start_fail_when_nonreadable_argsfile,
53
+ start_fail_when_relative_argsfile, start_fail_when_circular_argsfiles,
54
+ ping, shortname_ping, longname_ping, attach, pid, restart, reboot, escript,
55
+ remote_console, shortname_remote_console, replace_os_vars, replace_os_vars_sys_config_vm_args_src, replace_os_vars_multi_node,
56
+ replace_os_vars_included_config,
57
+ replace_os_vars_custom_location, replace_os_vars_dev_mode, replace_os_vars_twice, custom_start_script_hooks,
58
+ builtin_wait_for_vm_start_script_hook, builtin_pid_start_script_hook,
59
+ builtin_wait_for_process_start_script_hook, mixed_custom_and_builtin_start_script_hooks,
60
+ builtin_status_script, custom_status_script,
61
+ extension_script,
62
+ extension_script_exit_code,
63
+ extension_script_fail_when_no_exit].
64
65
ping(Config) ->
66
LibDir1 = proplists:get_value(lib1, Config),
67
+ rlx_test_utils:create_app(LibDir1, "goal_app", "0.0.1", [stdlib,kernel], []),
68
+
69
+ ConfigFile = filename:join([LibDir1, "relx.config"]),
70
+ rlx_test_utils:write_config(ConfigFile,
71
+ [{release, {foo, "0.0.1"},
72
+ [goal_app]},
73
+ {lib_dirs, [filename:join(LibDir1, "*")]},
74
+ {generate_start_script, true},
75
+ {extended_start_script, true}
76
+ ]),
77
+
78
+ OutputDir = filename:join([proplists:get_value(priv_dir, Config),
79
+ rlx_test_utils:create_random_name("relx-output")]),
80
+
81
+ {ok, _State} = relx:do([{relname, foo},
82
+ {relvsn, "0.0.1"},
83
+ {goals, []},
84
+ {lib_dirs, [LibDir1]},
85
+ {log_level, 3},
86
+ {output_dir, OutputDir},
87
+ {config, ConfigFile}], ["release"]),
88
+
89
+ %% now start/stop the release to make sure the extended script is working
90
+ {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo start"])),
91
+ timer:sleep(2000),
92
+ {ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])),
93
+ {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo stop"])),
94
+ %% a ping should fail after stopping a node
95
+ {error, 1, _} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])).
96
+
97
+shortname_ping(Config) ->
98
+ LibDir1 = proplists:get_value(lib1, Config),
99
+
100
+ rlx_test_utils:create_app(LibDir1, "goal_app", "0.0.1", [stdlib,kernel], []),
101
+
102
+ ConfigFile = filename:join([LibDir1, "relx.config"]),
103
+ VmArgs = filename:join([LibDir1, "vm.args"]),
104
+
105
+ rlx_test_utils:write_config(ConfigFile,
106
+ [{release, {foo, "0.0.1"},
107
+ [goal_app]},
108
+ {lib_dirs, [filename:join(LibDir1, "*")]},
109
+ {vm_args, VmArgs},
110
+ {generate_start_script, true},
111
+ {extended_start_script, true}
112
+ ]),
113
+
114
+ ec_file:write(VmArgs, "-sname foo\n\n"
115
+ "-setcookie cookie\n"),
116
+
117
+ OutputDir = filename:join([proplists:get_value(priv_dir, Config),
118
+ rlx_test_utils:create_random_name("relx-output")]),
119
+
120
+ {ok, _State} = relx:do([{relname, foo},
121
+ {relvsn, "0.0.1"},
122
+ {goals, []},
123
+ {lib_dirs, [LibDir1]},
124
+ {log_level, 3},
125
+ {output_dir, OutputDir},
126
+ {config, ConfigFile}], ["release"]),
127
+
128
+ %% now start/stop the release to make sure the extended script is working
129
+ {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo start"])),
130
+ timer:sleep(2000),
131
+ {ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])),
132
+ {ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo stop"])),
133
+ %% a ping should fail after stopping a node
134
+ {error, 1, _} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])).
135
+
136
+longname_ping(Config) ->
137
+ LibDir1 = proplists:get_value(lib1, Config),
138
139
rlx_test_utils:create_app(LibDir1, "goal_app", "0.0.1", [stdlib,kernel], []),
140
141
ConfigFile = filename:join([LibDir1, "relx.config"]),
142
+ VmArgs = filename:join([LibDir1, "vm.args"]),
143
+
144
rlx_test_utils:write_config(ConfigFile,
145
[{release, {foo, "0.0.1"},
146
[goal_app]},
147
{lib_dirs, [filename:join(LibDir1, "*")]},
148
+ {vm_args, VmArgs},
149
{generate_start_script, true},
150
{extended_start_script, true}
151
]),
152
+
153
+ ec_file:write(VmArgs, "-name foo\n\n"
154
+ "-setcookie cookie\n"),
155
156
OutputDir = filename:join([proplists:get_value(priv_dir, Config),
157
rlx_test_utils:create_random_name("relx-output")]),
158
159
{ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])),
160
{ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo stop"])),
161
%% a ping should fail after stopping a node
162
- {error, 1} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])).
163
+ {error, 1, _} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])).
164
165
attach(Config) ->
166
LibDir1 = proplists:get_value(lib1, Config),
167
168
{ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo attach", "&"])),
169
timer:sleep(2000),
170
{ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo stop"])),
171
- {error, 1} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])).
172
+ {error, 1, _} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])).
173
174
pid(Config) ->
175
LibDir1 = proplists:get_value(lib1, Config),
176
177
{ok, "pong"} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])),
178
{ok, _Pid} = sh(filename:join([OutputDir, "foo", "bin", "foo pid"])),
179
{ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo stop"])),
180
- {error, 1} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])).
181
+ {error, 1, _} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])).
182
183
restart(Config) ->
184
LibDir1 = proplists:get_value(lib1, Config),
185
186
timer:sleep(2000),
187
{ok, Pid2} = sh(filename:join([OutputDir, "foo", "bin", "foo pid"])),
188
{ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo stop"])),
189
- {error, 1} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])),
190
+ {error, 1, _} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])),
191
?assertEqual(Pid1, Pid2).
192
193
reboot(Config) ->
194
195
timer:sleep(2000),
196
{ok, Pid2} = sh(filename:join([OutputDir, "foo", "bin", "foo pid"])),
197
{ok, _} = sh(filename:join([OutputDir, "foo", "bin", "foo stop"])),
198
- {error, 1} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])),
199
+ {error, 1, _} = sh(filename:join([OutputDir, "foo", "bin", "foo ping"])),
200
?assertNotEqual(Pid1, Pid2).
201
relx-3.21.1.tar.gz/test/rlx_release_SUITE.erl -> relx-3.26.0.tar.gz/test/rlx_release_SUITE.erl
Changed
201
1
2
make_relup_release2/1,
3
make_one_app_top_level_release/1,
4
make_dev_mode_release/1,
5
+ make_dev_mode_template_release/1,
6
make_config_script_release/1,
7
make_release_twice/1,
8
make_release_twice_dev_mode/1,
9
make_erts_release/1,
10
make_erts_config_release/1,
11
make_included_nodetool_release/1,
12
+ make_not_included_nodetool_release/1,
13
make_src_release/1,
14
- make_excluded_src_release/1]).
15
+ make_excluded_src_release/1,
16
+ make_exclude_modules_release/1,
17
+ make_release_with_sys_config_vm_args_src/1]).
18
19
-include_lib("common_test/include/ct.hrl").
20
-include_lib("eunit/include/eunit.hrl").
21
22
make_implicit_config_release, make_rerun_overridden_release,
23
overlay_release, make_goalless_release, make_depfree_release,
24
make_invalid_config_release, make_relup_release, make_relup_release2,
25
- make_one_app_top_level_release, make_dev_mode_release,
26
+ make_one_app_top_level_release, make_dev_mode_release, make_dev_mode_template_release,
27
make_config_script_release, make_release_twice, make_release_twice_dev_mode,
28
- make_erts_release, make_erts_config_release, make_included_nodetool_release,
29
- make_src_release, make_excluded_src_release].
30
+ make_erts_release, make_erts_config_release,
31
+ make_included_nodetool_release, make_not_included_nodetool_release,
32
+ make_src_release, make_excluded_src_release, make_exclude_modules_release,
33
+ make_release_with_sys_config_vm_args_src].
34
35
add_providers(Config) ->
36
LibDir1 = proplists:get_value(lib1, Config),
37
38
{template, Template,
39
"{{target_dir}}/test_template_resolved"},
40
{template, Template,
41
- "bin/{{default_release_name}}-{{default_release_version}}"}]},
42
+ "bin/{{default_release_name}}-{{default_release_version}}"},
43
+ {copy, "{{erts_dir}}/bin/erl", "bin/copy.erl"}]},
44
{release, {foo, "0.0.1"},
45
[goal_app_1,
46
goal_app_2]}]),
47
48
?assert(ec_file:exists(filename:join([OutputDir, "foo", "foodir", "vars1.config"]))),
49
?assert(ec_file:exists(filename:join([OutputDir, "foo", "yahoo", "vars1.config"]))),
50
?assert(ec_file:exists(filename:join([OutputDir, "foo", SecondTestDir, TestDir, TestFile]))),
51
+ ?assert(ec_file:exists(filename:join([OutputDir, "foo", "bin", "copy.erl"]))),
52
53
TemplateData = case file:consult(filename:join([OutputDir, "foo", "test_template_resolved"])) of
54
{ok, Details} ->
55
56
?assert(ec_file:is_symlink(filename:join([OutputDir, "foo", "lib", "goal_app_2-0.0.1"]))),
57
?assert(ec_file:is_symlink(filename:join([OutputDir, "foo", "lib", "lib_dep_1-0.0.1"]))),
58
?assert(ec_file:is_symlink(filename:join([OutputDir, "foo", "releases", "0.0.1",
59
- "sys.config.orig"]))),
60
+ "sys.config"]))),
61
?assert(ec_file:is_symlink(filename:join([OutputDir, "foo", "releases", "0.0.1",
62
- "vm.args.orig"])));
63
+ "vm.args"])));
64
{win32, _} ->
65
?assert(filelib:is_dir(filename:join([OutputDir, "foo", "lib", "non_goal_1-0.0.1"]))),
66
?assert(filelib:is_dir(filename:join([OutputDir, "foo", "lib", "non_goal_2-0.0.1"]))),
67
68
"vm.args"])))
69
end.
70
71
+make_dev_mode_template_release(Config) ->
72
+ LibDir1 = proplists:get_value(lib1, Config),
73
+
74
+ rlx_test_utils:create_app(LibDir1, "goal_app_1", "0.0.1",
75
+ [stdlib,kernel,non_goal_1], []),
76
+ rlx_test_utils:create_app(LibDir1, "lib_dep_1", "0.0.1",
77
+ [stdlib,kernel], []),
78
+ rlx_test_utils:create_app(LibDir1, "goal_app_2", "0.0.1",
79
+ [stdlib,kernel,goal_app_1,non_goal_2], []),
80
+ rlx_test_utils:create_app(LibDir1, "non_goal_1", "0.0.1",
81
+ [stdlib,kernel], [lib_dep_1]),
82
+ rlx_test_utils:create_app(LibDir1, "non_goal_2", "0.0.1",
83
+ [stdlib,kernel], []),
84
+
85
+ SysConfig = filename:join([LibDir1, "config", "sys.config"]),
86
+ SysConfigTerm = [{this_is_a_test, "yup it is"},
87
+ {this_is_an_overlay_var, "{{var1}}"}],
88
+ rlx_test_utils:write_config(SysConfig, SysConfigTerm),
89
+
90
+ VmArgs = filename:join([LibDir1, "config", "vm.args"]),
91
+ ec_file:write(VmArgs, "-sname {{nodename}}"),
92
+
93
+ VarsFile1 = filename:join([LibDir1, "config", "vars1.config"]),
94
+ rlx_test_utils:write_config(VarsFile1, [{var1, "indeed it is"},
95
+ {nodename, "testnode"}]),
96
+
97
+ ConfigFile = filename:join([LibDir1, "relx.config"]),
98
+ rlx_test_utils:write_config(ConfigFile,
99
+ [{dev_mode, true},
100
+ {sys_config, SysConfig},
101
+ {vm_args, VmArgs},
102
+ {overlay_vars, [VarsFile1]},
103
+ {overlay, [
104
+ {template, "config/sys.config",
105
+ "releases/{{release_version}}/sys.config"},
106
+ {template, "config/vm.args",
107
+ "releases/{{release_version}}/vm.args"}]},
108
+ {release, {foo, "0.0.1"},
109
+ [goal_app_1,
110
+ goal_app_2]}]),
111
+ OutputDir = filename:join([proplists:get_value(priv_dir, Config),
112
+ rlx_test_utils:create_random_name("relx-output")]),
113
+ {ok, State} = relx:do(undefined, undefined, [], [LibDir1], 3,
114
+ OutputDir, ConfigFile),
115
+ [{{foo, "0.0.1"}, _Release}] = ec_dictionary:to_list(rlx_state:realized_releases(State)),
116
+
117
+ ?assert(ec_file:is_symlink(filename:join([OutputDir, "foo", "lib", "non_goal_1-0.0.1"]))),
118
+ ?assert(ec_file:is_symlink(filename:join([OutputDir, "foo", "lib", "non_goal_2-0.0.1"]))),
119
+ ?assert(ec_file:is_symlink(filename:join([OutputDir, "foo", "lib", "goal_app_1-0.0.1"]))),
120
+ ?assert(ec_file:is_symlink(filename:join([OutputDir, "foo", "lib", "goal_app_2-0.0.1"]))),
121
+ ?assert(ec_file:is_symlink(filename:join([OutputDir, "foo", "lib", "lib_dep_1-0.0.1"]))),
122
+ ?assert(not ec_file:is_symlink(filename:join([OutputDir, "foo", "releases", "0.0.1",
123
+ "sys.config"]))),
124
+ ?assert(not ec_file:is_symlink(filename:join([OutputDir, "foo", "releases", "0.0.1",
125
+ "vm.args"]))),
126
+ %% ensure that the original sys.config didn't get overwritten
127
+ ?assertMatch({ok, SysConfigTerm}, file:consult(SysConfig)),
128
+ %% ensure that the original vm.args didn't get overwritten
129
+ ?assertMatch({ok, <<"-sname {{nodename}}">>}, ec_file:read(VmArgs)).
130
+
131
make_config_script_release(Config) ->
132
LibDir1 = proplists:get_value(lib1, Config),
133
FooRoot = filename:join([LibDir1, "foodir1", "foodir2"]),
134
135
OutputDir, ConfigFile),
136
[{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rlx_state:realized_releases(State)),
137
AppSpecs = rlx_release:applications(Release),
138
+ ?assert(ec_file:exists(filename:join([OutputDir, "foo", "bin", "nodetool"]))),
139
+ ?assert(lists:keymember(stdlib, 1, AppSpecs)),
140
+ ?assert(lists:keymember(kernel, 1, AppSpecs)),
141
+ ?assertEqual(ErtsVsn, rlx_release:erts(Release)).
142
+
143
+make_not_included_nodetool_release(Config) ->
144
+ LibDir1 = proplists:get_value(lib1, Config),
145
+
146
+ rlx_test_utils:create_app(LibDir1, "goal_app_1", "0.0.1", [kernel,stdlib], []),
147
+ rlx_test_utils:create_app(LibDir1, "lib_dep_1", "0.0.1", [kernel,stdlib], []),
148
+ rlx_test_utils:create_app(LibDir1, "goal_app_2", "0.0.1", [kernel,stdlib], []),
149
+ rlx_test_utils:create_app(LibDir1, "non_goal_1", "0.0.1", [kernel,stdlib], []),
150
+ rlx_test_utils:create_app(LibDir1, "non_goal_2", "0.0.1", [kernel,stdlib], []),
151
+
152
+ ErtsVsn = erlang:system_info(version),
153
+ ConfigFile = filename:join([LibDir1, "relx.config"]),
154
+ rlx_test_utils:write_config(ConfigFile,
155
+ [{release, {foo, "0.0.1"}, {erts, ErtsVsn},
156
+ [goal_app_1]},
157
+ {extended_start_script, true},
158
+ {include_nodetool, false}]),
159
+ OutputDir = filename:join([proplists:get_value(priv_dir, Config),
160
+ rlx_test_utils:create_random_name("relx-output")]),
161
+ {ok, State} = relx:do(undefined, undefined, [], [LibDir1], 3,
162
+ OutputDir, ConfigFile),
163
+ [{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rlx_state:realized_releases(State)),
164
+ AppSpecs = rlx_release:applications(Release),
165
+ %% extended start script needs nodetool to work, so the
166
+ %% {include_nodetool, false} option is simply ignored
167
+ ?assert(ec_file:exists(filename:join([OutputDir, "foo", "bin", "nodetool"]))),
168
?assert(lists:keymember(stdlib, 1, AppSpecs)),
169
?assert(lists:keymember(kernel, 1, AppSpecs)),
170
?assertEqual(ErtsVsn, rlx_release:erts(Release)).
171
172
?assert(not ec_file:exists(filename:join([OutputDir, "foo", "lib",
173
"goal_app_1-0.0.1", "src"]))).
174
175
+%% Test to ensure that excluded modules don't end up in the release
176
+make_exclude_modules_release(Config) ->
177
+ LibDir1 = proplists:get_value(lib1, Config),
178
+
179
+ rlx_test_utils:create_app(LibDir1, "goal_app_1", "0.0.1", [stdlib,kernel, non_goal_1], []),
180
+ rlx_test_utils:create_app(LibDir1, "non_goal_1", "0.0.1", [stdlib,kernel], []),
181
+
182
+ ConfigFile = filename:join([LibDir1, "relx.config"]),
183
+ rlx_test_utils:write_config(ConfigFile,
184
+ [{release, {foo, "0.0.1"},
185
+ [goal_app_1]},
186
+ {exclude_modules, [{non_goal_1, [a_real_beamnon_goal_1]}]}]),
187
+ OutputDir = filename:join([proplists:get_value(priv_dir, Config),
188
+ rlx_test_utils:create_random_name("relx-output")]),
189
+ {ok, Cwd} = file:get_cwd(),
190
+ {ok, State} = relx:do(Cwd, undefined, undefined, [], [LibDir1], 3,
191
+ OutputDir, [],
192
+ ConfigFile),
193
+ [{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rlx_state:realized_releases(State)),
194
+ AppSpecs = rlx_release:applications(Release),
195
+ ?assert(lists:keymember(stdlib, 1, AppSpecs)),
196
+ ?assert(lists:keymember(kernel, 1, AppSpecs)),
197
+ ?assert(lists:member({goal_app_1, "0.0.1"}, AppSpecs)),
198
+ %% ensure that the excluded module beam file didn't get copied
199
+ ?assert(not ec_file:exists(filename:join([OutputDir, "foo", "lib",
200
+ "non_goal_1-0.0.1", "ebin",
201
relx-3.21.1.tar.gz/test/rlx_test_utils.erl -> relx-3.26.0.tar.gz/test/rlx_test_utils.erl
Changed
179
1
2
3
create_app(Dir, Name, Vsn, Deps, LibDeps) ->
4
AppDir = filename:join([Dir, Name ++ "-" ++ Vsn]),
5
- write_app_file(AppDir, Name, Vsn, Deps, LibDeps),
6
+ write_app_file(AppDir, Name, Vsn, app_modules(Name), Deps, LibDeps),
7
write_src_file(AppDir, Name),
8
- write_beam_file(AppDir, Name),
9
+ compile_src_files(AppDir),
10
+ rlx_app_info:new(erlang:list_to_atom(Name), Vsn, AppDir,
11
+ Deps, []).
12
+
13
+create_full_app(Dir, Name, Vsn, Deps, LibDeps) ->
14
+ AppDir = filename:join([Dir, Name ++ "-" ++ Vsn]),
15
+ write_full_app_files(AppDir, Name, Vsn, Deps, LibDeps),
16
+ compile_src_files(AppDir),
17
rlx_app_info:new(erlang:list_to_atom(Name), Vsn, AppDir,
18
Deps, []).
19
20
create_empty_app(Dir, Name, Vsn, Deps, LibDeps) ->
21
AppDir = filename:join([Dir, Name ++ "-" ++ Vsn]),
22
- write_app_file(AppDir, Name, Vsn, Deps, LibDeps),
23
+ write_app_file(AppDir, Name, Vsn, [], Deps, LibDeps),
24
rlx_app_info:new(erlang:list_to_atom(Name), Vsn, AppDir,
25
Deps, []).
26
27
-write_beam_file(Dir, Name) ->
28
- Beam = filename:join([Dir, "ebin", "not_a_real_beam" ++ Name ++ ".beam"]),
29
- ok = filelib:ensure_dir(Beam),
30
- ok = ec_file:write_term(Beam, testing_purposes_only).
31
+app_modules(Name) ->
32
+ [list_to_atom(M ++ Name) ||
33
+ M <- ["a_real_beam"]].
34
35
write_src_file(Dir, Name) ->
36
- Src = filename:join([Dir, "src", "not_a_real_beam" ++ Name ++ ".erl"]),
37
+ Src = filename:join([Dir, "src", "a_real_beam" ++ Name ++ ".erl"]),
38
ok = filelib:ensure_dir(Src),
39
- ok = ec_file:write_term(Src, testing_purposes_only).
40
+ ok = file:write_file(Src, beam_file_contents("a_real_beam"++Name)).
41
42
write_appup_file(AppInfo, DownVsn) ->
43
Dir = rlx_app_info:dir(AppInfo),
44
45
ok = filelib:ensure_dir(Filename),
46
ok = ec_file:write_term(Filename, {Vsn, [{DownVsn, []}], [{DownVsn, []}]}).
47
48
-write_app_file(Dir, Name, Version, Deps, LibDeps) ->
49
+write_app_file(Dir, Name, Version, Modules, Deps, LibDeps) ->
50
Filename = filename:join([Dir, "ebin", Name ++ ".app"]),
51
ok = filelib:ensure_dir(Filename),
52
- ok = ec_file:write_term(Filename, get_app_metadata(Name, Version, Deps, LibDeps)).
53
+ ok = ec_file:write_term(Filename, get_app_metadata(Name, Version, Modules,
54
+ Deps, LibDeps)).
55
56
-get_app_metadata(Name, Vsn, Deps, LibDeps) ->
57
+compile_src_files(Dir) ->
58
+ %% compile all *.erl files in src to ebin
59
+ SrcDir = filename:join([Dir, "src"]),
60
+ OutputDir = filename:join([Dir, "ebin"]),
61
+ lists:foreach(fun(SrcFile) ->
62
+ {ok, _} = compile:file(SrcFile, [{outdir, OutputDir},
63
+ return_errors])
64
+ end, ec_file:find(SrcDir, "\\.erl")),
65
+ ok.
66
+
67
+get_app_metadata(Name, Vsn, Modules, Deps, LibDeps) ->
68
{application, erlang:list_to_atom(Name),
69
[{description, ""},
70
{vsn, Vsn},
71
- {modules, []},
72
+ {modules, Modules},
73
{included_applications, LibDeps},
74
{registered, []},
75
{applications, Deps}]}.
76
77
+write_full_app_files(Dir, Name, Vsn, Deps, LibDeps) ->
78
+ %% write out the .app file
79
+ AppFilename = filename:join([Dir, "ebin", Name ++ ".app"]),
80
+ ok = filelib:ensure_dir(AppFilename),
81
+ ok = ec_file:write_term(AppFilename,
82
+ get_full_app_metadata(Name, Vsn, Deps, LibDeps)),
83
+ %% write out the _app.erl file
84
+ ApplicationFilename = filename:join([Dir, "src", Name ++ "_app.erl"]),
85
+ ok = filelib:ensure_dir(ApplicationFilename),
86
+ ok = file:write_file(ApplicationFilename, full_application_contents(Name)),
87
+ %% write out the supervisor
88
+ SupervisorFilename = filename:join([Dir, "src", Name ++ "_sup.erl"]),
89
+ ok = filelib:ensure_dir(SupervisorFilename),
90
+ ok = file:write_file(SupervisorFilename, supervisor_contents(Name)),
91
+ %% and finally the gen_server
92
+ GenServerFilename = filename:join([Dir, "src", Name ++ "_srv.erl"]),
93
+ ok = filelib:ensure_dir(GenServerFilename),
94
+ ok = file:write_file(GenServerFilename, gen_server_contents(Name)),
95
+ ok.
96
+
97
+get_full_app_metadata(Name, Vsn, Deps, LibDeps) ->
98
+ {application, erlang:list_to_atom(Name),
99
+ [{description, ""},
100
+ {vsn, Vsn},
101
+ {modules, [goal_app_app,goal_app_sup,goal_app_srv]},
102
+ {mod, {erlang:list_to_atom(Name ++ "_app"),
103
+ []}},
104
+ {included_applications, LibDeps},
105
+ {registered, []},
106
+ {applications, Deps}]}.
107
+
108
+full_application_contents(Name) ->
109
+ "-module("++Name++"_app).\n"
110
+ "-behaviour(application).\n"
111
+ "-export([start/2, stop/1]).\n"
112
+ "start(_StartType, _StartArgs) ->\n"
113
+ " "++Name++"_sup:start_link().\n"
114
+ "stop(_State) ->\n"
115
+ " ok.\n".
116
+
117
+supervisor_contents(Name) ->
118
+ "-module("++Name++"_sup).\n"
119
+ "-behaviour(supervisor).\n"
120
+ "-export([start_link/0]).\n"
121
+ "-export([init/1]).\n"
122
+ "-define(SERVER, ?MODULE).\n"
123
+ "start_link() ->\n"
124
+ " supervisor:start_link({local, ?SERVER}, ?MODULE, []).\n"
125
+ "init([]) ->\n"
126
+ " {ok, { {one_for_all, 0, 1},\n"
127
+ " [{"++Name++"_srv, {"++Name++"_srv, start_link, []},\n"
128
+ " transient, 5000, worker, ["++Name++"_srv]}\n"
129
+ " ]\n"
130
+ " }}.\n".
131
+
132
+gen_server_contents(Name) ->
133
+ "-module("++Name++"_srv).\n"
134
+ "-behaviour(gen_server).\n"
135
+ "-record(state, {}).\n"
136
+ "-export([start_link/0]).\n"
137
+ "-export([init/1,handle_call/3,handle_cast/2,\n"
138
+ " handle_info/2,terminate/2,code_change/3]).\n"
139
+ "start_link() ->\n"
140
+ " gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).\n"
141
+ "init([]) ->\n"
142
+ " erlang:send_after(4000, self(), register_signal),"
143
+ " {ok, #state{}}.\n"
144
+ "handle_call(_Event, _From, State) ->\n"
145
+ " {reply, ok, State}.\n"
146
+ "handle_cast(_Event, State) ->\n"
147
+ " {noreply, State}.\n"
148
+ "handle_info(register_signal, State) ->\n"
149
+ " erlang:register(goal_app_srv_signal, spawn(fun() -> timer:sleep(200000) end)),\n"
150
+ " {noreply, State};\n"
151
+ "handle_info(_Info, State) ->\n"
152
+ " {noreply, State}.\n"
153
+ "terminate(_Reason, _State) ->\n"
154
+ " ok.\n"
155
+ "code_change(_OldVsn, State, _Extra) ->\n"
156
+ " {ok, State}.\n".
157
+
158
create_random_name(Name) ->
159
Name ++ erlang:integer_to_list(random_uniform(1000000)).
160
161
162
ok = ec_file:write(Filename,
163
[io_lib:format("~p.\n", [Val]) || Val <- Values]).
164
165
+beam_file_contents(Name) ->
166
+ "-module("++Name++").".
167
+
168
test_template_contents() ->
169
"{erts_vsn, \"{{erts_vsn}}\"}.\n"
170
"{release_erts_version, \"{{release_erts_version}}\"}.\n"
171
172
{error, Error} ->
173
Error
174
end.
175
+
176
+unescape_string(String) ->
177
+ re:replace(String, "\"", "",
178
+ [global, {return, list}]).
179