Skip to content
This repository was archived by the owner on Jun 3, 2025. It is now read-only.

Commit 5ac4f32

Browse files
authored
Merge pull request #335 from tmc-cli/cli-context-aleksi
Cli context class
2 parents 9b4769f + 144f432 commit 5ac4f32

66 files changed

Lines changed: 1870 additions & 1618 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/main/java/fi/helsinki/cs/tmc/cli/Application.java

Lines changed: 33 additions & 174 deletions
Original file line numberDiff line numberDiff line change
@@ -3,91 +3,66 @@
33
import fi.helsinki.cs.tmc.cli.command.core.AbstractCommand;
44
import fi.helsinki.cs.tmc.cli.command.core.CommandFactory;
55
import fi.helsinki.cs.tmc.cli.io.Color;
6+
import fi.helsinki.cs.tmc.cli.io.EnvironmentUtil;
67
import fi.helsinki.cs.tmc.cli.io.HelpGenerator;
78
import fi.helsinki.cs.tmc.cli.io.Io;
8-
import fi.helsinki.cs.tmc.cli.io.TerminalIo;
9-
import fi.helsinki.cs.tmc.cli.tmcstuff.CourseInfo;
10-
import fi.helsinki.cs.tmc.cli.tmcstuff.CourseInfoIo;
11-
import fi.helsinki.cs.tmc.cli.tmcstuff.Settings;
12-
import fi.helsinki.cs.tmc.cli.tmcstuff.SettingsIo;
9+
import fi.helsinki.cs.tmc.cli.io.ShutdownHandler;
1310
import fi.helsinki.cs.tmc.cli.tmcstuff.WorkDir;
1411
import fi.helsinki.cs.tmc.cli.updater.TmcCliUpdater;
1512

16-
import fi.helsinki.cs.tmc.core.TmcCore;
17-
import fi.helsinki.cs.tmc.core.domain.Course;
18-
import fi.helsinki.cs.tmc.langs.util.TaskExecutor;
19-
import fi.helsinki.cs.tmc.langs.util.TaskExecutorImpl;
20-
2113
import org.apache.commons.cli.CommandLine;
2214
import org.apache.commons.cli.GnuParser;
2315
import org.apache.commons.cli.Options;
2416
import org.apache.commons.cli.ParseException;
2517
import org.slf4j.Logger;
2618
import org.slf4j.LoggerFactory;
2719

28-
import java.io.InputStream;
29-
import java.io.IOException;
30-
import java.nio.file.Path;
31-
import java.nio.file.Paths;
3220
import java.util.ArrayList;
3321
import java.util.Arrays;
3422
import java.util.Date;
35-
import java.util.HashMap;
3623
import java.util.List;
37-
import java.util.Properties;
24+
import java.util.Map;
3825

3926
/**
4027
* The application class for the program.
41-
* TODO: we should move all the command line related code to
42-
* somewhere else from here.
4328
*/
4429
public class Application {
4530
private static final Logger logger = LoggerFactory.getLogger(Application.class);
4631
private static final String previousUpdateDateKey = "update-date";
4732
private static final long defaultUpdateInterval = 60 * 60 * 1000;
4833
private static final String usage = "tmc [args] COMMAND [command-args]";
4934

50-
private CommandFactory commandFactory;
51-
private HashMap<String, String> properties;
52-
private TmcCore tmcCore;
53-
private Settings settings;
54-
private WorkDir workDir;
55-
private Io io;
56-
57-
private boolean inTest;
5835
private ShutdownHandler shutdownHandler;
36+
private final CliContext context;
37+
private final Io io;
5938

60-
private Options options;
61-
private GnuParser parser;
39+
private final Options options;
40+
private final GnuParser parser;
6241
private String commandName;
6342

64-
public Application(Io io) {
43+
public Application(CliContext context) {
6544
this.parser = new GnuParser();
6645
this.options = new Options();
67-
this.commandFactory = new CommandFactory();
46+
47+
this.context = context;
48+
this.io = context.getIo();
49+
6850
options.addOption("h", "help", false, "Display help information about tmc-cli");
6951
options.addOption("v", "version", false, "Give the version of the tmc-cli");
7052

71-
inTest = true;
72-
if (io == null) {
73-
inTest = false;
74-
io = new TerminalIo();
75-
shutdownHandler = new ShutdownHandler(io);
76-
Runtime.getRuntime().addShutdownHook(shutdownHandler);
53+
//TODO implement the inTests as context.property
54+
if (!context.inTests()) {
55+
shutdownHandler = new ShutdownHandler(context.getIo());
56+
shutdownHandler.enable();
7757
}
78-
79-
this.io = io;
80-
this.workDir = new WorkDir();
81-
this.properties = SettingsIo.loadProperties();
8258
}
8359

8460
public Application(Io io, WorkDir workDir) {
85-
this(io);
86-
this.workDir = workDir;
61+
this(new CliContext(io, workDir));
8762
}
8863

8964
private boolean runCommand(String name, String[] args) {
90-
AbstractCommand command = commandFactory.createCommand(this, name);
65+
AbstractCommand command = CommandFactory.createCommand(this.context, name);
9166
if (command == null) {
9267
io.println("Command " + name + " doesn't exist.");
9368
return false;
@@ -129,7 +104,7 @@ private String[] parseArgs(String[] args) {
129104
return null;
130105
}
131106
if (line.hasOption("v")) {
132-
io.println("TMC-CLI version " + getVersion());
107+
io.println("TMC-CLI version " + EnvironmentUtil.getVersion());
133108
return null;
134109
}
135110
return subArgs.toArray(new String[subArgs.size()]);
@@ -140,7 +115,9 @@ public void printHelp(String description) {
140115
}
141116

142117
public void run(String[] args) {
143-
if (!inTest) {
118+
context.setApp(this);
119+
120+
if (!context.inTests()) {
144121
versionCheck();
145122
}
146123

@@ -151,138 +128,18 @@ public void run(String[] args) {
151128

152129
runCommand(commandName, commandArgs);
153130

154-
if (!inTest) {
155-
Runtime.getRuntime().removeShutdownHook(shutdownHandler);
131+
if (!context.inTests()) {
132+
shutdownHandler.disable();
156133
}
157134
}
158135

159-
public void createTmcCore(Settings settings) {
160-
TaskExecutor tmcLangs;
161-
162-
tmcLangs = new TaskExecutorImpl();
163-
this.settings = settings;
164-
this.tmcCore = new TmcCore(settings, tmcLangs);
165-
/*XXX should we somehow check if the authentication is successful here */
166-
Path path = getWorkDir().getCourseDirectory();
167-
if (path == null) {
168-
settings.setTmcProjectDirectory(Paths.get(System.getProperty("user.dir")));
169-
return;
170-
}
171-
settings.setTmcProjectDirectory(path.getParent());
172-
}
173-
174-
public CommandFactory getCommandFactory() {
175-
return this.commandFactory;
176-
}
177-
178-
// Method is used to help testing
179-
public void setTmcCore(TmcCore tmcCore) {
180-
this.tmcCore = tmcCore;
181-
}
182-
183-
public TmcCore getTmcCore() {
184-
if (this.tmcCore == null) {
185-
SettingsIo settingsio = new SettingsIo();
186-
Settings settings;
187-
188-
if (workDir.getConfigFile() != null) {
189-
// If we're in a course directory, we load settings matching the course
190-
// Otherwise we just load the last used settings
191-
CourseInfo courseinfo = CourseInfoIo.load(workDir.getConfigFile());
192-
if (courseinfo == null) {
193-
io.println("Course configuration file "
194-
+ workDir.getConfigFile().toString()
195-
+ "is invalid.");
196-
return null;
197-
}
198-
settings = settingsio.load(courseinfo.getUsername(),
199-
courseinfo.getServerAddress());
200-
} else {
201-
settings = settingsio.load();
202-
}
203-
204-
if (settings == null) {
205-
// If no settings are present
206-
io.println("You are not logged in. Log in using: tmc login");
207-
return null;
208-
}
209-
createTmcCore(settings);
210-
}
211-
return this.tmcCore;
212-
}
213-
214-
public void setSettings(Settings settings) {
215-
this.settings = settings;
216-
}
217-
218136
public static void main(String[] args) {
219-
Application app = new Application(null);
137+
Application app = new Application(new CliContext(null));
220138
app.run(args);
221139
}
222140

223-
public static String getVersion() {
224-
String path = "/maven.prop";
225-
InputStream stream = Application.class.getResourceAsStream(path);
226-
if (stream == null) {
227-
return "n/a";
228-
}
229-
230-
Properties props = new Properties();
231-
try {
232-
props.load(stream);
233-
stream.close();
234-
return (String) props.get("version");
235-
} catch (IOException e) {
236-
logger.warn("Failed to get version", e);
237-
return "n/a";
238-
}
239-
}
240-
241-
public WorkDir getWorkDir() {
242-
return this.workDir;
243-
}
244-
245-
public void setWorkdir(WorkDir workDir) {
246-
this.workDir = workDir;
247-
}
248-
249-
public void setTmcProjectDirectory(Path path) {
250-
this.settings.setTmcProjectDirectory(path);
251-
}
252-
253-
public HashMap<String, String> getProperties() {
254-
// Loads properties from the global configuration file in .config/tmc-cli/
255-
return this.properties;
256-
}
257-
258-
public Boolean saveProperties() {
259-
// Saves properties to the global configuration file in .config/tmc-cli/
260-
return SettingsIo.saveProperties(properties);
261-
}
262-
263-
public static boolean isWindows() {
264-
String os = System.getProperty("os.name").toLowerCase();
265-
return os.contains("windows");
266-
}
267-
268-
public static int getTerminalWidth() {
269-
String colEnv = System.getenv("COLUMNS");
270-
if (colEnv != null && !colEnv.equals("")) {
271-
// Determine the terminal width - this won't work on Windows
272-
// Let's just hope our Windows users won't narrow their command prompt
273-
// We'll also enforce a minimum size of 20 columns
274-
275-
return Math.max(Integer.parseInt(colEnv), 20);
276-
} else {
277-
return 70;
278-
}
279-
}
280-
281-
public CourseInfo createCourseInfo(Course course) {
282-
return new CourseInfo(settings, course);
283-
}
284-
285141
private void versionCheck() {
142+
Map<String, String> properties = context.getProperties();
286143
String previousTimestamp = properties.get(previousUpdateDateKey);
287144
Date previous = null;
288145

@@ -303,19 +160,21 @@ private void versionCheck() {
303160
return;
304161
}
305162

306-
TmcCliUpdater update = new TmcCliUpdater(io, getVersion(), isWindows());
163+
TmcCliUpdater update = new TmcCliUpdater(io, EnvironmentUtil.getVersion(),
164+
EnvironmentUtil.isWindows());
307165
update.run();
308166

309167
long timestamp = now.getTime();
310168
properties.put(previousUpdateDateKey, Long.toString(timestamp));
311-
saveProperties();
169+
context.saveProperties();
312170
}
313171

314-
public Color.AnsiColor getColor(String context) {
315-
String propertyValue = this.properties.get(context);
172+
//TODO rename this as getColorProperty
173+
public Color.AnsiColor getColor(String propertyName) {
174+
String propertyValue = context.getProperties().get(propertyName);
316175
Color.AnsiColor color = Color.getColor(propertyValue);
317176
if (color == null) {
318-
switch (context) {
177+
switch (propertyName) {
319178
case "progressbar-left": return Color.AnsiColor.ANSI_CYAN;
320179
case "progressbar-right": return Color.AnsiColor.ANSI_CYAN;
321180
case "testresults-left": return Color.AnsiColor.ANSI_GREEN;

0 commit comments

Comments
 (0)