occam-open-cli 6.0.390 → 6.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -43,7 +43,7 @@ Commands:
43
43
 
44
44
  set-options Set options
45
45
 
46
- clone <package_name> Clone a package with Git
46
+ clone <repository_name> Clone a repository with Git
47
47
 
48
48
  publish <package_name> Publish a package
49
49
 
@@ -69,11 +69,15 @@ Options:
69
69
 
70
70
  --log-level|-l Set the log level when publishing
71
71
 
72
- --yes|-y Initially answer yes to prompts
72
+ --yes|-y Automatically answer yes to affiermation prompts
73
73
 
74
- --tail|-t Sets the size of the tail of the log messages when publishing. The default is ten.
74
+ --tail|-t Sets the size of the tail of the log messages when publishing. The default is ten
75
75
 
76
- --follow|-f Show all of the log messages when publishing. The default is false.
76
+ --follow|-f Show all of the log messages when publishing. The default is false
77
+
78
+ --headless|-x Headless mode. Clone or open all dependencies bar the repository or package itself
79
+
80
+ --dependencies|-a Include dependencies when cloning repositories or opening packages
77
81
  ```
78
82
 
79
83
  This is slightly different from `npm` in that `open` is usually executed from the parent directory of a project rather than from within the project sub-directory itself.
@@ -1,19 +1,19 @@
1
1
  "use strict";
2
2
 
3
- const { NO_OPTION, YES_OPTION, HELP_OPTION, TAIL_OPTION, FOLLOW_OPTION, DRY_RUN_OPTION, VERSION_OPTION, QUIETLY_OPTION, LOG_LEVEL_OPTION } = require("./options");
3
+ const { YES_OPTION, HELP_OPTION, TAIL_OPTION, FOLLOW_OPTION, DRY_RUN_OPTION, VERSION_OPTION, QUIETLY_OPTION, HEADLESS_OPTION, LOG_LEVEL_OPTION, DEPENDENCIES_OPTION } = require("./options");
4
4
 
5
- const n = NO_OPTION,
6
- y = YES_OPTION,
5
+ const y = YES_OPTION,
7
6
  h = HELP_OPTION,
8
7
  t = TAIL_OPTION,
9
8
  f = FOLLOW_OPTION,
10
9
  d = DRY_RUN_OPTION,
11
10
  v = VERSION_OPTION,
12
11
  q = QUIETLY_OPTION,
13
- l = LOG_LEVEL_OPTION
12
+ x = HEADLESS_OPTION,
13
+ l = LOG_LEVEL_OPTION,
14
+ a = DEPENDENCIES_OPTION;
14
15
 
15
16
  module.exports = {
16
- n,
17
17
  y,
18
18
  h,
19
19
  t,
@@ -21,5 +21,7 @@ module.exports = {
21
21
  d,
22
22
  v,
23
23
  q,
24
- l
24
+ x,
25
+ l,
26
+ a
25
27
  };
@@ -1,25 +1,23 @@
1
1
  "use strict";
2
2
 
3
3
  const cloneOperation = require("../operation/clone"),
4
- cloneReleasesOperation = require("../operation/cloneReleases"),
5
- releaseNamePromptOperation = require("../operation/prompt/releaseName"),
6
- cloneDependenciesPromptOperation = require("../operation/prompt/cloneDependencies");
4
+ cloneRepositoriesOperation = require("../operation/cloneRepositories"),
5
+ repositoryNamePromptOperation = require("../operation/prompt/repositoryName");
7
6
 
8
7
  const { executeOperations } = require("../utilities/operation"),
9
8
  { SUCCESSFUL_CLONE_MESSAGE, FAILED_CLONE_MESSAGE } = require("../messages");
10
9
 
11
- function cloneAction(releaseName, quietly, yes, no) {
10
+ function cloneAction(repositoryName, dependencies, headless, quietly) {
12
11
  const operations = [
13
- releaseNamePromptOperation,
14
- cloneDependenciesPromptOperation,
12
+ repositoryNamePromptOperation,
15
13
  cloneOperation,
16
- cloneReleasesOperation
14
+ cloneRepositoriesOperation
17
15
  ],
18
16
  context = {
19
- no,
20
- yes,
21
17
  quietly,
22
- releaseName
18
+ headless,
19
+ dependencies,
20
+ repositoryName
23
21
  };
24
22
 
25
23
  executeOperations(operations, (completed) => {
@@ -17,7 +17,7 @@ Commands:
17
17
 
18
18
  set-options Set options
19
19
 
20
- clone <package_name> Clone a package with Git
20
+ clone <repository_name> Clone a repository with Git
21
21
 
22
22
  publish <package_name> Publish a package
23
23
 
@@ -43,11 +43,15 @@ Options:
43
43
 
44
44
  --log-level|-l Set the log level when publishing
45
45
 
46
- --yes|-y Initially answer yes to prompts
46
+ --yes|-y Automatically answer yes to affiermation prompts
47
47
 
48
- --tail|-t Sets the size of the tail of the log messages when publishing. The default is ten.
48
+ --tail|-t Sets the size of the tail of the log messages when publishing. The default is ten
49
49
 
50
- --follow|-f Show all of the log messages when publishing. The default is false.
50
+ --follow|-f Show all of the log messages when publishing. The default is false
51
+
52
+ --headless|-x Headless mode. Clone or open all dependencies bar the repository or package itself
53
+
54
+ --dependencies|-a Include dependencies when cloning repositories or opening packages
51
55
 
52
56
  Further information:
53
57
 
@@ -1,24 +1,24 @@
1
1
  "use strict";
2
2
 
3
3
  const openOperation = require("../operation/open"),
4
- openReleasesOperation = require("../operation/openReleases"),
5
- openDependenciesOperation = require("../operation/openDependencies"),
4
+ openReleasesOperation = require("../operation/openReleasees"),
6
5
  releaseNamePromptOperation = require("../operation/prompt/releaseName");
7
6
 
8
7
  const { executeOperations } = require("../utilities/operation"),
9
8
  { SUCCESSFUL_OPEN_MESSAGE, FAILED_OPEN_MESSAGE } = require("../messages");
10
9
 
11
- function openAction(releaseName, quietly, no) {
10
+ function openAction(releaseName, dependencies, headless, quietly, yes) {
12
11
  const operations = [
13
12
  releaseNamePromptOperation,
14
- openDependenciesOperation,
15
13
  openOperation,
16
14
  openReleasesOperation
17
15
  ],
18
16
  context = {
19
- no,
17
+ yes,
20
18
  quietly,
21
- releaseName
19
+ headless,
20
+ releaseName,
21
+ dependencies
22
22
  };
23
23
 
24
24
  executeOperations(operations, (completed) => {
package/bin/defaults.js CHANGED
@@ -6,8 +6,7 @@ const { EMPTY_STRING } = require("./constants");
6
6
 
7
7
  const { INFO_LEVEL } = levels;
8
8
 
9
- const DEFAULT_NO = false,
10
- DEFAULT_YES = false,
9
+ const DEFAULT_YES = false,
11
10
  DEFAULT_HELP = false,
12
11
  DEFAULT_HOST = "https://openmathematics.org",
13
12
  DEFAULT_TAIL = 10,
@@ -15,12 +14,13 @@ const DEFAULT_NO = false,
15
14
  DEFAULT_DRY_RUN = false,
16
15
  DEFAULT_VERSION = false,
17
16
  DEFAULT_QUIETLY = false,
17
+ DEFAULT_HEADLESS = false,
18
18
  DEFAULT_LOG_LEVEL = INFO_LEVEL,
19
+ DEFAULT_DEPENDENCIES = false,
19
20
  DEFAULT_SHELL_COMMANDS = EMPTY_STRING,
20
21
  DEFAULT_GITHUB_HOST_NAME = "github.com";
21
22
 
22
23
  module.exports = {
23
- DEFAULT_NO,
24
24
  DEFAULT_YES,
25
25
  DEFAULT_HELP,
26
26
  DEFAULT_HOST,
@@ -29,7 +29,9 @@ module.exports = {
29
29
  DEFAULT_DRY_RUN,
30
30
  DEFAULT_VERSION,
31
31
  DEFAULT_QUIETLY,
32
+ DEFAULT_HEADLESS,
32
33
  DEFAULT_LOG_LEVEL,
34
+ DEFAULT_DEPENDENCIES,
33
35
  DEFAULT_SHELL_COMMANDS,
34
36
  DEFAULT_GITHUB_HOST_NAME
35
37
  };
@@ -7,9 +7,9 @@ const USE_SSH_DESCRIPTION = "Use SSH when cloning: ",
7
7
  ARE_YOU_SURE_DESCRIPTION = "Are you sure? (y)es (n)o: ",
8
8
  EMAIL_ADDRESS_DESCRIPTION = "Email address: ",
9
9
  SHELL_COMMANDS_DESCRIPTION = "Shell command(s) to run after successful publishing: ",
10
+ REPOSITORY_NAME_DESCRIPTION = "Repository name: ",
10
11
  CONFIRM_PASSWORD_DESCRIPTION = "Confirm password: ",
11
12
  GITHUB_HOST_NAME_DESCRIPTION = "GitHub host name (leave blank for default): ",
12
- CLONE_DEPENDENCIES_DESCRIPTION = "Clone dependencies? (y)es (n)o: ",
13
13
  EMAIL_ADDRESS_OR_USERNAME_DESCRIPTION = "Email address or username: ";
14
14
 
15
15
  module.exports = {
@@ -20,8 +20,8 @@ module.exports = {
20
20
  ARE_YOU_SURE_DESCRIPTION,
21
21
  EMAIL_ADDRESS_DESCRIPTION,
22
22
  SHELL_COMMANDS_DESCRIPTION,
23
+ REPOSITORY_NAME_DESCRIPTION,
23
24
  CONFIRM_PASSWORD_DESCRIPTION,
24
25
  GITHUB_HOST_NAME_DESCRIPTION,
25
- CLONE_DEPENDENCIES_DESCRIPTION,
26
26
  EMAIL_ADDRESS_OR_USERNAME_DESCRIPTION
27
27
  };
package/bin/main.js CHANGED
@@ -15,7 +15,7 @@ const helpAction = require("./action/help"),
15
15
  setShellCommandsAction = require("./action/setShellCommands");
16
16
 
17
17
  const { NO_ARGUMENT_GIVEN_MESSAGE, COMMAND_NOT_RECOGNISED_MESSAGE } = require("./messages"),
18
- { DEFAULT_NO, DEFAULT_YES, DEFAULT_TAIL, DEFAULT_FOLLOW, DEFAULT_DRY_RUN, DEFAULT_QUIETLY, DEFAULT_LOG_LEVEL } = require("./defaults"),
18
+ { DEFAULT_YES, DEFAULT_TAIL, DEFAULT_FOLLOW, DEFAULT_DRY_RUN, DEFAULT_QUIETLY, DEFAULT_HEADLESS, DEFAULT_LOG_LEVEL, DEFAULT_DEPENDENCIES } = require("./defaults"),
19
19
  { HELP_COMMAND,
20
20
  OPEN_COMMAND,
21
21
  CLONE_COMMAND,
@@ -31,13 +31,14 @@ const { NO_ARGUMENT_GIVEN_MESSAGE, COMMAND_NOT_RECOGNISED_MESSAGE } = require(".
31
31
  SET_SHELL_COMMANDS_COMMAND } = require("./commands");
32
32
 
33
33
  function main(command, argument, options) {
34
- const { no = DEFAULT_NO,
35
- yes = DEFAULT_YES,
34
+ const { yes = DEFAULT_YES,
36
35
  tail = DEFAULT_TAIL,
37
36
  follow = DEFAULT_FOLLOW,
38
37
  dryRun = DEFAULT_DRY_RUN,
39
38
  quietly = DEFAULT_QUIETLY,
40
- logLevel = DEFAULT_LOG_LEVEL } = options;
39
+ headless = DEFAULT_HEADLESS,
40
+ logLevel = DEFAULT_LOG_LEVEL,
41
+ dependencies = DEFAULT_DEPENDENCIES } = options;
41
42
 
42
43
  switch (command) {
43
44
  case HELP_COMMAND: {
@@ -64,7 +65,7 @@ function main(command, argument, options) {
64
65
  } else {
65
66
  const releaseName = argument; ///
66
67
 
67
- openAction(releaseName, quietly, no);
68
+ openAction(releaseName, dependencies, headless, quietly, yes);
68
69
  }
69
70
 
70
71
  break;
@@ -74,9 +75,9 @@ function main(command, argument, options) {
74
75
  if (argument === null) {
75
76
  console.log(NO_ARGUMENT_GIVEN_MESSAGE);
76
77
  } else {
77
- const releaseName = argument; ///
78
+ const repositoryName = argument; ///
78
79
 
79
- cloneAction(releaseName, quietly, yes, no);
80
+ cloneAction(repositoryName, dependencies, headless, quietly);
80
81
  }
81
82
 
82
83
  break;
package/bin/messages.js CHANGED
@@ -12,10 +12,11 @@ const NO_ARGUMENT_GIVEN_MESSAGE = "No argument has been given.",
12
12
  INVALID_AFFIRMATION_MESSAGE = "You must answer (y)es or (n)o.",
13
13
  INVALID_RELEASE_NAME_MESSAGE = "Package names must consist of groups of at least two and no more than sixteen numbers or lowercase letters, separated by dashes.",
14
14
  INVALID_EMAIL_ADDRESS_MESSAGE = "The email address does not appear to be a valid one.",
15
+ INVALID_REPOSITORY_NAME_MESSAGE = "Repository names must consist of groups of at least two and no more than sixteen numbers or lowercase letters, separated by dashes.",
15
16
  INVALID_GITHUB_HOST_NAME_MESSAGE = "The GitHub host name can be any number of alphabetical, numeric, dash or period characters, or can be left blank.",
16
17
  INVALID_EMAIL_ADDRESS_OR_USERNAME_MESSAGE = "The email address or username does not appear to be a valid one.",
17
18
  FAILED_OPEN_MESSAGE = "Failed to open the package.",
18
- FAILED_CLONE_MESSAGE = "Failed to clone the package.",
19
+ FAILED_CLONE_MESSAGE = "Failed to clone the repository.",
19
20
  FAILED_PUBLISH_MESSAGE = "Failed to publish the package.",
20
21
  FAILED_WITHDRAW_MESSAGE = "Failed to withdraw the package.",
21
22
  FAILED_INITIALISE_MESSAGE = "Failed to create a configuration file because one is already present.",
@@ -23,9 +24,9 @@ const NO_ARGUMENT_GIVEN_MESSAGE = "No argument has been given.",
23
24
  FAILED_PROJECT_LOAD_MESSAGE = "Failed to load the project. Likely it is missing or perhaps it is already a package.",
24
25
  FAILED_SET_SHELL_COMMANDS_MESSAGE = "Failed to set the shell commands.",
25
26
  SUCCESSFUL_OPEN_MESSAGE = "The package has been opened successfully.",
26
- SUCCESSFUL_CLONE_MESSAGE = "The package has been cloned successfully.",
27
+ SUCCESSFUL_CLONE_MESSAGE = "The repository has been cloned successfully.",
27
28
  SUCCESSFUL_PUBLISH_MESSAGE = "The package has been published successfully.",
28
- SUCCESSFUL_WITHDRAW_MESSAGE = "The package has been withdrawd successfully.",
29
+ SUCCESSFUL_WITHDRAW_MESSAGE = "The package has been withdrawn successfully.",
29
30
  SUCCESSFUL_INITIALISE_MESSAGE = "The configuration file has been created successfully.",
30
31
  SUCCESSFUL_SET_OPTIONS_MESSAGE = "The options have been set successfully.",
31
32
  SUCCESSFUL_SET_SHELL_COMMANDS_MESSAGE = "The shell commands have been set successfully.";
@@ -43,6 +44,7 @@ module.exports = {
43
44
  INVALID_AFFIRMATION_MESSAGE,
44
45
  INVALID_RELEASE_NAME_MESSAGE,
45
46
  INVALID_EMAIL_ADDRESS_MESSAGE,
47
+ INVALID_REPOSITORY_NAME_MESSAGE,
46
48
  INVALID_GITHUB_HOST_NAME_MESSAGE,
47
49
  INVALID_EMAIL_ADDRESS_OR_USERNAME_MESSAGE,
48
50
  FAILED_OPEN_MESSAGE,
@@ -5,7 +5,8 @@ const post = require("../post");
5
5
  const { CLONE_API_URI } = require("../uris");
6
6
 
7
7
  function cloneOperation(proceed, abort, context) {
8
- const { releaseName } = context,
8
+ const { repositoryName } = context,
9
+ releaseName = repositoryName, ///
9
10
  uri = `${CLONE_API_URI}/${releaseName}`,
10
11
  json = {};
11
12
 
@@ -0,0 +1,136 @@
1
+ "use strict";
2
+
3
+ const { exec } = require("child_process"),
4
+ { Entries } = require("occam-entities"),
5
+ { arrayUtilities, fileSystemUtilities, asynchronousUtilities } = require("necessary");
6
+
7
+ const { retrieveOptions } = require("../configuration"),
8
+ { DEFAULT_GITHUB_HOST_NAME } = require("../defaults");
9
+
10
+ const { first } = arrayUtilities,
11
+ { forEach } = asynchronousUtilities,
12
+ { checkEntryExists } = fileSystemUtilities;
13
+
14
+ function cloneRepositoriesOperation(proceed, abort, context) {
15
+ const { releases, dependencies } = context
16
+
17
+ if (dependencies) {
18
+ const success = true;
19
+
20
+ Object.assign(context, {
21
+ success
22
+ });
23
+
24
+ forEach(releases, cloneRepositoryOperation, () => {
25
+ const { success } = context;
26
+
27
+ delete context.success;
28
+
29
+ success ?
30
+ proceed() :
31
+ abort();
32
+ }, context);
33
+
34
+ return;
35
+ }
36
+
37
+ const success = true;
38
+
39
+ Object.assign(context, {
40
+ success
41
+ });
42
+
43
+ const firstRelease = first(releases),
44
+ release = firstRelease, ///
45
+ index = Infinity,
46
+ done = null;
47
+
48
+ cloneRepositoryOperation(release, () => {
49
+ const { success } = context;
50
+
51
+ delete context.success;
52
+
53
+ success ?
54
+ proceed() :
55
+ abort();
56
+ }, done, context, index);
57
+ }
58
+
59
+ module.exports = cloneRepositoriesOperation;
60
+
61
+ function cloneRepositoryOperation(release, next, done, context, index) {
62
+ if (index === 0) {
63
+ const { headless } = context;
64
+
65
+ if (headless) {
66
+ next();
67
+
68
+ return;
69
+ }
70
+ }
71
+
72
+ const { name, quietly } = release,
73
+ entryPath = name, ///
74
+ entryExists = checkEntryExists(entryPath);
75
+
76
+ if (entryExists) {
77
+ if (!quietly) {
78
+ console.log(`Cannot clone the '${name}' package because a file or directory with that name already exists.`);
79
+ }
80
+
81
+ const success = false;
82
+
83
+ Object.assign(context, {
84
+ success
85
+ });
86
+
87
+ next();
88
+
89
+ return;
90
+ }
91
+
92
+ done = next; ///
93
+
94
+ cloneRepository(release, quietly, done);
95
+ }
96
+
97
+ function cloneRepository(release, quietly, done) {
98
+ let repository = repositoryFromRelease(release)
99
+
100
+ const options = retrieveOptions(),
101
+ { ssh } = options;
102
+
103
+ if (ssh) {
104
+ const { gitHubHostName } = ssh;
105
+
106
+ repository = repository.replace(`https://${DEFAULT_GITHUB_HOST_NAME}/`, `git@${gitHubHostName}:`)
107
+ }
108
+
109
+ const command = `git clone ${repository}.git`;
110
+
111
+ exec(command, (error) => {
112
+ if (error) {
113
+ console.log(error);
114
+ }
115
+
116
+ if (!quietly) {
117
+ const { name } = release;
118
+
119
+ console.log(name);
120
+ }
121
+
122
+ done();
123
+ });
124
+ }
125
+
126
+ function repositoryFromRelease(release) {
127
+ let { entries } = release;
128
+
129
+ const json = entries; ///
130
+
131
+ entries = Entries.fromJSON(json);
132
+
133
+ const repository = entries.getRepository();
134
+
135
+ return repository;
136
+ }
@@ -0,0 +1,184 @@
1
+ "use strict";
2
+
3
+ const { arrayUtilities, shellUtilities, fileSystemUtilities, asynchronousUtilities } = require("necessary");
4
+
5
+ const { isFileRelease } = require("../utilities/release"),
6
+ { validateAnswer } = require("../utilities/validate"),
7
+ { isAnswerAffirmative } = require("../utilities/prompt"),
8
+ { INVALID_ANSWER_MESSAGE } = require("../messages");
9
+
10
+ const { first } = arrayUtilities,
11
+ { prompt } = shellUtilities,
12
+ { forEach } = asynchronousUtilities,
13
+ { writeFile, removeEntry, checkEntryExists, isEntryDirectory } = fileSystemUtilities;
14
+
15
+ function openReleasesOperation(proceed, abort, context) {
16
+ const { releases, dependencies } = context;
17
+
18
+ if (dependencies) {
19
+ const success = true;
20
+
21
+ Object.assign(context, {
22
+ success
23
+ });
24
+
25
+ forEach(releases, openReleasePromptOperation, () => {
26
+ const { success } = context;
27
+
28
+ delete context.success;
29
+
30
+ success ?
31
+ proceed() :
32
+ abort();
33
+ }, context);
34
+
35
+ return;
36
+ }
37
+
38
+ const success = true;
39
+
40
+ Object.assign(context, {
41
+ success
42
+ });
43
+
44
+ const firstRelease = first(releases),
45
+ release = firstRelease, ///
46
+ index = Infinity,
47
+ done = null;
48
+
49
+ openReleasePromptOperation(release, () => {
50
+ const { success } = context;
51
+
52
+ delete context.success;
53
+
54
+ success ?
55
+ proceed() :
56
+ abort();
57
+ }, done, context, index);
58
+ }
59
+
60
+ module.exports = openReleasesOperation;
61
+
62
+ function openReleasePromptOperation(release, next, done, context, index) {
63
+ if (index === 0) {
64
+ const { headless } = context;
65
+
66
+ if (headless) {
67
+ next();
68
+
69
+ return;
70
+ }
71
+ }
72
+
73
+ const { name, quietly } = release,
74
+ entryPath = name, ///
75
+ entryExists = checkEntryExists(entryPath);
76
+
77
+ if (!entryExists) {
78
+ openRelease(release, quietly);
79
+
80
+ next();
81
+
82
+ return;
83
+ }
84
+
85
+ const entryDirectory = isEntryDirectory(entryPath);
86
+
87
+ if (entryDirectory) {
88
+ if (!quietly) {
89
+ console.log(`Cannot open the '${name}' package because a directory with that name already exists.`);
90
+ }
91
+
92
+ const success = false;
93
+
94
+ Object.assign(context, {
95
+ success
96
+ });
97
+
98
+ next();
99
+
100
+ return;
101
+ }
102
+
103
+ const fileName = name,
104
+ fileRelease = isFileRelease(fileName);
105
+
106
+ if (!fileRelease) {
107
+ if (!quietly) {
108
+ console.log(`The '${name}' file is not a package and therefore cannot be overwritten.`);
109
+ }
110
+
111
+ const success = false;
112
+
113
+ Object.assign(context, {
114
+ success
115
+ });
116
+
117
+ next();
118
+
119
+ return;
120
+ }
121
+
122
+ const { yes } = context;
123
+
124
+ if (yes) {
125
+ if (!quietly) {
126
+ console.log(`Overwriting the existing '${name}' package.`);
127
+ }
128
+
129
+ removeEntry(entryPath);
130
+
131
+ openRelease(release, quietly);
132
+
133
+ return;
134
+ }
135
+
136
+ const description = `Overwrite the existing '${name}' package? (y)es (n)o: `,
137
+ errorMessage = INVALID_ANSWER_MESSAGE,
138
+ validationFunction = validateAnswer, ///
139
+ options = {
140
+ description,
141
+ errorMessage,
142
+ validationFunction
143
+ };
144
+
145
+ prompt(options, (answer) => {
146
+ const valid = (answer !== null);
147
+
148
+ if (valid) {
149
+ const affirmative = isAnswerAffirmative(answer);
150
+
151
+ if (affirmative) {
152
+ removeEntry(entryPath);
153
+
154
+ openRelease(release, quietly);
155
+ }
156
+
157
+ next();
158
+
159
+ return;
160
+ }
161
+
162
+ const success = false;
163
+
164
+ Object.assign(context, {
165
+ success
166
+ });
167
+
168
+ next();
169
+ });
170
+ }
171
+
172
+ function openRelease(release, quietly) {
173
+ const { name } = release,
174
+ filePath = name, ///
175
+ releaseJSON = release, ///
176
+ releaseJSONString = JSON.stringify(releaseJSON),
177
+ content = releaseJSONString; ///
178
+
179
+ writeFile(filePath, content);
180
+
181
+ if (!quietly) {
182
+ console.log(name);
183
+ }
184
+ }
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+
3
+ const { shellUtilities } = require("necessary");
4
+
5
+ const { validateRepositoryName } = require("../../utilities/validate"),
6
+ { REPOSITORY_NAME_DESCRIPTION } = require("../../descriptions"),
7
+ { INVALID_REPOSITORY_NAME_MESSAGE } = require("../../messages");
8
+
9
+ const { prompt } = shellUtilities;
10
+
11
+ function repositoryNamePromptOperation(proceed, abort, context) {
12
+ const { repositoryName } = context,
13
+ errorMessage = INVALID_REPOSITORY_NAME_MESSAGE;
14
+
15
+ if (repositoryName !== null) {
16
+ const valid = validateRepositoryName(repositoryName);
17
+
18
+ if (valid) {
19
+ proceed();
20
+
21
+ return;
22
+ }
23
+
24
+ console.log(errorMessage);
25
+ }
26
+
27
+ const description = REPOSITORY_NAME_DESCRIPTION,
28
+ validationFunction = validateRepositoryName, ///
29
+ options = {
30
+ description,
31
+ errorMessage,
32
+ validationFunction
33
+ };
34
+
35
+ prompt(options, (answer) => {
36
+ const repositoryName = answer, ///
37
+ valid = (repositoryName !== null);
38
+
39
+ if (valid) {
40
+ Object.assign(context, {
41
+ repositoryName
42
+ });
43
+
44
+ proceed();
45
+
46
+ return;
47
+ }
48
+
49
+ abort();
50
+ });
51
+ }
52
+
53
+ module.exports = repositoryNamePromptOperation;
package/bin/options.js CHANGED
@@ -1,17 +1,17 @@
1
1
  "use strict";
2
2
 
3
- const NO_OPTION = "no",
4
- YES_OPTION = "yes",
3
+ const YES_OPTION = "yes",
5
4
  HELP_OPTION = "help",
6
5
  TAIL_OPTION = "tail",
7
6
  FOLLOW_OPTION = "follow",
8
7
  VERSION_OPTION = "version",
9
8
  QUIETLY_OPTION = "quietly",
10
9
  DRY_RUN_OPTION = "dry-run",
11
- LOG_LEVEL_OPTION = "log-level";
10
+ HEADLESS_OPTION = "headless",
11
+ LOG_LEVEL_OPTION = "log-level",
12
+ DEPENDENCIES_OPTION = "dependencies";
12
13
 
13
14
  module.exports = {
14
- NO_OPTION,
15
15
  YES_OPTION,
16
16
  HELP_OPTION,
17
17
  TAIL_OPTION,
@@ -19,5 +19,7 @@ module.exports = {
19
19
  VERSION_OPTION,
20
20
  QUIETLY_OPTION,
21
21
  DRY_RUN_OPTION,
22
- LOG_LEVEL_OPTION
22
+ HEADLESS_OPTION,
23
+ LOG_LEVEL_OPTION,
24
+ DEPENDENCIES_OPTION
23
25
  };
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+
3
+ const { fileSystemUtilities } = require("occam-file-system");
4
+
5
+ const { loadRelease } = fileSystemUtilities;
6
+
7
+ function isFileRelease(fileName) {
8
+ const projectsDirectoryPath = process.cwd(), ///
9
+ release = loadRelease(fileName, projectsDirectoryPath),
10
+ fileRelease = (release !== null);
11
+
12
+ return fileRelease;
13
+ }
14
+
15
+ module.exports = {
16
+ isFileRelease
17
+ };
@@ -14,6 +14,8 @@ function validateEmailAddress(emailAddress) { return /^[a-z0-9._%+-]+@[a-z0-9.-]
14
14
 
15
15
  function validateShellCommands(shellCommands) { return /^.*$/.test(shellCommands); }
16
16
 
17
+ function validateRepositoryName(repositoryName) { return /^[a-z0-9]{2,16}(?:-[a-z0-9]{2,16}){0,4}$/.test(repositoryName); }
18
+
17
19
  function validateGitHubHostName(gitHubHostName) { return /^[a-zA-Z0-9.\-]*$/.test(gitHubHostName); }
18
20
 
19
21
  function validateEmailAddressOrUsername(emailAddressOrUsername) {
@@ -42,6 +44,7 @@ module.exports = {
42
44
  validateReleaseName,
43
45
  validateEmailAddress,
44
46
  validateShellCommands,
47
+ validateRepositoryName,
45
48
  validateGitHubHostName,
46
49
  validateEmailAddressOrUsername
47
50
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "occam-open-cli",
3
3
  "author": "James Smith",
4
- "version": "6.0.390",
4
+ "version": "6.1.0",
5
5
  "license": "MIT, Anti-996",
6
6
  "homepage": "https://github.com/djalbat/occam-open-cli",
7
7
  "description": "Occam's package management tool.",
@@ -1,52 +0,0 @@
1
- "use strict";
2
-
3
- const { exec } = require("child_process"),
4
- { fileSystemUtilities } = require("necessary");
5
-
6
- const { checkEntryExists } = fileSystemUtilities;
7
-
8
- const { retrieveOptions } = require("../configuration"),
9
- { DEFAULT_GITHUB_HOST_NAME } = require("../defaults");
10
-
11
- function cloneOperation(proceed, abort, context) {
12
- const { releaseName } = context,
13
- path = releaseName, ///
14
- entryExists = checkEntryExists(path);
15
-
16
- if (entryExists) {
17
- const { quietly } = context;
18
-
19
- if (!quietly) {
20
- console.log(`Cannot clone the '${releaseName}' package because an entry of that name already exists.`);
21
- }
22
-
23
- proceed();
24
-
25
- return;
26
- }
27
-
28
- let { repository } = context;
29
-
30
- const options = retrieveOptions(),
31
- { ssh } = options;
32
-
33
- if (ssh) {
34
- const { gitHubHostName } = ssh;
35
-
36
- repository = repository.replace(`https://${DEFAULT_GITHUB_HOST_NAME}/`, `git@${gitHubHostName}:`)
37
- }
38
-
39
- const command = `git clone ${repository}.git`;
40
-
41
- exec(command, (error) => {
42
- if (error) {
43
- abort();
44
-
45
- return;
46
- }
47
-
48
- proceed();
49
- });
50
- }
51
-
52
- module.exports = cloneOperation;
@@ -1,92 +0,0 @@
1
- "use strict";
2
-
3
- const { exec } = require("child_process"),
4
- { Entries } = require("occam-entities"),
5
- { fileSystemUtilities, asynchronousUtilities } = require("necessary");
6
-
7
- const { retrieveOptions } = require("../configuration"),
8
- { DEFAULT_GITHUB_HOST_NAME } = require("../defaults");
9
-
10
- const { checkEntryExists } = fileSystemUtilities;
11
-
12
- const { forEach } = asynchronousUtilities;
13
-
14
- function cloneReleasesOperation(proceed, abort, context) {
15
- const { releases } = context,
16
- done = proceed; ///
17
-
18
- forEach(releases, cloneReleasePromptOperation, done, context);
19
- }
20
-
21
- module.exports = cloneReleasesOperation;
22
-
23
- function cloneReleasePromptOperation(release, next, done, context, index) {
24
- const { cloneDependencies } = context;
25
-
26
- if (!cloneDependencies) {
27
- if (index > 0) {
28
- next();
29
-
30
- return;
31
- }
32
- }
33
-
34
- const { name, quietly } = release,
35
- entryPath = name, ///
36
- entryExists = checkEntryExists(entryPath);
37
-
38
- if (entryExists) {
39
- if (!quietly) {
40
- console.log(`Cannot clone the '${name}' package because a directory of that name already exists.`);
41
- }
42
-
43
- next();
44
-
45
- return;
46
- }
47
-
48
- done = next; ///
49
-
50
- cloneRelease(release, quietly, done);
51
- }
52
-
53
- function cloneRelease(release, quietly, done) {
54
- let repository = repositoryFromRelease(release)
55
-
56
- const options = retrieveOptions(),
57
- { ssh } = options;
58
-
59
- if (ssh) {
60
- const { gitHubHostName } = ssh;
61
-
62
- repository = repository.replace(`https://${DEFAULT_GITHUB_HOST_NAME}/`, `git@${gitHubHostName}:`)
63
- }
64
-
65
- const command = `git clone ${repository}.git`;
66
-
67
- exec(command, (error) => {
68
- if (error) {
69
- console.log(error);
70
- }
71
-
72
- if (!quietly) {
73
- const { name } = release;
74
-
75
- console.log(name);
76
- }
77
-
78
- done();
79
- });
80
- }
81
-
82
- function repositoryFromRelease(release) {
83
- let { entries } = release;
84
-
85
- const json = entries; ///
86
-
87
- entries = Entries.fromJSON(json);
88
-
89
- const repository = entries.getRepository();
90
-
91
- return repository;
92
- }
@@ -1,14 +0,0 @@
1
- "use strict";
2
-
3
- function openDependenciesOperation(proceed, abort, context) {
4
- const { no } = context,
5
- openDependencies = !no;
6
-
7
- Object.assign(context, {
8
- openDependencies
9
- });
10
-
11
- proceed();
12
- }
13
-
14
- module.exports = openDependenciesOperation;
@@ -1,97 +0,0 @@
1
- "use strict";
2
-
3
- const { shellUtilities, fileSystemUtilities, asynchronousUtilities } = require("necessary");
4
-
5
- const { YES, NO} = require("../constants"),
6
- { validateAnswer } = require("../utilities/validate"),
7
- { isAnswerAffirmative } = require("../utilities/prompt"),
8
- { INVALID_ANSWER_MESSAGE } = require("../messages");
9
-
10
- const { writeFile, removeEntry, checkEntryExists, isEntryDirectory } = fileSystemUtilities;
11
-
12
- const { prompt } = shellUtilities,
13
- { forEach } = asynchronousUtilities;
14
-
15
- function openReleasesOperation(proceed, abort, context) {
16
- const { releases } = context,
17
- done = proceed; ///
18
-
19
- forEach(releases, openReleasePromptOperation, done, context);
20
- }
21
-
22
- module.exports = openReleasesOperation;
23
-
24
- function openReleasePromptOperation(release, next, done, context, index) {
25
- const { openDependencies } = context;
26
-
27
- if (!openDependencies) {
28
- if (index > 0) {
29
- next();
30
-
31
- return;
32
- }
33
- }
34
-
35
- const { name, quietly } = release,
36
- entryPath = name, ///
37
- entryExists = checkEntryExists(entryPath);
38
-
39
- if (!entryExists) {
40
- openRelease(release, quietly);
41
-
42
- next();
43
-
44
- return;
45
- }
46
-
47
- const entryDirectory = isEntryDirectory(entryPath);
48
-
49
- if (entryDirectory) {
50
- if (!quietly) {
51
- console.log(`Cannot open the '${name}' package because a directory of that name already exists.`);
52
- }
53
-
54
- next();
55
-
56
- return;
57
- }
58
-
59
- const description = `Overwrite the existing '${name}' package? (y)es (n)o: `,
60
- errorMessage = INVALID_ANSWER_MESSAGE,
61
- validationFunction = validateAnswer, ///
62
- options = {
63
- description,
64
- errorMessage,
65
- validationFunction
66
- };
67
-
68
- prompt(options, (answer) => {
69
- const valid = (answer !== null);
70
-
71
- if (valid) {
72
- const affirmative = isAnswerAffirmative(answer);
73
-
74
- if (affirmative) {
75
- removeEntry(entryPath);
76
-
77
- openRelease(release, quietly);
78
- }
79
-
80
- next();
81
- }
82
- });
83
- }
84
-
85
- function openRelease(release, quietly) {
86
- const { name } = release,
87
- filePath = name, ///
88
- releaseJSON = release, ///
89
- releaseJSONString = JSON.stringify(releaseJSON),
90
- content = releaseJSONString; ///
91
-
92
- writeFile(filePath, content);
93
-
94
- if (!quietly) {
95
- console.log(name);
96
- }
97
- }
@@ -1,56 +0,0 @@
1
- "use strict";
2
-
3
- const { shellUtilities } = require("necessary");
4
-
5
- const { YES, NO } = require("../../constants"),
6
- { isAnswerAffirmative } = require("../../utilities/prompt"),
7
- { validateAffirmation } = require("../../utilities/validate"),
8
- { INVALID_AFFIRMATION_MESSAGE } = require("../../messages"),
9
- { CLONE_DEPENDENCIES_DESCRIPTION } = require("../../descriptions");
10
-
11
- const { prompt } = shellUtilities;
12
-
13
- function cloneDependenciesPromptOperation(proceed, abort, context) {
14
- let answer = null;
15
-
16
- const { yes, no } = context;
17
-
18
- if (yes) {
19
- answer = YES;
20
- }
21
-
22
- if (no) {
23
- answer = NO;
24
- }
25
-
26
- const description = CLONE_DEPENDENCIES_DESCRIPTION,
27
- errorMessage = INVALID_AFFIRMATION_MESSAGE,
28
- validationFunction = validateAffirmation, ///
29
- options = {
30
- answer,
31
- description,
32
- errorMessage,
33
- validationFunction
34
- };
35
-
36
- prompt(options, (answer) => {
37
- const valid = (answer !== null);
38
-
39
- if (valid) {
40
- const affirmative = isAnswerAffirmative(answer),
41
- cloneDependencies = affirmative; ///
42
-
43
- Object.assign(context, {
44
- cloneDependencies
45
- });
46
-
47
- proceed();
48
-
49
- return;
50
- }
51
-
52
- abort();
53
- });
54
- }
55
-
56
- module.exports = cloneDependenciesPromptOperation;