Skip to content

Commit

Permalink
#919: Require user to agree to license (#948)
Browse files Browse the repository at this point in the history
  • Loading branch information
hohwille authored Jan 20, 2025
1 parent dbdd941 commit afc09e7
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,6 @@
*/
public final class HelpCommandlet extends Commandlet {

static final String LOGO = """
__ ___ ___ ___
╲ ╲ |_ _| ╲| __|__ _ ____ _
> > | || |) | _|/ _` (_-< || |
/_/ ___ |___|___/|___╲__,_/__/╲_, |
|___| |__/
""".replace('╲', '\\');

/** The optional commandlet to get help about. */
public final CommandletProperty commandlet;

Expand Down Expand Up @@ -54,15 +46,11 @@ public boolean isIdeRootRequired() {
return false;
}

private void printLogo() {

this.context.info(LOGO);
}

@Override
public void run() {

printLogo();
this.context.printLogo();
NlsBundle bundle = NlsBundle.of(this.context);
this.context.success(bundle.get("version-banner"), IdeVersion.get());
Commandlet cmd = this.commandlet.getValue();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import java.net.URLConnection;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
Expand All @@ -21,6 +22,7 @@
import com.devonfw.tools.ide.commandlet.CommandletManager;
import com.devonfw.tools.ide.commandlet.CommandletManagerImpl;
import com.devonfw.tools.ide.commandlet.ContextCommandlet;
import com.devonfw.tools.ide.commandlet.EnvironmentCommandlet;
import com.devonfw.tools.ide.commandlet.HelpCommandlet;
import com.devonfw.tools.ide.common.SystemPath;
import com.devonfw.tools.ide.completion.CompletionCandidate;
Expand Down Expand Up @@ -55,6 +57,7 @@
import com.devonfw.tools.ide.step.Step;
import com.devonfw.tools.ide.step.StepImpl;
import com.devonfw.tools.ide.url.model.UrlMetadata;
import com.devonfw.tools.ide.util.DateTimeUtil;
import com.devonfw.tools.ide.validation.ValidationResult;
import com.devonfw.tools.ide.validation.ValidationResultValid;
import com.devonfw.tools.ide.validation.ValidationState;
Expand All @@ -67,6 +70,8 @@ public abstract class AbstractIdeContext implements IdeContext {

private static final GitUrl IDE_URLS_GIT = new GitUrl("https://github.com/devonfw/ide-urls.git", null);

private static final String LICENSE_URL = "https://github.com/devonfw/IDEasy/blob/main/documentation/LICENSE.adoc";

private final IdeStartContextImpl startContext;

private Path ideHome;
Expand Down Expand Up @@ -869,11 +874,16 @@ private ValidationResult applyAndRun(CliArguments arguments, Commandlet cmd) {
Path settingsRepository = getSettingsGitRepository();
if (settingsRepository != null) {
if (getGitContext().isRepositoryUpdateAvailable(settingsRepository, getSettingsCommitIdPath()) ||
(getGitContext().fetchIfNeeded(settingsRepository) && getGitContext().isRepositoryUpdateAvailable(settingsRepository, getSettingsCommitIdPath()))) {
(getGitContext().fetchIfNeeded(settingsRepository) && getGitContext().isRepositoryUpdateAvailable(settingsRepository,
getSettingsCommitIdPath()))) {
interaction("Updates are available for the settings repository. If you want to apply the latest changes, call \"ide update\"");
}
}
}
boolean success = ensureLicenseAgreement(cmd);
if (!success) {
return ValidationResultValid.get();
}
cmd.run();
} finally {
if (previousLogLevel != null) {
Expand All @@ -886,6 +896,67 @@ private ValidationResult applyAndRun(CliArguments arguments, Commandlet cmd) {
return result;
}

private boolean ensureLicenseAgreement(Commandlet cmd) {

if (isTest()) {
return true; // ignore for tests
}
getFileAccess().mkdirs(this.userHomeIde);
Path licenseAgreement = this.userHomeIde.resolve(FILE_LICENSE_AGREEMENT);
if (Files.isRegularFile(licenseAgreement)) {
return true; // success, license already accepted
}
if (cmd instanceof EnvironmentCommandlet) {
// if the license was not accepted, "$(ideasy env --bash)" that is written into a variable prevents the user from seeing the question he is asked
// in such situation the user could not open a bash terminal anymore and gets blocked what would really annoy the user so we exit here without doing or
// printing anything anymore in such case.
return false;
}
boolean logLevelInfoDisabled = !this.startContext.info().isEnabled();
if (logLevelInfoDisabled) {
this.startContext.setLogLevel(IdeLogLevel.INFO, true);
}
boolean logLevelInteractionDisabled = !this.startContext.interaction().isEnabled();
if (logLevelInteractionDisabled) {
this.startContext.setLogLevel(IdeLogLevel.INTERACTION, true);
}
StringBuilder sb = new StringBuilder(1180);
sb.append(LOGO).append("""
Welcome to IDEasy!
This product (with its included 3rd party components) is open-source software and can be used free (also commercially).
It supports automatic download and installation of arbitrary 3rd party tools.
By default only open-source 3rd party tools are used (downloaded, installed, executed).
But if explicitly configured, also commercial software that requires an additional license may be used.
This happens e.g. if you configure "ultimate" edition of IntelliJ or "docker" edition of Docker (Docker Desktop).
You are solely responsible for all risks implied by using this software.
Before using IDEasy you need to read and accept the license agreement with all involved licenses.
You will be able to find it online under the following URL:
""").append(LICENSE_URL);
if (this.ideRoot != null) {
sb.append("\n\nAlso it is included in the documentation that you can find here:\n").
append(this.ideRoot.resolve(FOLDER_IDE).resolve("IDEasy.pdf").toString()).append("\n");
}
info(sb.toString());
askToContinue("Do you accept these terms of use and all license agreements?");

sb.setLength(0);
LocalDateTime now = LocalDateTime.now();
sb.append("On ").append(DateTimeUtil.formatDate(now, false)).append(" at ").append(DateTimeUtil.formatTime(now))
.append(" you accepted the IDEasy license.\n").append(LICENSE_URL);
try {
Files.writeString(licenseAgreement, sb);
} catch (Exception e) {
throw new RuntimeException("Failed to save license agreement!", e);
}
if (logLevelInfoDisabled) {
this.startContext.setLogLevel(IdeLogLevel.INFO, false);
}
if (logLevelInteractionDisabled) {
this.startContext.setLogLevel(IdeLogLevel.INTERACTION, false);
}
return true;
}

private void verifyIdeRoot() {
if (!isTest()) {
if (this.ideRoot == null) {
Expand Down
20 changes: 20 additions & 0 deletions cli/src/main/java/com/devonfw/tools/ide/context/IdeContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@ public interface IdeContext extends IdeStartContext {
/** The file where the installed software version is written to as plain text. */
String FILE_LEGACY_SOFTWARE_VERSION = ".devon.software.version";

/** The file for the license agreement. */
String FILE_LICENSE_AGREEMENT = ".license.agreement";

/** The file extension for a {@link java.util.Properties} file. */
String EXT_PROPERTIES = ".properties";

Expand All @@ -144,6 +147,15 @@ public interface IdeContext extends IdeStartContext {
*/
String SETTINGS_COMMIT_ID = ".commit.id";

/** The IDEasy ASCII logo. */
String LOGO = """
__ ___ ___ ___
╲ ╲ |_ _| ╲| __|__ _ ____ _
> > | || |) | _|/ _` (_-< || |
/_/ ___ |___|___/|___╲__,_/__/╲_, |
|___| |__/
""".replace('╲', '\\');

/**
* @return {@code true} if {@link #isOfflineMode() offline mode} is active or we are NOT {@link #isOnline() online}, {@code false} otherwise.
*/
Expand All @@ -157,6 +169,14 @@ default boolean isOffline() {
*/
boolean isOnline();

/**
* Print the IDEasy {@link #LOGO logo}.
*/
default void printLogo() {

info(LOGO);
}

/**
* Asks the user for a single string input.
*
Expand Down
23 changes: 12 additions & 11 deletions cli/src/main/package/setup
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
#!/bin/bash

function createFile() {
local fileName=$1
touch "$fileName"
echo "Created ${fileName}"
}

function createFileIfNotExists() {
local fileName=$1
if [ ! -f "${fileName}" ]; then
createFile "$fileName"
local file=$1
if [ ! -f "${file}" ]; then
touch "$file"
echo "Created ${file}"
fi
}

Expand All @@ -30,13 +25,19 @@ function doSetupInConfigFile() {

cd "$(dirname "${BASH_SOURCE:-$0}")" || exit 255
if [ "${PWD/*\//}" != "_ide" ]; then
echo -e "\033[93mInvalid installation path $PWD - you need to install IDEasy to a folder named '_ide'.\033[39m" >&2
echo -e "\033[93mInvalid installation path $PWD - you need to rename '${PWD/*\//}' to '_ide'.\033[39m" >&2
exit 1
fi
echo "Setting up IDEasy in ${PWD}"
cd ..
if [ "${PWD/*\//}" != "projects" ]; then
echo -e "\033[93mInvalid IDE_ROOT path $PWD - you need to rename '${PWD/*\//}' to 'projects'.\033[39m" >&2
exit 1
fi
export IDE_ROOT=${PWD}
source "$IDE_ROOT/_ide/functions"
source "$IDE_ROOT/_ide/functions" || exit 255
# enforce license agreement
ide -v || exit 255

doSetupInConfigFile ~/.bashrc
doSetupInConfigFile ~/.zshrc
Expand Down
1 change: 1 addition & 0 deletions cli/src/main/package/setup.bat
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ echo "%BASH%" -l -c "cd \"%CD%\";./setup"
"%BASH%" -l -c "cd \"%CD%\";./setup"
if %ERRORLEVEL% neq 0 (
echo %_fBRed%Error occurred while running setup of IDEasy in bash.%_RESET%
pause
exit /b %ERRORLEVEL%
)
echo %_fBGreen%Setup of IDEasy completed%_RESET%
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,6 @@ private void assertOptionLogMessages(IdeTestContext context) {
*/
private void assertLogoMessage(IdeTestContext context) {

assertThat(context).logAtInfo().hasMessage(HelpCommandlet.LOGO);
assertThat(context).logAtInfo().hasMessage(IdeContext.LOGO);
}
}

0 comments on commit afc09e7

Please sign in to comment.