Refactor Version Checks (#472)

Merge branch 'master' into refactor-versionCheck

Merge branch 'master' into refactor-versionCheck

Revert "test CI"

This reverts commit b56eff092020eedf20a4abaf7a0a9a3f3c5ffe9b.

test CI

Reformat LoginActivity.java

cleanup

migrate

Working + Tests

add first UnitTest

wip ...

enum2class

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/472
Reviewed-by: M M Arif <mmarif@swatian.com>
This commit is contained in:
6543 2020-05-17 16:14:06 +00:00 committed by M M Arif
parent 7f0689524f
commit 3de4dd9463
11 changed files with 915 additions and 761 deletions

View File

@ -24,7 +24,7 @@ import org.mian.gitnex.clients.AppApiService;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.StaticGlobalVariables;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.VersionCheck;
import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.interfaces.ApiInterface;
import org.mian.gitnex.models.Commits;
import org.mian.gitnex.util.TinyDB;
@ -92,7 +92,7 @@ public class CommitsActivity extends BaseActivity {
closeActivity.setOnClickListener(onClickListener);
// if gitea is 1.12 or higher use the new limit (resultLimitNewGiteaInstances)
if(VersionCheck.compareVersion("1.12.0", tinyDb.getString("giteaVersion")) >= 1) {
if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12")) {
resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances;
}

View File

@ -18,7 +18,7 @@ import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.VersionCheck;
import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.models.Milestones;
import org.mian.gitnex.util.AppUtil;
@ -134,7 +134,7 @@ public class CreateMilestoneActivity extends BaseActivity implements View.OnClic
String finalMilestoneDueDate = null;
if(!newMilestoneDueDate.isEmpty()) {
finalMilestoneDueDate = (AppUtil.customDateCombine(AppUtil.customDateFormat(newMilestoneDueDate)));
} else if (VersionCheck.compareVersion("1.10.0", tinyDb.getString("giteaVersion")) > 1) {
} else if (new Version(tinyDb.getString("giteaVersion")).less("1.10.0")) {
// if Gitea version is less than 1.10.0 DueDate is required
Toasty.info(ctx, getString(R.string.milestoneDateEmpty));
return;

View File

@ -25,7 +25,7 @@ import org.mian.gitnex.R;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.NetworkObserver;
import org.mian.gitnex.helpers.SnackBar;
import org.mian.gitnex.helpers.VersionCheck;
import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.models.GiteaVersion;
import org.mian.gitnex.models.UserInfo;
import org.mian.gitnex.models.UserTokens;
@ -35,7 +35,6 @@ import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import okhttp3.Credentials;
import retrofit2.Call;
@ -58,7 +57,8 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
private ScrollView layoutView;
@Override
protected int getLayoutResourceId(){
protected int getLayoutResourceId() {
return R.layout.activity_login;
}
@ -89,8 +89,7 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
Resources res = getResources();
String[] allProtocols = res.getStringArray(R.array.protocolValues);
final ArrayAdapter<String> adapterProtocols = new ArrayAdapter<String>(LoginActivity.this,
R.layout.spinner_item, allProtocols);
final ArrayAdapter<String> adapterProtocols = new ArrayAdapter<String>(LoginActivity.this, R.layout.spinner_item, allProtocols);
adapterProtocols.setDropDownViewResource(R.layout.spinner_dropdown_item);
protocolSpinner.setAdapter(adapterProtocols);
@ -101,12 +100,13 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
String value = getResources().getStringArray(R.array.protocolValues)[pos];
if(value.toLowerCase().equals("http")) {
SnackBar.warning(ctx, layoutView,getResources().getString(R.string.protocolError));
SnackBar.warning(ctx, layoutView, getResources().getString(R.string.protocolError));
}
}
public void onNothingSelected(AdapterView<?> parent) {
}
});
@ -202,13 +202,14 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
@Override
public void onClick(View v) {
if (v.getId() == R.id.login_button) {
if(v.getId() == R.id.login_button) {
login();
}
}
private View.OnClickListener loginListener = new View.OnClickListener() {
public void onClick(View v) {
disableProcessButton();
@ -218,16 +219,7 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
}
};
private View.OnClickListener infoListener = v -> new Tooltip.Builder(v)
.setText(R.string.urlInfoTooltip)
.setTextColor(getResources().getColor(R.color.white))
.setBackgroundColor(getResources().getColor(R.color.tooltipBackground))
.setCancelable(true)
.setDismissOnClick(true)
.setPadding(30)
.setCornerRadius(R.dimen.tooltipCornor)
.setGravity(Gravity.BOTTOM)
.show();
private View.OnClickListener infoListener = v -> new Tooltip.Builder(v).setText(R.string.urlInfoTooltip).setTextColor(getResources().getColor(R.color.white)).setBackgroundColor(getResources().getColor(R.color.tooltipBackground)).setCancelable(true).setDismissOnClick(true).setPadding(30).setCornerRadius(R.dimen.tooltipCornor).setGravity(Gravity.BOTTOM).show();
@SuppressLint("ResourceAsColor")
private void login() {
@ -266,7 +258,8 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
URI uri = null;
try {
uri = new URI(instanceUrl);
} catch (URISyntaxException e) {
}
catch(URISyntaxException e) {
e.printStackTrace();
}
assert uri != null;
@ -357,7 +350,8 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
URI uri = null;
try {
uri = new URI(instanceUrl);
} catch (URISyntaxException e) {
}
catch(URISyntaxException e) {
e.printStackTrace();
}
assert uri != null;
@ -384,7 +378,7 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
if(connToInternet) {
if (instanceUrlET.getText().toString().equals("")) {
if(instanceUrlET.getText().toString().equals("")) {
SnackBar.warning(ctx, layoutView, getResources().getString(R.string.emptyFieldURL));
enableProcessButton();
@ -392,7 +386,7 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
return;
}
if (loginToken_.equals("")) {
if(loginToken_.equals("")) {
SnackBar.warning(ctx, layoutView, getResources().getString(R.string.loginTokenError));
enableProcessButton();
@ -416,25 +410,16 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
private void versionCheck(final String instanceUrl, final String loginUid, final String loginPass, final int loginOTP, final String loginToken_, final int loginType) {
Call<GiteaVersion> callVersion;
if (!loginToken_.isEmpty()) {
callVersion = RetrofitClient
.getInstance(instanceUrl, ctx)
.getApiInterface()
.getGiteaVersionWithToken(loginToken_);
if(!loginToken_.isEmpty()) {
callVersion = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getGiteaVersionWithToken(loginToken_);
}
else {
final String credential = Credentials.basic(loginUid, loginPass, StandardCharsets.UTF_8);
if (loginOTP != 0) {
callVersion = RetrofitClient
.getInstance(instanceUrl, ctx)
.getApiInterface()
.getGiteaVersionWithOTP(credential,loginOTP);
if(loginOTP != 0) {
callVersion = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getGiteaVersionWithOTP(credential, loginOTP);
}
else {
callVersion = RetrofitClient
.getInstance(instanceUrl, ctx)
.getApiInterface()
.getGiteaVersionWithBasic(credential);
callVersion = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getGiteaVersionWithBasic(credential);
}
}
@ -443,37 +428,33 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
@Override
public void onResponse(@NonNull final Call<GiteaVersion> callVersion, @NonNull retrofit2.Response<GiteaVersion> responseVersion) {
if (responseVersion.code() == 200) {
if(responseVersion.code() == 200) {
GiteaVersion version = responseVersion.body();
assert version != null;
VersionCheck vt = VersionCheck.check(getString(R.string.versionLow), getString(R.string.versionHigh), version.getVersion());
// init
Version gitea_version = new Version(getString(R.string.versionLow));
try {
gitea_version = new Version(version.getVersion());
}
catch(Error e) {
SnackBar.error(ctx, layoutView, getResources().getString(R.string.versionUnknow));
enableProcessButton();
}
//(getString(R.string.versionLow), getString(), version.getVersion());
switch (vt) {
case UNSUPPORTED_NEW:
//SnackBar.warning(ctx, layoutView, getResources().getString(R.string.versionUnsupportedNew));
case SUPPORTED_LATEST:
case SUPPORTED_OLD:
case DEVELOPMENT:
login(loginType, instanceUrl, loginUid, loginPass, loginOTP, loginToken_);
return;
case UNSUPPORTED_OLD:
// UNSUPPORTED_OLD
if(gitea_version.less(getString(R.string.versionLow))) {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(ctx);
alertDialogBuilder
.setTitle(getString(R.string.versionAlertDialogHeader))
.setMessage(getResources().getString(R.string.versionUnsupportedOld, version.getVersion()))
.setCancelable(true)
.setIcon(R.drawable.ic_warning)
.setNegativeButton(getString(R.string.cancelButton), (dialog, which) -> {
alertDialogBuilder.setTitle(getString(R.string.versionAlertDialogHeader)).setMessage(getResources().getString(R.string.versionUnsupportedOld, version.getVersion())).setCancelable(true).setIcon(R.drawable.ic_warning).setNegativeButton(getString(R.string.cancelButton), (dialog, which) -> {
dialog.dismiss();
enableProcessButton();
})
.setPositiveButton(getString(R.string.textContinue), (dialog, which) -> {
}).setPositiveButton(getString(R.string.textContinue), (dialog, which) -> {
dialog.dismiss();
login(loginType, instanceUrl, loginUid, loginPass, loginOTP, loginToken_);
@ -484,14 +465,22 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
alertDialog.show();
return;
default: // UNKNOWN
SnackBar.error(ctx, layoutView, getResources().getString(R.string.versionUnknow));
enableProcessButton();
}
// SUPPORTED
else if(gitea_version.lessOrEqual(getString(R.string.versionHigh))) {
login(loginType, instanceUrl, loginUid, loginPass, loginOTP, loginToken_);
return;
}
// UNSUPPORTED_NEW
else {
SnackBar.info(ctx, layoutView, getResources().getString(R.string.versionUnsupportedNew));
login(loginType, instanceUrl, loginUid, loginPass, loginOTP, loginToken_);
return;
}
}
else if (responseVersion.code() == 403) {
else if(responseVersion.code() == 403) {
login(loginType, instanceUrl, loginUid, loginPass, loginOTP, loginToken_);
@ -500,10 +489,10 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
private void login(int loginType, String instanceUrl, String loginUid, String loginPass, int loginOTP, String loginToken_) {
if (loginType == 1) {
if(loginType == 1) {
letTheUserIn(instanceUrl, loginUid, loginPass, loginOTP);
}
else if (loginType == 2) { // token
else if(loginType == 2) { // token
letTheUserInViaToken(instanceUrl, loginToken_);
}
@ -527,10 +516,7 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
final TinyDB tinyDb = new TinyDB(appCtx);
Call<UserInfo> call = RetrofitClient
.getInstance(instanceUrl, ctx)
.getApiInterface()
.getUserInfo("token " + loginToken_);
Call<UserInfo> call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getUserInfo("token " + loginToken_);
call.enqueue(new Callback<UserInfo>() {
@ -539,9 +525,9 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
UserInfo userDetails = response.body();
if (response.isSuccessful()) {
if(response.isSuccessful()) {
if (response.code() == 200) {
if(response.code() == 200) {
tinyDb.putBoolean("loggedInMode", true);
assert userDetails != null;
@ -594,18 +580,12 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
Call<List<UserTokens>> call;
if(loginOTP != 0) {
call = RetrofitClient
.getInstance(instanceUrl, ctx)
.getApiInterface()
.getUserTokensWithOTP(credential, loginOTP, loginUid);
call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getUserTokensWithOTP(credential, loginOTP, loginUid);
}
else {
call = RetrofitClient
.getInstance(instanceUrl, ctx)
.getApiInterface()
.getUserTokens(credential, loginUid);
call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getUserTokens(credential, loginUid);
}
@ -619,19 +599,19 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
final AppUtil appUtil = new AppUtil();
//Headers responseHeaders = response.headers();
if (response.isSuccessful()) {
if(response.isSuccessful()) {
if (response.code() == 200) {
if(response.code() == 200) {
boolean setTokenFlag = false;
assert userTokens != null;
if (userTokens.size() > 0) {
if(userTokens.size() > 0) {
if(userTokens.get(0).getToken_last_eight() != null) {
for (int i = 0; i < userTokens.size(); i++) {
if (userTokens.get(i).getToken_last_eight().equals(tinyDb.getString(loginUid + "-token-last-eight"))) {
for(int i = 0; i < userTokens.size(); i++) {
if(userTokens.get(i).getToken_last_eight().equals(tinyDb.getString(loginUid + "-token-last-eight"))) {
setTokenFlag = true;
break;
}
@ -641,8 +621,8 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
}
else {
for (int i = 0; i < userTokens.size(); i++) {
if (userTokens.get(i).getSha1().equals(tinyDb.getString(loginUid + "-token"))) {
for(int i = 0; i < userTokens.size(); i++) {
if(userTokens.get(i).getSha1().equals(tinyDb.getString(loginUid + "-token"))) {
setTokenFlag = true;
break;
}
@ -660,18 +640,12 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
Call<UserTokens> callCreateToken;
if(loginOTP != 0) {
callCreateToken = RetrofitClient
.getInstance(instanceUrl, ctx)
.getApiInterface()
.createNewTokenWithOTP(credential, loginOTP, loginUid, createUserToken);
callCreateToken = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().createNewTokenWithOTP(credential, loginOTP, loginUid, createUserToken);
}
else {
callCreateToken = RetrofitClient
.getInstance(instanceUrl, ctx)
.getApiInterface()
.createNewToken(credential, loginUid, createUserToken);
callCreateToken = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().createNewToken(credential, loginUid, createUserToken);
}
@ -688,12 +662,9 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
assert newToken != null;
//Log.i("Tokens-NEW", "new:" + newToken.getSha1());
if (!newToken.getSha1().equals("")) {
if(!newToken.getSha1().equals("")) {
Call<UserInfo> call = RetrofitClient
.getInstance(instanceUrl, ctx)
.getApiInterface()
.getUserInfo("token " + newToken.getSha1());
Call<UserInfo> call = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getUserInfo("token " + newToken.getSha1());
call.enqueue(new Callback<UserInfo>() {
@ -702,9 +673,9 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
UserInfo userDetails = response.body();
if (response.isSuccessful()) {
if(response.isSuccessful()) {
if (response.code() == 200) {
if(response.code() == 200) {
tinyDb.remove("loginPass");
tinyDb.putBoolean("loggedInMode", true);
@ -754,7 +725,7 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
}
else if(responseCreate.code() == 500) {
SnackBar.error(ctx, layoutView,getResources().getString(R.string.genericApiStatusError) + responseCreate.code());
SnackBar.error(ctx, layoutView, getResources().getString(R.string.genericApiStatusError) + responseCreate.code());
enableProcessButton();
loginButton.setText(R.string.btnLogin);
@ -775,10 +746,7 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
Call<UserInfo> callGetUsername = RetrofitClient
.getInstance(instanceUrl, ctx)
.getApiInterface()
.getUserInfo(instanceToken);
Call<UserInfo> callGetUsername = RetrofitClient.getInstance(instanceUrl, ctx).getApiInterface().getUserInfo(instanceToken);
callGetUsername.enqueue(new Callback<UserInfo>() {
@ -787,9 +755,9 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
UserInfo userDetails = response.body();
if (response.isSuccessful()) {
if(response.isSuccessful()) {
if (response.code() == 200) {
if(response.code() == 200) {
assert userDetails != null;
tinyDb.putString("userLogin", userDetails.getUsername());
@ -836,14 +804,14 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
}
else if(response.code() == 500) {
SnackBar.error(ctx, layoutView,getResources().getString(R.string.genericApiStatusError) + response.code());
SnackBar.error(ctx, layoutView, getResources().getString(R.string.genericApiStatusError) + response.code());
enableProcessButton();
loginButton.setText(R.string.btnLogin);
}
else {
SnackBar.error(ctx, layoutView,getResources().getString(R.string.genericApiStatusError) + response.code());
SnackBar.error(ctx, layoutView, getResources().getString(R.string.genericApiStatusError) + response.code());
enableProcessButton();
loginButton.setText(R.string.btnLogin);
@ -855,7 +823,7 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
public void onFailure(@NonNull Call<List<UserTokens>> call, @NonNull Throwable t) {
Log.e("onFailure-login", t.toString());
SnackBar.error(ctx, layoutView,getResources().getString(R.string.malformedJson));
SnackBar.error(ctx, layoutView, getResources().getString(R.string.malformedJson));
enableProcessButton();
loginButton.setText(R.string.btnLogin);
@ -868,7 +836,7 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
loginButton.setEnabled(false);
GradientDrawable shape = new GradientDrawable();
shape.setCornerRadius( 8 );
shape.setCornerRadius(8);
shape.setColor(getResources().getColor(R.color.hintColor));
loginButton.setBackground(shape);
@ -878,7 +846,7 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
loginButton.setEnabled(true);
GradientDrawable shape = new GradientDrawable();
shape.setCornerRadius( 8 );
shape.setCornerRadius(8);
shape.setColor(getResources().getColor(R.color.btnBackground));
loginButton.setBackground(shape);

View File

@ -23,7 +23,7 @@ import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.VersionCheck;
import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.models.Collaborators;
import org.mian.gitnex.models.MergePullRequest;
import org.mian.gitnex.models.MergePullRequestSpinner;
@ -110,7 +110,7 @@ public class MergePullRequestActivity extends BaseActivity {
if(!tinyDb.getString("issueTitle").isEmpty()) {
toolbar_title.setText(tinyDb.getString("issueTitle"));
mergeTitle.setText(tinyDb.getString("issueTitle") + " (#" + tinyDb.getString("issueNumber")+ ")");
mergeTitle.setText(tinyDb.getString("issueTitle") + " (#" + tinyDb.getString("issueNumber") + ")");
}
initCloseListener();
@ -140,8 +140,8 @@ public class MergePullRequestActivity extends BaseActivity {
mergeList.add(new MergePullRequestSpinner("merge", getResources().getString(R.string.mergeOptionMerge)));
mergeList.add(new MergePullRequestSpinner("rebase", getResources().getString(R.string.mergeOptionRebase)));
mergeList.add(new MergePullRequestSpinner("rebase-merge", getResources().getString(R.string.mergeOptionRebaseCommit)));
//squash merge works only on gitea v1.11.5 and higher due to a bug
if(VersionCheck.compareVersion("1.11.5", tinyDb.getString("giteaVersion")) < 1) {
//squash merge works only on gitea > v1.11.4 due to a bug
if(new Version(tinyDb.getString("giteaVersion")).higher("1.11.4")) {
mergeList.add(new MergePullRequestSpinner("squash", getResources().getString(R.string.mergeOptionSquash)));
}

View File

@ -38,7 +38,7 @@ import org.mian.gitnex.fragments.PullRequestsFragment;
import org.mian.gitnex.fragments.ReleasesFragment;
import org.mian.gitnex.fragments.RepoInfoFragment;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.VersionCheck;
import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.models.UserRepositories;
import org.mian.gitnex.models.WatchRepository;
import org.mian.gitnex.util.AppUtil;
@ -222,7 +222,7 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
}
// release count
if(VersionCheck.compareVersion("1.11.5", tinyDb.getString("giteaVersion")) < 1) {
if(new Version("1.11.4").less(tinyDb.getString("giteaVersion"))) {
if(textViewBadgeRelease.getText() != "") { // only show if API returned a number
Objects.requireNonNull(tabLayout.getTabAt(5)).setCustomView(tabHeader6);
TabLayout.Tab tabOpenRelease = tabLayout.getTabAt(5);

View File

@ -26,7 +26,7 @@ import org.mian.gitnex.clients.AppApiService;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.StaticGlobalVariables;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.VersionCheck;
import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.interfaces.ApiInterface;
import org.mian.gitnex.models.Issues;
import org.mian.gitnex.util.TinyDB;
@ -76,7 +76,7 @@ public class IssuesFragment extends Fragment {
final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefresh);
// if gitea is 1.12 or higher use the new limit
if(VersionCheck.compareVersion("1.12.0", tinyDb.getString("giteaVersion")) >= 1) {
if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) {
resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances;
}

View File

@ -27,7 +27,7 @@ import org.mian.gitnex.clients.AppApiService;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.StaticGlobalVariables;
import org.mian.gitnex.helpers.Toasty;
import org.mian.gitnex.helpers.VersionCheck;
import org.mian.gitnex.helpers.Version;
import org.mian.gitnex.interfaces.ApiInterface;
import org.mian.gitnex.models.PullRequests;
import org.mian.gitnex.util.TinyDB;
@ -76,7 +76,7 @@ public class PullRequestsFragment extends Fragment {
final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefresh);
// if gitea is 1.12 or higher use the new limit
if(VersionCheck.compareVersion("1.12.0", tinyDb.getString("giteaVersion")) >= 1) {
if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) {
resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances;
}

View File

@ -0,0 +1,222 @@
package org.mian.gitnex.helpers;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Author 6543
*/
public class Version {
// the raw String
private String raw;
// the version numbers in its order (dot separated)
private List<Integer> values;
public Version(String value) {
raw = value;
this.init();
}
/**
* init parse and store values for other functions of an Version instance
* it use the raw variable as base
*
* @return if parse was successfully
*/
private void init() {
final Pattern pattern_valid = Pattern.compile("^[v,V]?(\\d+)+(\\.(\\d+))*([_,\\-,+][\\w,\\d,_,\\-,+]*)?$");
final Pattern pattern_number_dot_number = Pattern.compile("^\\d+(\\.(\\d)+)*");
if(!pattern_valid.matcher(raw).find()) {
throw new IllegalArgumentException("Invalid version format");
}
if(raw.charAt(0) == 'v' || raw.charAt(0) == 'V') {
raw = raw.substring(1);
}
values = new ArrayList<Integer>();
Matcher match = pattern_number_dot_number.matcher(raw);
match.find();
for(String i : match.group().split("\\.")) {
values.add(Integer.parseInt(i));
}
}
/**
* equal return true if version is the same
*
* @param value
* @return true/false
*/
public boolean equal(String value) {
return this.equal(new Version(value));
}
/**
* equal return true if version is the same
*
* @param v
* @return
*/
public boolean equal(@NotNull Version v) {
int rounds = Math.min(this.values.size(), v.values.size());
for(int i = 0; i < rounds; i++) {
if(this.values.get(i) != v.values.get(i)) {
return false;
}
}
return true;
}
/**
* less return true if version is less
*
* @param value
* @return true/false
*/
public boolean less(String value) {
return this.less(new Version(value));
}
/**
* less return true if version is less
*
* @param v
* @return
*/
public boolean less(@NotNull Version v) {
int rounds = Math.min(this.values.size(), v.values.size());
for(int i = 0; i < rounds; i++) {
if(i + 1 == rounds) {
if(this.values.get(i) >= v.values.get(i)) {
return false;
}
}
else {
if(this.values.get(i) > v.values.get(i)) {
return false;
}
}
}
return true;
}
/**
* higher return true if version is higher
*
* @param value
* @return true/false
*/
public boolean higher(String value) {
return this.higher(new Version(value));
}
/**
* higher return true if version is higher
*
* @param v
* @return
*/
public boolean higher(@NotNull Version v) {
int rounds = Math.min(this.values.size(), v.values.size());
for(int i = 0; i < rounds; i++) {
if(i + 1 == rounds) {
if(this.values.get(i) <= v.values.get(i)) {
return false;
}
}
else {
if(this.values.get(i) < v.values.get(i)) {
return false;
}
}
}
return true;
}
/**
* lessOrEqual return true if version is less or equal
*
* @param value
* @return true/false
*/
public boolean lessOrEqual(String value) {
return this.lessOrEqual(new Version(value));
}
/**
* lessOrEqual return true if version is less or equal
*
* @param v
* @return
*/
public boolean lessOrEqual(@NotNull Version v) {
int rounds = Math.min(this.values.size(), v.values.size());
for(int i = 0; i < rounds; i++) {
if(this.values.get(i) > v.values.get(i)) {
return false;
}
}
return true;
}
/**
* higherOrEqual return true if version is higher or equal
*
* @param value
* @return true/false
*/
public boolean higherOrEqual(String value) {
return this.higherOrEqual(new Version(value));
}
/**
* higherOrEqual return true if version is higher or equal
*
* @param v
* @return
*/
public boolean higherOrEqual(@NotNull Version v) {
int rounds = Math.min(this.values.size(), v.values.size());
for(int i = 0; i < rounds; i++) {
if(this.values.get(i) < v.values.get(i)) {
return false;
}
}
return true;
}
}

View File

@ -1,151 +0,0 @@
package org.mian.gitnex.helpers;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Author 6543
*/
public enum VersionCheck {
UNKNOWN,
SUPPORTED_LATEST,
SUPPORTED_OLD,
DEVELOPMENT,
UNSUPPORTED_OLD,
UNSUPPORTED_NEW;
public static VersionCheck check(String min, String last, String value) {
final Pattern pattern_stable_release = Pattern.compile("^(\\d)\\.(\\d+)\\.(\\d+)$");
final Pattern pattern_dev_release = Pattern.compile("^(\\d).(\\d+).(\\d+)(\\D)(.+)");
Matcher match;
if (!pattern_stable_release.matcher(min).find() || !pattern_stable_release.matcher(last).find()) {
throw new IllegalArgumentException("VersionCheck: wrong format for min or last version given");
}
match = pattern_stable_release.matcher(value);
if (match.find()) {
switch (correlate(min, last, match.group())){
case 0:
return UNSUPPORTED_OLD;
case 1:
return SUPPORTED_OLD;
case 2:
return SUPPORTED_LATEST;
default:
return UNSUPPORTED_NEW;
}
}
match = pattern_dev_release.matcher(value);
if (match.find()) {
match = Pattern.compile("^(\\d)\\.(\\d+)\\.(\\d+)").matcher(value);
match.find();
if (correlate(min, last, match.group())>0) {
return DEVELOPMENT;
}
else {
return UNSUPPORTED_OLD;
}
}
return UNKNOWN;
}
//helper
// 0 to less
// 1 in range
// 2 at the top
// 3 above
private static int correlate(String min, String last, String value){
int min_check = compareVersion(value,min);
int max_check = compareVersion(value,last);
int range_check = compareVersion(min,last);
switch (range_check) {
case 2:
throw new IllegalArgumentException("Minimum Version higher than Last Version");
case 1: //min == last
switch (min_check) {
case 0:
return 0;
case 1:
return 2;
default:
return 3;
}
default:
if (max_check >1) return 3;
if (max_check == 1) return 2;
if (min_check < 1) return 0;
return 1;
}
}
/**
* @description compare doted formatted Versions
* @param A doted formatted Versions
* @param B doted formatted Versions
* @return 0|1|2
* 0 = less
* 1 = same
* 2 = more
*/
public static int compareVersion(String A, String B) {
final Pattern pattern_stable_release = Pattern.compile("^(\\d)\\.(\\d+)\\.(\\d+)");
final Pattern pattern_dev_release = Pattern.compile("^(\\d).(\\d+).(\\d+)(\\D)(.+)");
Matcher match;
match = pattern_dev_release.matcher(A);
if (match.find()) {
match = pattern_stable_release.matcher(A);
match.find();
A = match.group();
}
match = pattern_dev_release.matcher(B);
if (match.find()) {
match = pattern_stable_release.matcher(B);
match.find();
B = match.group();
}
//throw new IllegalArgumentException
if((!A.matches("[0-9]+(\\.[0-9]+)*")) || (!B.matches("[0-9]+(\\.[0-9]+)*"))) throw new IllegalArgumentException("Invalid version format");
if (A.contains(".") || B.contains(".")) {
// example 2 vs 1.3
if (!(A.contains(".") && B.contains("."))) {
if (A.contains(".")) {
return compareVersion(A,B + ".0");
}
if (B.contains(".")) {
return compareVersion(A + ".0",B);
}
}
//normal compare
int a = Integer.parseInt(A.substring(0,A.indexOf(".")));
int b = Integer.parseInt(B.substring(0,B.indexOf(".")));
if (a < b) return 0;
if (a == b) return compareVersion(A.substring(A.indexOf(".")+1),B.substring(B.indexOf(".")+1));
return 2; //if (a > b)
}
else {
int a = Integer.parseInt(A);
int b = Integer.parseInt(B);
if (a < b) return 0;
if (a == b) return 1;
return 2; //if (a > b)
}
}
}

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="versionLow" translatable="false">1.10.0</string>
<string name="versionHigh" translatable="false">1.11.15</string>
<string name="versionLow" translatable="false">1.10</string>
<string name="versionHigh" translatable="false">1.12</string>
</resources>

View File

@ -0,0 +1,115 @@
package org.mian.gitnex.helpers;
/**
* Author 6543
*/
import org.junit.Test;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class VersionTest {
@Test
public void equal() {
assertTrue(new Version("1.12.0").equal("1.12.0"));
assertTrue(new Version("1.12.0").equal(new Version("1.12.0")));
assertTrue(new Version("1.12.0").equal("1.12"));
assertTrue(new Version("1.12.0").equal("1.12.0+dev-211-g316db0fe7"));
assertTrue(new Version("1.12.0").equal("v1.12"));
assertTrue(new Version("v1.12.0").equal("1.12.0"));
assertTrue(new Version("0").equal("0"));
assertFalse(new Version("1.12.1").equal("1.12.0+dev-211-g316db0fe7"));
assertFalse(new Version("v1.12.0").equal("1.10.0"));
assertFalse(new Version("2.12.0").equal("v1.12"));
assertFalse(new Version("1.12").equal("2"));
assertFalse(new Version("2").equal("1"));
assertFalse(new Version("1.2").equal("2.1"));
assertFalse(new Version("2.2").equal("2.1.120"));
}
@Test
public void less() {
assertTrue(new Version("1.11.0").less("1.12"));
assertTrue(new Version("v1.11").less("1.12.0+dev-211-g316db0fe7"));
assertTrue(new Version("1.12.0").less("v2"));
assertTrue(new Version("v1.12.0").less("1.12.1-wowowow"));
assertTrue(new Version("1.2.3").less("1.2.4"));
assertFalse(new Version("1").less("1.1.10"));
assertFalse(new Version("1.12.1").less("1.12.0+dev-211-g316db0fe7"));
assertFalse(new Version("1.12.0").less("1.12.0"));
assertFalse(new Version("v1.12.0").less("1.10.0"));
assertFalse(new Version("2.12.0").less("v1.12"));
assertFalse(new Version("2").less("1"));
assertFalse(new Version("1.2").less("2.1"));
assertFalse(new Version("2.2").less("2.1.120"));
}
@Test
public void lessOrEqual() {
assertTrue(new Version("1.11.0").lessOrEqual("1.12"));
assertTrue(new Version("v1.11").lessOrEqual("1.12.0+dev-211-g316db0fe7"));
assertTrue(new Version("1.12.0").lessOrEqual("v2"));
assertTrue(new Version("v1.12.0").lessOrEqual("1.12.1-wowowow"));
assertTrue(new Version("1.2.3").lessOrEqual("1.2.4"));
assertTrue(new Version("1").lessOrEqual("1.1.10"));
assertTrue(new Version("1.12.0").lessOrEqual("1.12.0"));
assertFalse(new Version("1.12.1").lessOrEqual("1.12.0+dev-211-g316db0fe7"));
assertFalse(new Version("v1.12.0").lessOrEqual("1.10.0"));
assertFalse(new Version("2.12.0").lessOrEqual("v1.12"));
assertFalse(new Version("2").lessOrEqual("1"));
assertFalse(new Version("1.2").lessOrEqual("2.1"));
assertFalse(new Version("2.2").lessOrEqual("2.1.120"));
}
@Test
public void higher() {
assertTrue(new Version("1.12").higher("1.11.0"));
assertTrue(new Version("1.12.0+dev-211-g316db0fe7").higher("v1.11"));
assertTrue(new Version("v2").higher("1.12.0"));
assertTrue(new Version("1.12.1-wowowow").higher("v1.12.0"));
assertTrue(new Version("1.2.4").higher("1.2.3"));
assertFalse(new Version("1").higher("1.1.10"));
assertFalse(new Version("1.12.0+dev-211-g316db0fe7").higher("1.12.1"));
assertFalse(new Version("1.12.0").higher("1.12.0"));
assertFalse(new Version("1.10.0").higher("v1.12.0"));
assertFalse(new Version("v1.12").higher("2.12.0"));
assertFalse(new Version("1").higher("2"));
assertFalse(new Version("2.1").higher("1.2"));
assertFalse(new Version("2.1.120").higher("2.2"));
}
@Test
public void higherOrEqual() {
assertTrue(new Version("1.12").higherOrEqual("1.11.0"));
assertTrue(new Version("1.12.0+dev-211-g316db0fe7").higherOrEqual("v1.11"));
assertTrue(new Version("v2").higherOrEqual("1.12.0"));
assertTrue(new Version("1.12.1-wowowow").higherOrEqual("v1.12.0"));
assertTrue(new Version("1.2.4").higherOrEqual("1.2.3"));
assertTrue(new Version("1").higherOrEqual("1.1.10"));
assertTrue(new Version("1.12.0").higherOrEqual("1.12.0"));
assertFalse(new Version("1.12.0+dev-211-g316db0fe7").higherOrEqual("1.12.1"));
assertFalse(new Version("1.10.0").higherOrEqual("v1.12.0"));
assertFalse(new Version("v1.12").higherOrEqual("2.12.0"));
assertFalse(new Version("1").higherOrEqual("2"));
assertFalse(new Version("2.1").higherOrEqual("1.2"));
assertFalse(new Version("2.1.120").higherOrEqual("2.2"));
}
}