Merge branch 'stable-2.15'
* stable-2.15: ChangeIT: Temporarily disable tests related to group matching Align SSH create-project with REST API SubmoduleOp: Fix formatting of submodule update commit message Fix Postgresql JDBC driver leaking memory Document that the build works with Python 2 or 3 merge_jars.py: Fix for python 3 compatibility project.py: decode byte output from check_result license and doc: Add support for python3 Bazel: Make build tool chain python 3 compatible ExternalIds NoteDb migration: Avoid intermediate migration state Make PrivateStateChanged and WorkInProgressStateChanged singletons BatchProgramModule: Bind GitReferenceUpdated.DISABLED BatchProgramModule: Don't bind event classes to null Document that Python 2 is required by the build Make event firing classes singleton Fix ConcurrentModificationException when posting reviews Revert partially "Trim multi-line arguments for task name and ssh_log" BaseCommand: Fix formatting of task description with arguments Add analytics to the list of plugins config-plugins: Consistently use "/+doc/" for documentation links config-plugins: Fix link to ref-protection plugin documentation config-plugins: Add readonly plugin to plugin list Add documentation for SshCreateCommandInterceptor Allow plugins to intercept ssh command creation GWT/Poly: Default to "Create initial commit" during project creation Revert "Reduce chance of deadlock in account cache" commit-msg: Adapt to awk behavior change on Cygwin/MSYS Expand docs on how to include external dependencies in core plugins Document how to bundle custom plugins in release.war Group members can't be added as reviewers if a matched username exists Set version to 2.13.11 StreamEventsApiListener: Prevent NPE when account is null Set version to 2.11.11 Replace links to code.google.com/p/gerrit Update issue tracker URL in documentation Update issue tracker URL in POM files Bump jsch to 0.54 Update jsch to 0.1.53 Bump Jsch to 1.52 Change-Id: Icec3dcfe53146da7d66d4d690afdd9e77ee10380
This commit is contained in:
@@ -60,7 +60,14 @@ This command is intended to be used in scripts.
|
||||
|
||||
--owner::
|
||||
-o::
|
||||
Name of the group(s) which will initially own this repository.
|
||||
Identifier of the group(s) which will initially own this repository.
|
||||
|
||||
This can be:
|
||||
|
||||
* the UUID of the group
|
||||
* the legacy numeric ID of the group
|
||||
* the name of the group if it is unique
|
||||
|
||||
The specified group(s) must already be defined within Gerrit.
|
||||
Several groups can be specified on the command line.
|
||||
+
|
||||
|
@@ -119,7 +119,7 @@ This plugin allows users to configure different review strategies.
|
||||
|
||||
link:https://gerrit-review.googlesource.com/#/admin/projects/plugins/review-strategy[
|
||||
Project] |
|
||||
link:https://gerrit.googlesource.com/plugins/review-strategy/+/master/src/main/resources/Documentation/about.md[
|
||||
link:https://gerrit.googlesource.com/plugins/review-strategy/+doc/master/src/main/resources/Documentation/about.md[
|
||||
Documentation]
|
||||
|
||||
[[singleusergroup]]
|
||||
@@ -161,6 +161,18 @@ Project] |
|
||||
link:https://gerrit.googlesource.com/plugins/admin-console/+doc/master/src/main/resources/Documentation/about.md[
|
||||
Documentation]
|
||||
|
||||
[[analytics]]
|
||||
=== analytics
|
||||
|
||||
Plugin to extract commit and review data from Gerrit projects and
|
||||
expose aggregated metrics over REST and SSH API.
|
||||
Metrics are extracted in JSON format with one record per line, ready to be
|
||||
archived and processed with popular BigData transformation tools such
|
||||
Apache Spark or published and visualized in dashboards.
|
||||
|
||||
link:https://gerrit-review.googlesource.com/#/admin/projects/plugins/analytics[Project] |
|
||||
link:https://gerrit.googlesource.com/plugins/analytics/+doc/master/README.md[Documentation]
|
||||
|
||||
[[avatars-external]]
|
||||
=== avatars-external
|
||||
|
||||
@@ -473,7 +485,7 @@ This plugin provides a Prolog predicate `add_owner_approval/3` that
|
||||
appends `label('Owner-Approval', need(_))` to a provided list.
|
||||
|
||||
link:https://gerrit-review.googlesource.com/#/admin/projects/plugins/owners[Project] |
|
||||
link:https://gerrit.googlesource.com/plugins/owners/+/refs/heads/master/README.md[Documentation]
|
||||
link:https://gerrit.googlesource.com/plugins/owners/+doc/master/README.md[Documentation]
|
||||
|
||||
[[project-download-commands]]
|
||||
=== project-download-commands
|
||||
@@ -507,6 +519,19 @@ Documentation]
|
||||
link:https://gerrit.googlesource.com/plugins/quota/+doc/master/src/main/resources/Documentation/config.md[
|
||||
Configuration]
|
||||
|
||||
[[readonly]]
|
||||
=== readonly
|
||||
|
||||
A plugin that makes the Gerrit server read-only by rejecting git pushes,
|
||||
blocking HTTP PUT/POST/DELETE requests, and disabling SSH commands.
|
||||
|
||||
link:https://gerrit-review.googlesource.com/#/admin/projects/plugins/readonly[
|
||||
Project] |
|
||||
link:https://gerrit.googlesource.com/plugins/readonly/+doc/master/src/main/resources/Documentation/about.md[
|
||||
Documentation] |
|
||||
link:https://gerrit.googlesource.com/plugins/readonly/+doc/master/src/main/resources/Documentation/config.md[
|
||||
Configuration]
|
||||
|
||||
[[ref-protection]]
|
||||
=== ref-protection
|
||||
|
||||
@@ -517,7 +542,7 @@ Backups of deleted or non-fast-forward updated refs are created under the
|
||||
|
||||
link:https://gerrit-review.googlesource.com/#/admin/projects/plugins/ref-protection[
|
||||
Project] |
|
||||
link:https://gerrit.googlesource.com/plugins/ref-protection/+/refs/heads/stable-2.11/src/main/resources/Documentation/about.md[
|
||||
link:https://gerrit.googlesource.com/plugins/ref-protection/+doc/master/src/main/resources/Documentation/about.md[
|
||||
Documentation]
|
||||
|
||||
[[reparent]]
|
||||
|
@@ -7,6 +7,7 @@ To build Gerrit from source, you need:
|
||||
|
||||
* A Linux or macOS system (Windows is not supported at this time)
|
||||
* A JDK for Java 8
|
||||
* Python 2 or 3
|
||||
* Node.js
|
||||
* link:https://www.bazel.io/versions/master/docs/install.html[Bazel]
|
||||
|
||||
|
@@ -2716,6 +2716,26 @@ public class MyPlugin implements MailFilter {
|
||||
}
|
||||
----
|
||||
|
||||
[[ssh-command-interception]]
|
||||
== SSH Command Interception
|
||||
|
||||
Gerrit provides an extension point that allows a plugin to intercept
|
||||
creation of SSH commands and override the functionality with its own
|
||||
implementation.
|
||||
|
||||
[source, java]
|
||||
----
|
||||
import com.google.gerrit.sshd.SshCreateCommandInterceptor;
|
||||
|
||||
class MyCommandInterceptor implements SshCreateCommandInterceptor {
|
||||
@Override
|
||||
public String intercept(String in) {
|
||||
return pluginName + " mycommand";
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
|
||||
== SEE ALSO
|
||||
|
||||
* link:js-api.html[JavaScript API]
|
||||
|
@@ -229,12 +229,16 @@ opts.add_option('--no-searchbox', action="store_false", dest='searchbox',
|
||||
options, _ = opts.parse_args()
|
||||
|
||||
try:
|
||||
try:
|
||||
out_file = open(options.out, 'w', errors='ignore')
|
||||
src_file = open(options.src, 'r', errors='ignore')
|
||||
except TypeError:
|
||||
out_file = open(options.out, 'w')
|
||||
src_file = open(options.src, 'r')
|
||||
last_line = ''
|
||||
ignore_next_line = False
|
||||
last_title = ''
|
||||
for line in src_file.xreadlines():
|
||||
for line in src_file:
|
||||
if PAT_GERRIT.match(last_line):
|
||||
# Case of "GERRIT\n------" at the footer
|
||||
out_file.write(GERRIT_UPLINK)
|
||||
|
@@ -130,6 +130,7 @@ public class CreateProjectScreen extends Screen {
|
||||
addGrid(fp);
|
||||
|
||||
emptyCommit = new CheckBox(AdminConstants.I.checkBoxEmptyCommit());
|
||||
emptyCommit.setValue(true);
|
||||
permissionsOnly = new CheckBox(AdminConstants.I.checkBoxPermissionsOnly());
|
||||
fp.add(emptyCommit);
|
||||
fp.add(permissionsOnly);
|
||||
|
@@ -1161,6 +1161,14 @@ public abstract class AbstractDaemonTest {
|
||||
return createGroup(name, "Administrators");
|
||||
}
|
||||
|
||||
protected String createGroupWithRealName(String name) throws Exception {
|
||||
GroupInput in = new GroupInput();
|
||||
in.name = name;
|
||||
in.ownerId = "Administrators";
|
||||
gApi.groups().create(in);
|
||||
return name;
|
||||
}
|
||||
|
||||
protected String createGroup(String name, String owner) throws Exception {
|
||||
name = name(name);
|
||||
GroupInput in = new GroupInput();
|
||||
|
@@ -29,7 +29,6 @@ import com.google.gerrit.pgm.util.ThreadLimiter;
|
||||
import com.google.gerrit.reviewdb.client.Change;
|
||||
import com.google.gerrit.reviewdb.client.Project;
|
||||
import com.google.gerrit.server.change.ChangeResource;
|
||||
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
|
||||
import com.google.gerrit.server.index.DummyIndexModule;
|
||||
import com.google.gerrit.server.index.change.ChangeSchemaDefinitions;
|
||||
import com.google.gerrit.server.notedb.rebuild.NoteDbMigrator;
|
||||
@@ -189,7 +188,6 @@ public class MigrateToNoteDb extends SiteProgram {
|
||||
@Override
|
||||
public void configure() {
|
||||
install(dbInjector.getInstance(BatchProgramModule.class));
|
||||
bind(GitReferenceUpdated.class).toInstance(GitReferenceUpdated.DISABLED);
|
||||
install(new DummyIndexModule());
|
||||
factory(ChangeResource.Factory.class);
|
||||
}
|
||||
|
@@ -32,7 +32,6 @@ import com.google.gerrit.pgm.util.SiteProgram;
|
||||
import com.google.gerrit.pgm.util.ThreadLimiter;
|
||||
import com.google.gerrit.server.change.ChangeResource;
|
||||
import com.google.gerrit.server.config.GerritServerConfig;
|
||||
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
|
||||
import com.google.gerrit.server.index.IndexModule;
|
||||
import com.google.gerrit.server.index.IndexModule.IndexType;
|
||||
import com.google.gerrit.server.index.change.ChangeSchemaDefinitions;
|
||||
@@ -166,7 +165,6 @@ public class Reindex extends SiteProgram {
|
||||
@Override
|
||||
protected void configure() {
|
||||
factory(ChangeResource.Factory.class);
|
||||
bind(GitReferenceUpdated.class).toInstance(GitReferenceUpdated.DISABLED);
|
||||
}
|
||||
});
|
||||
|
||||
|
@@ -51,6 +51,9 @@ import com.google.gerrit.server.config.DisableReverseDnsLookupProvider;
|
||||
import com.google.gerrit.server.config.GerritServerConfig;
|
||||
import com.google.gerrit.server.config.GitReceivePackGroups;
|
||||
import com.google.gerrit.server.config.GitUploadPackGroups;
|
||||
import com.google.gerrit.server.extensions.events.EventUtil;
|
||||
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
|
||||
import com.google.gerrit.server.extensions.events.RevisionCreated;
|
||||
import com.google.gerrit.server.git.MergeUtil;
|
||||
import com.google.gerrit.server.git.SearchingChangeCacheImpl;
|
||||
import com.google.gerrit.server.git.TagCache;
|
||||
@@ -169,6 +172,9 @@ public class BatchProgramModule extends FactoryModule {
|
||||
factory(SubmitRuleEvaluator.Factory.class);
|
||||
|
||||
bind(ChangeJson.Factory.class).toProvider(Providers.<ChangeJson.Factory>of(null));
|
||||
bind(EventUtil.class).toProvider(Providers.<EventUtil>of(null));
|
||||
bind(GitReferenceUpdated.class).toInstance(GitReferenceUpdated.DISABLED);
|
||||
bind(RevisionCreated.class).toInstance(RevisionCreated.DISABLED);
|
||||
bind(AccountVisibility.class).toProvider(AccountVisibilityProvider.class).in(SINGLETON);
|
||||
}
|
||||
}
|
||||
|
@@ -14,12 +14,18 @@
|
||||
|
||||
package com.google.gerrit.server.args4j;
|
||||
|
||||
import com.google.gerrit.common.data.GroupDescription;
|
||||
import com.google.gerrit.common.data.GroupReference;
|
||||
import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||
import com.google.gerrit.server.account.GroupBackend;
|
||||
import com.google.gerrit.server.account.GroupBackends;
|
||||
import com.google.gerrit.server.account.GroupCache;
|
||||
import com.google.gerrit.server.account.GroupControl;
|
||||
import com.google.gerrit.server.group.InternalGroup;
|
||||
import com.google.gerrit.server.group.InternalGroupDescription;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
import java.util.Optional;
|
||||
import org.kohsuke.args4j.CmdLineException;
|
||||
import org.kohsuke.args4j.CmdLineParser;
|
||||
import org.kohsuke.args4j.OptionDef;
|
||||
@@ -29,20 +35,50 @@ import org.kohsuke.args4j.spi.Setter;
|
||||
|
||||
public class AccountGroupUUIDHandler extends OptionHandler<AccountGroup.UUID> {
|
||||
private final GroupBackend groupBackend;
|
||||
private final GroupControl.Factory groupControlFactory;
|
||||
private final GroupCache groupCache;
|
||||
|
||||
@Inject
|
||||
public AccountGroupUUIDHandler(
|
||||
final GroupBackend groupBackend,
|
||||
final GroupControl.Factory groupControlFactory,
|
||||
@Assisted final CmdLineParser parser,
|
||||
@Assisted final OptionDef option,
|
||||
@Assisted final Setter<AccountGroup.UUID> setter) {
|
||||
@Assisted final Setter<AccountGroup.UUID> setter,
|
||||
GroupCache groupCache) {
|
||||
super(parser, option, setter);
|
||||
this.groupBackend = groupBackend;
|
||||
this.groupControlFactory = groupControlFactory;
|
||||
this.groupCache = groupCache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int parseArguments(Parameters params) throws CmdLineException {
|
||||
final String n = params.getParameter(0);
|
||||
AccountGroup.UUID uuid = new AccountGroup.UUID(n);
|
||||
if (groupBackend.handles(uuid)) {
|
||||
GroupDescription.Basic d = groupBackend.get(uuid);
|
||||
if (d != null) {
|
||||
setter.addValue(uuid);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Might be a numeric AccountGroup.Id. -> Internal group.
|
||||
if (n.matches("^[1-9][0-9]*$")) {
|
||||
try {
|
||||
AccountGroup.Id groupId = AccountGroup.Id.parse(n);
|
||||
Optional<InternalGroup> groupInternal = groupCache.get(groupId);
|
||||
if (groupInternal.isPresent()) {
|
||||
uuid = new InternalGroupDescription(groupInternal.get()).getGroupUUID();
|
||||
setter.addValue(uuid);
|
||||
return 1;
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Ignored
|
||||
}
|
||||
}
|
||||
|
||||
GroupReference group = GroupBackends.findExactSuggestion(groupBackend, n);
|
||||
if (group == null) {
|
||||
throw new CmdLineException(owner, "Group \"" + n + "\" does not exist");
|
||||
|
@@ -19,7 +19,9 @@ import com.google.gerrit.extensions.events.AgreementSignupListener;
|
||||
import com.google.gerrit.extensions.registration.DynamicSet;
|
||||
import com.google.gerrit.server.account.AccountState;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
@Singleton
|
||||
public class AgreementSignup {
|
||||
private final DynamicSet<AgreementSignupListener> listeners;
|
||||
private final EventUtil util;
|
||||
|
@@ -23,10 +23,12 @@ import com.google.gerrit.reviewdb.client.Change;
|
||||
import com.google.gerrit.server.account.AccountState;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import java.sql.Timestamp;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@Singleton
|
||||
public class AssigneeChanged {
|
||||
private static final Logger log = LoggerFactory.getLogger(AssigneeChanged.class);
|
||||
|
||||
|
@@ -29,11 +29,13 @@ import com.google.gerrit.server.patch.PatchListObjectTooLargeException;
|
||||
import com.google.gerrit.server.permissions.PermissionBackendException;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import java.io.IOException;
|
||||
import java.sql.Timestamp;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@Singleton
|
||||
public class ChangeAbandoned {
|
||||
private static final Logger log = LoggerFactory.getLogger(ChangeAbandoned.class);
|
||||
|
||||
|
@@ -29,11 +29,13 @@ import com.google.gerrit.server.patch.PatchListObjectTooLargeException;
|
||||
import com.google.gerrit.server.permissions.PermissionBackendException;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import java.io.IOException;
|
||||
import java.sql.Timestamp;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@Singleton
|
||||
public class ChangeMerged {
|
||||
private static final Logger log = LoggerFactory.getLogger(ChangeMerged.class);
|
||||
|
||||
|
@@ -29,11 +29,13 @@ import com.google.gerrit.server.patch.PatchListObjectTooLargeException;
|
||||
import com.google.gerrit.server.permissions.PermissionBackendException;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import java.io.IOException;
|
||||
import java.sql.Timestamp;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@Singleton
|
||||
public class ChangeRestored {
|
||||
private static final Logger log = LoggerFactory.getLogger(ChangeRestored.class);
|
||||
|
||||
|
@@ -21,10 +21,12 @@ import com.google.gerrit.extensions.registration.DynamicSet;
|
||||
import com.google.gerrit.reviewdb.client.Change;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import java.sql.Timestamp;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@Singleton
|
||||
public class ChangeReverted {
|
||||
private static final Logger log = LoggerFactory.getLogger(ChangeReverted.class);
|
||||
|
||||
|
@@ -30,12 +30,14 @@ import com.google.gerrit.server.patch.PatchListObjectTooLargeException;
|
||||
import com.google.gerrit.server.permissions.PermissionBackendException;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import java.io.IOException;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.Map;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@Singleton
|
||||
public class CommentAdded {
|
||||
private static final Logger log = LoggerFactory.getLogger(CommentAdded.class);
|
||||
|
||||
|
@@ -35,6 +35,7 @@ import com.google.gerrit.server.query.change.ChangeData;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
import com.google.inject.Singleton;
|
||||
import java.io.IOException;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.EnumSet;
|
||||
@@ -43,6 +44,7 @@ import java.util.Map;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@Singleton
|
||||
public class EventUtil {
|
||||
private static final Logger log = LoggerFactory.getLogger(EventUtil.class);
|
||||
|
||||
@@ -65,7 +67,7 @@ public class EventUtil {
|
||||
|
||||
private final ChangeData.Factory changeDataFactory;
|
||||
private final Provider<ReviewDb> db;
|
||||
private final ChangeJson changeJson;
|
||||
private final ChangeJson.Factory changeJsonFactory;
|
||||
|
||||
@Inject
|
||||
EventUtil(
|
||||
@@ -74,11 +76,11 @@ public class EventUtil {
|
||||
Provider<ReviewDb> db) {
|
||||
this.changeDataFactory = changeDataFactory;
|
||||
this.db = db;
|
||||
this.changeJson = changeJsonFactory.create(CHANGE_OPTIONS);
|
||||
this.changeJsonFactory = changeJsonFactory;
|
||||
}
|
||||
|
||||
public ChangeInfo changeInfo(Change change) throws OrmException {
|
||||
return changeJson.format(change);
|
||||
return changeJsonFactory.create(CHANGE_OPTIONS).format(change);
|
||||
}
|
||||
|
||||
public RevisionInfo revisionInfo(Project project, PatchSet ps)
|
||||
@@ -91,7 +93,7 @@ public class EventUtil {
|
||||
throws OrmException, PatchListNotAvailableException, GpgException, IOException,
|
||||
PermissionBackendException {
|
||||
ChangeData cd = changeDataFactory.create(db.get(), project, ps.getId().getParentKey());
|
||||
return changeJson.getRevisionInfo(cd, ps);
|
||||
return changeJsonFactory.create(CHANGE_OPTIONS).getRevisionInfo(cd, ps);
|
||||
}
|
||||
|
||||
public AccountInfo accountInfo(AccountState accountState) {
|
||||
|
@@ -21,11 +21,13 @@ import com.google.gerrit.extensions.registration.DynamicSet;
|
||||
import com.google.gerrit.reviewdb.client.Project;
|
||||
import com.google.gerrit.server.account.AccountState;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import org.eclipse.jgit.lib.BatchRefUpdate;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
import org.eclipse.jgit.lib.RefUpdate;
|
||||
import org.eclipse.jgit.transport.ReceiveCommand;
|
||||
|
||||
@Singleton
|
||||
public class GitReferenceUpdated {
|
||||
public static final GitReferenceUpdated DISABLED =
|
||||
new GitReferenceUpdated() {
|
||||
|
@@ -24,12 +24,14 @@ import com.google.gerrit.reviewdb.client.Change;
|
||||
import com.google.gerrit.server.account.AccountState;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@Singleton
|
||||
public class HashtagsEdited {
|
||||
private static final Logger log = LoggerFactory.getLogger(HashtagsEdited.class);
|
||||
|
||||
|
@@ -17,7 +17,9 @@ package com.google.gerrit.server.extensions.events;
|
||||
import com.google.gerrit.extensions.events.PluginEventListener;
|
||||
import com.google.gerrit.extensions.registration.DynamicSet;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
@Singleton
|
||||
public class PluginEvent {
|
||||
private final DynamicSet<PluginEventListener> listeners;
|
||||
|
||||
|
@@ -23,10 +23,12 @@ import com.google.gerrit.reviewdb.client.Change;
|
||||
import com.google.gerrit.server.account.AccountState;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import java.sql.Timestamp;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@Singleton
|
||||
public class PrivateStateChanged {
|
||||
private static final Logger log = LoggerFactory.getLogger(PrivateStateChanged.class);
|
||||
|
||||
|
@@ -30,12 +30,14 @@ import com.google.gerrit.server.patch.PatchListObjectTooLargeException;
|
||||
import com.google.gerrit.server.permissions.PermissionBackendException;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import java.io.IOException;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.List;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@Singleton
|
||||
public class ReviewerAdded {
|
||||
private static final Logger log = LoggerFactory.getLogger(ReviewerAdded.class);
|
||||
|
||||
|
@@ -30,12 +30,14 @@ import com.google.gerrit.server.patch.PatchListObjectTooLargeException;
|
||||
import com.google.gerrit.server.permissions.PermissionBackendException;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import java.io.IOException;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.Map;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@Singleton
|
||||
public class ReviewerDeleted {
|
||||
private static final Logger log = LoggerFactory.getLogger(ReviewerDeleted.class);
|
||||
|
||||
|
@@ -29,14 +29,27 @@ import com.google.gerrit.server.patch.PatchListObjectTooLargeException;
|
||||
import com.google.gerrit.server.permissions.PermissionBackendException;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import java.io.IOException;
|
||||
import java.sql.Timestamp;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@Singleton
|
||||
public class RevisionCreated {
|
||||
private static final Logger log = LoggerFactory.getLogger(RevisionCreated.class);
|
||||
|
||||
public static final RevisionCreated DISABLED =
|
||||
new RevisionCreated() {
|
||||
@Override
|
||||
public void fire(
|
||||
Change change,
|
||||
PatchSet patchSet,
|
||||
AccountState uploader,
|
||||
Timestamp when,
|
||||
NotifyHandling notify) {}
|
||||
};
|
||||
|
||||
private final DynamicSet<RevisionCreatedListener> listeners;
|
||||
private final EventUtil util;
|
||||
|
||||
@@ -46,6 +59,11 @@ public class RevisionCreated {
|
||||
this.util = util;
|
||||
}
|
||||
|
||||
private RevisionCreated() {
|
||||
this.listeners = null;
|
||||
this.util = null;
|
||||
}
|
||||
|
||||
public void fire(
|
||||
Change change,
|
||||
PatchSet patchSet,
|
||||
|
@@ -23,10 +23,12 @@ import com.google.gerrit.reviewdb.client.Change;
|
||||
import com.google.gerrit.server.account.AccountState;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import java.sql.Timestamp;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@Singleton
|
||||
public class TopicEdited {
|
||||
private static final Logger log = LoggerFactory.getLogger(TopicEdited.class);
|
||||
|
||||
|
@@ -30,12 +30,14 @@ import com.google.gerrit.server.patch.PatchListObjectTooLargeException;
|
||||
import com.google.gerrit.server.permissions.PermissionBackendException;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import java.io.IOException;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.Map;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@Singleton
|
||||
public class VoteDeleted {
|
||||
private static final Logger log = LoggerFactory.getLogger(VoteDeleted.class);
|
||||
|
||||
|
@@ -23,10 +23,12 @@ import com.google.gerrit.reviewdb.client.Change;
|
||||
import com.google.gerrit.server.account.AccountState;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import java.sql.Timestamp;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@Singleton
|
||||
public class WorkInProgressStateChanged {
|
||||
private static final Logger log = LoggerFactory.getLogger(WorkInProgressStateChanged.class);
|
||||
|
||||
|
@@ -415,8 +415,13 @@ public class SubmoduleOp {
|
||||
PersonIdent author = null;
|
||||
DirCache dc = readTree(or.rw, currentCommit);
|
||||
DirCacheEditor ed = dc.editor();
|
||||
int count = 0;
|
||||
for (SubmoduleSubscription s : targets.get(subscriber)) {
|
||||
if (count > 0) {
|
||||
msgbuf.append("\n\n");
|
||||
}
|
||||
RevCommit newCommit = updateSubmodule(dc, ed, msgbuf, s);
|
||||
count++;
|
||||
if (newCommit != null) {
|
||||
if (author == null) {
|
||||
author = newCommit.getAuthorIdent();
|
||||
|
@@ -395,12 +395,11 @@ public abstract class BaseCommand implements Command {
|
||||
}
|
||||
|
||||
protected String getTaskDescription() {
|
||||
StringBuilder m = new StringBuilder(commandName);
|
||||
String[] ta = getTrimmedArguments();
|
||||
if (ta != null) {
|
||||
m.append(Joiner.on(" ").join(ta));
|
||||
return commandName + " " + Joiner.on(" ").join(ta);
|
||||
}
|
||||
return m.toString();
|
||||
return commandName;
|
||||
}
|
||||
|
||||
private String getTaskName() {
|
||||
|
@@ -17,6 +17,7 @@ package com.google.gerrit.sshd;
|
||||
import com.google.common.util.concurrent.Atomics;
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
import com.google.gerrit.extensions.events.LifecycleListener;
|
||||
import com.google.gerrit.extensions.registration.DynamicItem;
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gerrit.server.config.GerritServerConfig;
|
||||
import com.google.gerrit.server.git.WorkQueue;
|
||||
@@ -57,6 +58,7 @@ class CommandFactoryProvider implements Provider<CommandFactory>, LifecycleListe
|
||||
private final ScheduledExecutorService startExecutor;
|
||||
private final ExecutorService destroyExecutor;
|
||||
private final SchemaFactory<ReviewDb> schemaFactory;
|
||||
private final DynamicItem<SshCreateCommandInterceptor> createCommandInterceptor;
|
||||
|
||||
@Inject
|
||||
CommandFactoryProvider(
|
||||
@@ -65,11 +67,13 @@ class CommandFactoryProvider implements Provider<CommandFactory>, LifecycleListe
|
||||
WorkQueue workQueue,
|
||||
SshLog l,
|
||||
SshScope s,
|
||||
SchemaFactory<ReviewDb> sf) {
|
||||
SchemaFactory<ReviewDb> sf,
|
||||
DynamicItem<SshCreateCommandInterceptor> i) {
|
||||
dispatcher = d;
|
||||
log = l;
|
||||
sshScope = s;
|
||||
schemaFactory = sf;
|
||||
createCommandInterceptor = i;
|
||||
|
||||
int threads = cfg.getInt("sshd", "commandStartThreads", 2);
|
||||
startExecutor = workQueue.createQueue(threads, "SshCommandStart");
|
||||
@@ -94,7 +98,12 @@ class CommandFactoryProvider implements Provider<CommandFactory>, LifecycleListe
|
||||
return new CommandFactory() {
|
||||
@Override
|
||||
public Command createCommand(String requestCommand) {
|
||||
return new Trampoline(requestCommand);
|
||||
String c = requestCommand;
|
||||
SshCreateCommandInterceptor interceptor = createCommandInterceptor.get();
|
||||
if (interceptor != null) {
|
||||
c = interceptor.intercept(c);
|
||||
}
|
||||
return new Trampoline(c);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
26
java/com/google/gerrit/sshd/SshCreateCommandInterceptor.java
Normal file
26
java/com/google/gerrit/sshd/SshCreateCommandInterceptor.java
Normal file
@@ -0,0 +1,26 @@
|
||||
// Copyright (C) 2018 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.sshd;
|
||||
|
||||
public interface SshCreateCommandInterceptor {
|
||||
|
||||
/**
|
||||
* Intrcept SSH command creation
|
||||
*
|
||||
* @param in command name passed in to command instance creation machinery
|
||||
* @return intercepted command name
|
||||
*/
|
||||
String intercept(String in);
|
||||
}
|
@@ -14,7 +14,6 @@
|
||||
|
||||
package com.google.gerrit.sshd;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.ListMultimap;
|
||||
import com.google.common.collect.MultimapBuilder;
|
||||
import com.google.gerrit.common.TimeUtil;
|
||||
@@ -283,9 +282,9 @@ class SshLog implements LifecycleListener {
|
||||
return "Command was already destroyed";
|
||||
}
|
||||
StringBuilder commandName = new StringBuilder(dcmd.getCommandName());
|
||||
String[] trimmedArgs = dcmd.getTrimmedArguments();
|
||||
if (trimmedArgs != null) {
|
||||
commandName.append(Joiner.on(".").join(trimmedArgs));
|
||||
String[] args = dcmd.getArguments();
|
||||
for (int i = 1; i < args.length; i++) {
|
||||
commandName.append(".").append(args[i]);
|
||||
}
|
||||
return commandName.toString();
|
||||
}
|
||||
|
@@ -19,6 +19,7 @@ import static com.google.inject.Scopes.SINGLETON;
|
||||
|
||||
import com.google.common.base.CharMatcher;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.gerrit.extensions.registration.DynamicItem;
|
||||
import com.google.gerrit.extensions.registration.DynamicMap;
|
||||
import com.google.gerrit.lifecycle.LifecycleModule;
|
||||
import com.google.gerrit.server.DynamicOptions;
|
||||
@@ -100,6 +101,7 @@ public class SshModule extends LifecycleModule {
|
||||
.to(SshPluginStarterCallback.class);
|
||||
|
||||
DynamicMap.mapOf(binder(), DynamicOptions.DynamicBean.class);
|
||||
DynamicItem.itemOf(binder(), SshCreateCommandInterceptor.class);
|
||||
|
||||
listener().toInstance(registerInParentInjectors());
|
||||
listener().to(SshLog.class);
|
||||
|
@@ -85,6 +85,7 @@ import com.google.gerrit.extensions.api.changes.ReviewInput.DraftHandling;
|
||||
import com.google.gerrit.extensions.api.changes.ReviewResult;
|
||||
import com.google.gerrit.extensions.api.changes.RevisionApi;
|
||||
import com.google.gerrit.extensions.api.changes.StarsInput;
|
||||
import com.google.gerrit.extensions.api.groups.GroupApi;
|
||||
import com.google.gerrit.extensions.api.projects.BranchInput;
|
||||
import com.google.gerrit.extensions.api.projects.ConfigInput;
|
||||
import com.google.gerrit.extensions.client.ChangeKind;
|
||||
@@ -167,6 +168,7 @@ import org.eclipse.jgit.revwalk.RevWalk;
|
||||
import org.eclipse.jgit.transport.PushResult;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
@NoHttpd
|
||||
@@ -1504,6 +1506,100 @@ public class ChangeIT extends AbstractDaemonTest {
|
||||
assertThat(sender.getMessages()).hasSize(1);
|
||||
}
|
||||
|
||||
@Ignore
|
||||
@Test
|
||||
public void addReviewerThatIsNotPerfectMatch() throws Exception {
|
||||
TestTimeUtil.resetWithClockStep(1, SECONDS);
|
||||
PushOneCommit.Result r = createChange();
|
||||
ChangeResource rsrc = parseResource(r);
|
||||
String oldETag = rsrc.getETag();
|
||||
Timestamp oldTs = rsrc.getChange().getLastUpdatedOn();
|
||||
|
||||
//create a group named "ab" with one user: testUser
|
||||
TestAccount testUser = accountCreator.create("abcd", "abcd@test.com", "abcd");
|
||||
String testGroup = createGroupWithRealName("ab");
|
||||
GroupApi groupApi = gApi.groups().id(testGroup);
|
||||
groupApi.description("test group");
|
||||
groupApi.addMembers(user.fullName);
|
||||
|
||||
AddReviewerInput in = new AddReviewerInput();
|
||||
in.reviewer = "abc";
|
||||
gApi.changes().id(r.getChangeId()).addReviewer(in.reviewer);
|
||||
|
||||
List<Message> messages = sender.getMessages();
|
||||
assertThat(messages).hasSize(1);
|
||||
Message m = messages.get(0);
|
||||
assertThat(m.rcpt()).containsExactly(testUser.emailAddress);
|
||||
assertThat(m.body()).contains("Hello " + testUser.fullName + ",\n");
|
||||
assertThat(m.body()).contains("I'd like you to do a code review.");
|
||||
assertThat(m.body()).contains("Change subject: " + PushOneCommit.SUBJECT + "\n");
|
||||
assertMailReplyTo(m, testUser.email);
|
||||
ChangeInfo c = gApi.changes().id(r.getChangeId()).get();
|
||||
|
||||
// When NoteDb is enabled adding a reviewer records that user as reviewer
|
||||
// in NoteDb. When NoteDb is disabled adding a reviewer results in a dummy 0
|
||||
// approval on the change which is treated as CC when the ChangeInfo is
|
||||
// created.
|
||||
Collection<AccountInfo> reviewers = c.reviewers.get(REVIEWER);
|
||||
assertThat(reviewers).isNotNull();
|
||||
assertThat(reviewers).hasSize(1);
|
||||
assertThat(reviewers.iterator().next()._accountId).isEqualTo(testUser.getId().get());
|
||||
|
||||
// Ensure ETag and lastUpdatedOn are updated.
|
||||
rsrc = parseResource(r);
|
||||
assertThat(rsrc.getETag()).isNotEqualTo(oldETag);
|
||||
assertThat(rsrc.getChange().getLastUpdatedOn()).isNotEqualTo(oldTs);
|
||||
}
|
||||
|
||||
@Ignore
|
||||
@Test
|
||||
public void addGroupAsReviewersWhenANotPerfectMatchedUserExists() throws Exception {
|
||||
TestTimeUtil.resetWithClockStep(1, SECONDS);
|
||||
PushOneCommit.Result r = createChange();
|
||||
ChangeResource rsrc = parseResource(r);
|
||||
String oldETag = rsrc.getETag();
|
||||
Timestamp oldTs = rsrc.getChange().getLastUpdatedOn();
|
||||
|
||||
//create a group named "us" with one user: testUser
|
||||
TestAccount testUser = accountCreator.create("testUser", "testUser@test.com", "testUser");
|
||||
String testGroup =
|
||||
createGroupWithRealName(user.fullName.substring(0, user.fullName.length() / 2));
|
||||
GroupApi groupApi = gApi.groups().id(testGroup);
|
||||
groupApi.description("test group");
|
||||
groupApi.addMembers(testUser.fullName);
|
||||
|
||||
//ensure that user "user" is not in the group
|
||||
groupApi.removeMembers(user.fullName);
|
||||
|
||||
AddReviewerInput in = new AddReviewerInput();
|
||||
in.reviewer = testGroup;
|
||||
gApi.changes().id(r.getChangeId()).addReviewer(in.reviewer);
|
||||
|
||||
List<Message> messages = sender.getMessages();
|
||||
assertThat(messages).hasSize(1);
|
||||
Message m = messages.get(0);
|
||||
assertThat(m.rcpt()).containsExactly(testUser.emailAddress);
|
||||
assertThat(m.body()).contains("Hello " + testUser.fullName + ",\n");
|
||||
assertThat(m.body()).contains("I'd like you to do a code review.");
|
||||
assertThat(m.body()).contains("Change subject: " + PushOneCommit.SUBJECT + "\n");
|
||||
assertMailReplyTo(m, testUser.email);
|
||||
ChangeInfo c = gApi.changes().id(r.getChangeId()).get();
|
||||
|
||||
// When NoteDb is enabled adding a reviewer records that user as reviewer
|
||||
// in NoteDb. When NoteDb is disabled adding a reviewer results in a dummy 0
|
||||
// approval on the change which is treated as CC when the ChangeInfo is
|
||||
// created.
|
||||
Collection<AccountInfo> reviewers = c.reviewers.get(REVIEWER);
|
||||
assertThat(reviewers).isNotNull();
|
||||
assertThat(reviewers).hasSize(1);
|
||||
assertThat(reviewers.iterator().next()._accountId).isEqualTo(testUser.getId().get());
|
||||
|
||||
// Ensure ETag and lastUpdatedOn are updated.
|
||||
rsrc = parseResource(r);
|
||||
assertThat(rsrc.getETag()).isNotEqualTo(oldETag);
|
||||
assertThat(rsrc.getChange().getLastUpdatedOn()).isNotEqualTo(oldTs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addReviewerWithNoteDbWhenDummyApprovalInReviewDbExists() throws Exception {
|
||||
assume().that(notesMigration.readChanges()).isTrue();
|
||||
|
@@ -313,6 +313,52 @@ public class SubmoduleSubscriptionsWholeTopicMergeIT extends AbstractSubmoduleSu
|
||||
expectToHaveSubmoduleState(superRepo, "master", "sub2", sub2, "master");
|
||||
expectToHaveSubmoduleState(superRepo, "master", "sub3", sub3, "master");
|
||||
|
||||
String sub1HEAD =
|
||||
sub1.git()
|
||||
.fetch()
|
||||
.setRemote("origin")
|
||||
.call()
|
||||
.getAdvertisedRef("refs/heads/master")
|
||||
.getObjectId()
|
||||
.name();
|
||||
|
||||
String sub2HEAD =
|
||||
sub2.git()
|
||||
.fetch()
|
||||
.setRemote("origin")
|
||||
.call()
|
||||
.getAdvertisedRef("refs/heads/master")
|
||||
.getObjectId()
|
||||
.name();
|
||||
|
||||
String sub3HEAD =
|
||||
sub3.git()
|
||||
.fetch()
|
||||
.setRemote("origin")
|
||||
.call()
|
||||
.getAdvertisedRef("refs/heads/master")
|
||||
.getObjectId()
|
||||
.name();
|
||||
|
||||
if (getSubmitType() == SubmitType.MERGE_IF_NECESSARY) {
|
||||
expectToHaveCommitMessage(
|
||||
superRepo,
|
||||
"master",
|
||||
"Update git submodules\n\n"
|
||||
+ "* Update "
|
||||
+ name("sub3")
|
||||
+ " from branch 'master'\n to "
|
||||
+ sub3HEAD
|
||||
+ "\n\n* Update "
|
||||
+ name("sub2")
|
||||
+ " from branch 'master'\n to "
|
||||
+ sub2HEAD
|
||||
+ "\n\n* Update "
|
||||
+ name("sub1")
|
||||
+ " from branch 'master'\n to "
|
||||
+ sub1HEAD);
|
||||
}
|
||||
|
||||
superRepo
|
||||
.git()
|
||||
.fetch()
|
||||
|
@@ -31,7 +31,7 @@
|
||||
value: () => {
|
||||
// Set default values for dropdowns.
|
||||
return {
|
||||
create_empty_commit: false,
|
||||
create_empty_commit: true,
|
||||
permissions_only: false,
|
||||
};
|
||||
},
|
||||
|
@@ -49,7 +49,7 @@ limitations under the License.
|
||||
});
|
||||
|
||||
test('default values are populated', () => {
|
||||
assert.isFalse(element.$.initalCommit.bindValue);
|
||||
assert.isTrue(element.$.initalCommit.bindValue);
|
||||
assert.isFalse(element.$.parentRepo.bindValue);
|
||||
});
|
||||
|
||||
|
@@ -78,6 +78,9 @@ add_ChangeId() {
|
||||
# - in END, the last textLine+ block is available for footer parsing
|
||||
$AWK '
|
||||
BEGIN {
|
||||
if (match(ENVIRON["OS"], "Windows")) {
|
||||
RS="\r?\n" # Required on recent Cygwin
|
||||
}
|
||||
# while we start with the assumption that textLine+
|
||||
# is a footer, the first block is not.
|
||||
isFooter = 0
|
||||
|
@@ -113,7 +113,12 @@ for n in sorted(graph.keys()):
|
||||
print()
|
||||
print("[[%s_license]]" % safename)
|
||||
print("----")
|
||||
with open(n[2:].replace(":", "/")) as fd:
|
||||
filename = n[2:].replace(":", "/")
|
||||
try:
|
||||
with open(filename, errors='ignore') as fd:
|
||||
copyfileobj(fd, stdout)
|
||||
except TypeError:
|
||||
with open(filename) as fd:
|
||||
copyfileobj(fd, stdout)
|
||||
print()
|
||||
print("----")
|
||||
|
@@ -68,7 +68,7 @@ def retrieve_ext_location():
|
||||
return check_output(_build_bazel_cmd('info', 'output_base')).strip()
|
||||
|
||||
def gen_bazel_path():
|
||||
bazel = check_output(['which', 'bazel']).strip()
|
||||
bazel = check_output(['which', 'bazel']).strip().decode('UTF-8')
|
||||
with open(path.join(ROOT, ".bazel_path"), 'w') as fd:
|
||||
fd.write("bazel=%s\n" % bazel)
|
||||
fd.write("PATH=%s\n" % environ["PATH"])
|
||||
|
@@ -39,14 +39,12 @@ try:
|
||||
continue
|
||||
elif n.startswith(SERVICES):
|
||||
# Concatenate all provider configuration files.
|
||||
myfile = inzip.open(n, 'r')
|
||||
myfile = io.TextIOWrapper(myfile, encoding='iso-8859-1', newline='')
|
||||
services[n] += myfile.read()
|
||||
services[n] += inzip.read(n).decode("UTF-8")
|
||||
continue
|
||||
outzip.writestr(info, inzip.read(n))
|
||||
seen.add(n)
|
||||
|
||||
for n, v in services.items():
|
||||
for n, v in list(services.items()):
|
||||
outzip.writestr(n, v)
|
||||
except Exception as err:
|
||||
exit('Failed to merge jars: %s' % err)
|
||||
|
Reference in New Issue
Block a user