private PostResult putGroup(ChangeResource rsrc, Input input) throws BadRequestException, UnprocessableEntityException, OrmException, EmailException, IOException { GroupDescription.Basic group = groupsCollection.get().parseInternal(input.reviewer); PostResult result = new PostResult(); if (!isLegalReviewerGroup(group.getGroupUUID())) { result.error = MessageFormat.format(ChangeMessages.get().groupIsNotAllowed, group.getName()); return result; } Set<IdentifiedUser> reviewers = Sets.newLinkedHashSet(); ChangeControl control = rsrc.getControl(); Set<Account> members; try { members = groupMembersFactory .create(control.getCurrentUser()) .listAccounts(group.getGroupUUID(), control.getProject().getNameKey()); } catch (NoSuchGroupException e) { throw new UnprocessableEntityException(e.getMessage()); } catch (NoSuchProjectException e) { throw new BadRequestException(e.getMessage()); } // if maxAllowed is set to 0, it is allowed to add any number of // reviewers int maxAllowed = cfg.getInt("addreviewer", "maxAllowed", DEFAULT_MAX_REVIEWERS); if (maxAllowed > 0 && members.size() > maxAllowed) { result.error = MessageFormat.format(ChangeMessages.get().groupHasTooManyMembers, group.getName()); return result; } // if maxWithoutCheck is set to 0, we never ask for confirmation int maxWithoutConfirmation = cfg.getInt("addreviewer", "maxWithoutConfirmation", DEFAULT_MAX_REVIEWERS_WITHOUT_CHECK); if (!input.confirmed() && maxWithoutConfirmation > 0 && members.size() > maxWithoutConfirmation) { result.confirm = true; result.error = MessageFormat.format( ChangeMessages.get().groupManyMembersConfirmation, group.getName(), members.size()); return result; } for (Account member : members) { if (member.isActive()) { IdentifiedUser user = identifiedUserFactory.create(member.getId()); // Does not account for draft status as a user might want to let a // reviewer see a draft. if (control.forUser(user).isRefVisible()) { reviewers.add(user); } } } addReviewers(rsrc, result, reviewers); return result; }
ReceiveConfig(final Config config) { checkReceivedObjects = config.getBoolean("receive", "fsckobjects", false); allowCreates = true; allowDeletes = !config.getBoolean("receive", "denydeletes", false); allowNonFastForwards = !config.getBoolean("receive", "denynonfastforwards", false); allowOfsDelta = config.getBoolean("repack", "usedeltabaseoffset", true); }
protected static void set( Config rc, String section, String subsection, String name, String value) { if (value != null) { rc.setString(section, subsection, name, value); } else { rc.unset(section, subsection, name); } }
protected static <E extends Enum<?>> void set( Config rc, String section, String subsection, String name, E value, E defaultValue) { if (value != defaultValue) { rc.setEnum(section, subsection, name, value); } else { rc.unset(section, subsection, name); } }
protected static void set( Config rc, String section, String subsection, String name, boolean value) { if (value) { rc.setBoolean(section, subsection, name, value); } else { rc.unset(section, subsection, name); } }
private List<Git.Remote> getRemotes(final Repository repository) { Config config = repository.getConfig(); List<Git.Remote> remotes = new ArrayList<Git.Remote>(); for (String remote : config.getSubsections("remote")) { String url = config.getString("remote", remote, "url"); remotes.add(new Git.Remote(remote, url)); } return remotes; }
@Test public void testAddConfigEntry() throws Exception { URI workspaceLocation = createWorkspace(getMethodName()); IPath[] clonePaths = createTestProjects(workspaceLocation); for (IPath clonePath : clonePaths) { // clone a repo String contentLocation = clone(clonePath).getString(ProtocolConstants.KEY_CONTENT_LOCATION); // get project metadata WebRequest request = getGetRequest(contentLocation); WebResponse response = webConversation.getResponse(request); assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode()); JSONObject project = new JSONObject(response.getText()); JSONObject gitSection = project.getJSONObject(GitConstants.KEY_GIT); String gitConfigUri = gitSection.getString(GitConstants.KEY_CONFIG); JSONObject configResponse = listConfigEntries(gitConfigUri); JSONArray configEntries = configResponse.getJSONArray(ProtocolConstants.KEY_CHILDREN); // initial number of config entries int initialConfigEntriesCount = configEntries.length(); // set some dummy value final String ENTRY_KEY = "a.b.c"; final String ENTRY_VALUE = "v"; request = getPostGitConfigRequest(gitConfigUri, ENTRY_KEY, ENTRY_VALUE); response = webConversation.getResponse(request); assertEquals(HttpURLConnection.HTTP_CREATED, response.getResponseCode()); configResponse = new JSONObject(response.getText()); String entryLocation = configResponse.getString(ProtocolConstants.KEY_LOCATION); assertConfigUri(entryLocation); // get list of config entries again configResponse = listConfigEntries(gitConfigUri); configEntries = configResponse.getJSONArray(ProtocolConstants.KEY_CHILDREN); assertEquals(initialConfigEntriesCount + 1, configEntries.length()); entryLocation = null; for (int i = 0; i < configEntries.length(); i++) { JSONObject configEntry = configEntries.getJSONObject(i); if (ENTRY_KEY.equals(configEntry.getString(GitConstants.KEY_CONFIG_ENTRY_KEY))) { assertConfigOption(configEntry, ENTRY_KEY, ENTRY_VALUE); break; } } // double check org.eclipse.jgit.lib.Config config = getRepositoryForContentLocation(contentLocation).getConfig(); assertEquals(ENTRY_VALUE, config.getString("a", "b", "c")); } }
protected Config readConfig(String fileName) throws IOException, ConfigInvalidException { Config rc = new Config(); String text = readUTF8(fileName); if (!text.isEmpty()) { try { rc.fromText(text); } catch (ConfigInvalidException err) { throw new ConfigInvalidException( "Invalid config file " + fileName + " in commit " + revision.name(), err); } } return rc; }
/** * @param gitConfigFolder e.g. /your/project/root/.git * @return Returns git config remote.origin.url field of the repository located at gitConfigFolder */ public static String getGitRemoteUrl(String gitConfigFolder) throws MojoExecutionException { try { Repository repo = new RepositoryBuilder() .setGitDir(new File(gitConfigFolder)) .readEnvironment() .findGitDir() .build(); Config config = repo.getConfig(); return config.getString("remote", "origin", "url"); } catch (Exception e) { throw new MojoExecutionException( "Error trying to get remote origin url of git repository", e); } }
private String getRemote() { String remoteName = config.getString( ConfigConstants.CONFIG_BRANCH_SECTION, branchName, ConfigConstants.CONFIG_KEY_REMOTE); if (remoteName == null) return Constants.DEFAULT_REMOTE_NAME; else return remoteName; }
@Inject LocalDiskRepositoryManager(final SitePaths site, @GerritServerConfig final Config cfg) { basePath = site.resolve(cfg.getString("gerrit", null, "basePath")); if (basePath == null) { throw new IllegalStateException("gerrit.basePath must be configured"); } }
@Provides @Singleton @IndexExecutor(BATCH) ListeningExecutorService getBatchIndexExecutor( @GerritServerConfig Config config, WorkQueue workQueue) { if (batchExecutor != null) { return batchExecutor; } int threads = config.getInt("index", null, "batchThreads", 0); if (threads <= 0) { threads = config.getInt("changeMerge", null, "threadPoolSize", 0); } if (threads <= 0) { threads = Runtime.getRuntime().availableProcessors(); } return MoreExecutors.listeningDecorator(workQueue.createQueue(threads, "Index-Batch")); }
@Provides @Singleton @IndexExecutor(INTERACTIVE) ListeningExecutorService getInteractiveIndexExecutor( @GerritServerConfig Config config, WorkQueue workQueue) { if (interactiveExecutor != null) { return interactiveExecutor; } int threads = this.threads; if (threads <= 0) { threads = config.getInt("index", null, "threads", 0); } if (threads <= 0) { threads = config.getInt("changeMerge", null, "interactiveThreadPoolSize", 0); } if (threads <= 0) { return MoreExecutors.newDirectExecutorService(); } return MoreExecutors.listeningDecorator(workQueue.createQueue(threads, "Index-Interactive")); }
@Inject GetBlame( GitRepositoryManager repoManager, BlameCache blameCache, @GerritServerConfig Config cfg, AutoMerger autoMerger) { this.repoManager = repoManager; this.blameCache = blameCache; this.mergeStrategy = MergeUtil.getMergeStrategy(cfg); this.autoMerger = autoMerger; allowBlame = cfg.getBoolean("change", "allowBlame", true); }
private Object getValueFromConfig(Config config, String keyString) { StringTokenizer tok = new StringTokenizer(keyString, "."); // $NON-NLS-1$ String section; String subsection; String name; String[] valueList = null; if (tok.countTokens() == 2) { section = tok.nextToken(); subsection = null; name = tok.nextToken(); } else if (tok.countTokens() == 3) { section = tok.nextToken(); subsection = tok.nextToken(); name = tok.nextToken(); } else { return ""; //$NON-NLS-1$ } if (getSingleValueMode()) valueList = new String[] {config.getString(section, subsection, name)}; else valueList = config.getStringList(section, subsection, name); if (valueList == null || valueList.length == 0) return null; if (valueList.length == 1) { return valueList[0]; } StringBuilder sb = new StringBuilder(); for (String value : valueList) { sb.append('['); sb.append(value); sb.append(']'); } return sb.toString(); }
/** * Get a list of string values * * <p>If this instance was created with a base, the base's values are returned first (if any). * * @param section the section * @param subsection the subsection for the value * @param name the key name * @return array of zero or more values from the configuration. */ public String[] getStringList(final String section, String subsection, final String name) { final String[] baseList; if (baseConfig != null) baseList = baseConfig.getStringList(section, subsection, name); else baseList = EMPTY_STRING_ARRAY; final List<String> lst = getRawStringList(section, subsection, name); if (lst != null) { final String[] res = new String[baseList.length + lst.size()]; int idx = baseList.length; System.arraycopy(baseList, 0, res, 0, idx); for (final String val : lst) res[idx++] = val; return res; } return baseList; }
@Override public ServiceUserInfo apply(ServiceUserResource rsrc) throws ResourceNotFoundException, OrmException { ProjectLevelConfig storage = projectCache.getAllProjects().getConfig(pluginName + ".db"); String username = rsrc.getUser().getUserName(); Config db = storage.get(); if (!db.getSubsections(USER).contains(username)) { throw new ResourceNotFoundException(username); } ServiceUserInfo info = new ServiceUserInfo(getAccount.get().apply(rsrc)); AccountLoader al = accountLoader.create(true); info.createdBy = al.get(new Account.Id(db.getInt(USER, username, KEY_CREATOR_ID, -1))); al.fill(); info.createdAt = db.getString(USER, username, KEY_CREATED_AT); info.inactive = !rsrc.getUser().getAccount().isActive() ? true : null; Response<GroupInfo> response = getOwner.apply(rsrc); if (response.statusCode() == SC_OK) { info.owner = response.value(); } return info; }
private static String getNameInternal(Config rc, String envKey) { // try to get the user name from the local and global configurations. String username = rc.getString("user", null, "name"); if (username == null) { // try to get the user name for the system property GIT_XXX_NAME username = system().getenv(envKey); } if (username == null) { // get the system user name username = system().getProperty(Constants.OS_USER_NAME_KEY); } if (username == null) { username = Constants.UNKNOWN_USER_DEFAULT; } return username; }
@Inject GitwebConfig(GitwebCgiConfig cgiConfig, @GerritServerConfig Config cfg) { if (isDisabled(cfg)) { type = null; url = null; return; } String cfgUrl = cfg.getString("gitweb", null, "url"); GitwebType type = typeFromConfig(cfg); if (type == null) { this.type = null; url = null; return; } else if (cgiConfig.getGitwebCgi() == null) { // Use an externally managed gitweb instance, and not an internal one. url = cfgUrl; } else { url = firstNonNull(cfgUrl, "gitweb"); } if (isNullOrEmpty(type.getBranch())) { log.warn("No Pattern specified for gitweb.branch, disabling."); this.type = null; } else if (isNullOrEmpty(type.getProject())) { log.warn("No Pattern specified for gitweb.project, disabling."); this.type = null; } else if (isNullOrEmpty(type.getRevision())) { log.warn("No Pattern specified for gitweb.revision, disabling."); this.type = null; } else if (isNullOrEmpty(type.getRootTree())) { log.warn("No Pattern specified for gitweb.roottree, disabling."); this.type = null; } else if (isNullOrEmpty(type.getFile())) { log.warn("No Pattern specified for gitweb.file, disabling."); this.type = null; } else if (isNullOrEmpty(type.getFileHistory())) { log.warn("No Pattern specified for gitweb.filehistory, disabling."); this.type = null; } else { this.type = type; } }
private static String getEmailInternal(Config rc, String envKey) { // try to get the email from the local and global configurations. String email = rc.getString("user", null, "email"); if (email == null) { // try to get the email for the system property GIT_XXX_EMAIL email = system().getenv(envKey); } if (email == null) { // try to construct an email String username = system().getProperty(Constants.OS_USER_NAME_KEY); if (username == null) { username = Constants.UNKNOWN_USER_DEFAULT; } email = username + "@" + system().getHostname(); } return email; }
@Inject CommandFactoryProvider( @CommandName(Commands.ROOT) final DispatchCommandProvider d, @GerritServerConfig final Config cfg, final WorkQueue workQueue, final SshLog l, final SshScope s) { dispatcher = d; log = l; sshScope = s; int threads = cfg.getInt("sshd", "commandStartThreads", 2); startExecutor = workQueue.createQueue(threads, "SshCommandStart"); destroyExecutor = Executors.newSingleThreadExecutor( new ThreadFactoryBuilder() .setNameFormat("SshCommandDestroy-%s") .setDaemon(true) .build()); }
@Inject public SubmoduleOp( @CanonicalWebUrl @Nullable Provider<String> urlProvider, @GerritPersonIdent PersonIdent myIdent, @GerritServerConfig Config cfg, GitRepositoryManager repoManager, GitReferenceUpdated gitRefUpdated, @Nullable Account account, ChangeHooks changeHooks, SubmoduleSectionParser.Factory subSecParserFactory) { this.urlProvider = urlProvider; this.myIdent = myIdent; this.repoManager = repoManager; this.gitRefUpdated = gitRefUpdated; this.account = account; this.changeHooks = changeHooks; this.subSecParserFactory = subSecParserFactory; this.verboseSuperProject = cfg.getBoolean("submodule", "verboseSuperprojectUpdate", true); updatedSubscribers = new HashSet<>(); }
private void handleAuth(HttpServletRequest req) { String username = req.getRemoteUser(); if (username != null) { if (config.getBoolean("auth", "userNameToLowerCase", false)) { username = username.toLowerCase(Locale.US); } log.debug("User name: " + username); AccountState who = accountCache.getByUsername(username); log.debug("AccountState " + who); if (who == null && username.matches("^([a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9]|[a-zA-Z0-9])$")) { log.debug( "User is not registered with Gerrit. Register now."); // This approach assumes an auth // type of HTTP_LDAP final AuthRequest areq = AuthRequest.forUser(username); try { accountManager.authenticate(areq); who = accountCache.getByUsername(username); if (who == null) { log.warn("Unable to register user \"" + username + "\". Continue as anonymous."); } else { log.debug("User registered."); } } catch (AccountException e) { log.warn("Exception registering user \"" + username + "\". Continue as anonymous.", e); } } if (who != null && who.getAccount().isActive()) { log.debug("Not anonymous user"); WebSession ws = session.get(); ws.setUserAccountId(who.getAccount().getId()); ws.setAccessPathOk(AccessPath.REST_API, true); } else { log.debug("Anonymous user"); } } }
private String getMergeBranch() { String mergeRef = config.getString( ConfigConstants.CONFIG_BRANCH_SECTION, branchName, ConfigConstants.CONFIG_KEY_MERGE); return mergeRef; }
private State getBaseState() { return baseConfig != null ? baseConfig.getState() : null; }
private String getRawString(final String section, final String subsection, final String name) { final List<String> lst = getRawStringList(section, subsection, name); if (lst != null) return lst.get(0); else if (baseConfig != null) return baseConfig.getRawString(section, subsection, name); else return null; }
public GitBlitUrlsConfig(Config config) { canonicalWebUrlString = config.getString("gerrit", null, "canonicalWebUrl"); sshdListenAddressString = config.getString("sshd", null, "listenAddress"); httpdListenUrlString = config.getString("httpd", null, "listenUrl"); downloadSchemes = Arrays.asList(config.getStringList("download", null, "scheme")); }
private static Config readConfig(String dat) throws ConfigInvalidException { Config config = new Config(); config.fromText(dat); return config; }
@Test public void testStoreLoadSection() throws Exception { SectionInfo d = SectionInfo.defaults(); SectionInfo in = new SectionInfo(); in.missing = "42"; in.i = 1; in.ii = 43; in.l = 4L; in.ll = -43L; in.b = false; in.bb = true; in.bd = false; in.s = "baz"; in.t = Theme.MIDNIGHT; Config cfg = new Config(); ConfigUtil.storeSection(cfg, SECT, SUB, in, d); assertThat(cfg.getString(SECT, SUB, "CONSTANT")).isNull(); assertThat(cfg.getString(SECT, SUB, "missing")).isNull(); assertThat(cfg.getBoolean(SECT, SUB, "b", false)).isEqualTo(in.b); assertThat(cfg.getBoolean(SECT, SUB, "bb", false)).isEqualTo(in.bb); assertThat(cfg.getInt(SECT, SUB, "i", 0)).isEqualTo(0); assertThat(cfg.getInt(SECT, SUB, "ii", 0)).isEqualTo(in.ii); assertThat(cfg.getLong(SECT, SUB, "l", 0L)).isEqualTo(0L); assertThat(cfg.getLong(SECT, SUB, "ll", 0L)).isEqualTo(in.ll); assertThat(cfg.getString(SECT, SUB, "s")).isEqualTo(in.s); assertThat(cfg.getString(SECT, SUB, "sd")).isNull(); assertThat(cfg.getString(SECT, SUB, "nd")).isNull(); SectionInfo out = new SectionInfo(); ConfigUtil.loadSection(cfg, SECT, SUB, out, d, null); assertThat(out.i).isEqualTo(in.i); assertThat(out.ii).isEqualTo(in.ii); assertThat(out.id).isEqualTo(d.id); assertThat(out.l).isEqualTo(in.l); assertThat(out.ll).isEqualTo(in.ll); assertThat(out.ld).isEqualTo(d.ld); assertThat(out.b).isEqualTo(in.b); assertThat(out.bb).isEqualTo(in.bb); assertThat(out.bd).isNull(); assertThat(out.s).isEqualTo(in.s); assertThat(out.sd).isEqualTo(d.sd); assertThat(out.nd).isNull(); assertThat(out.t).isEqualTo(in.t); assertThat(out.td).isEqualTo(d.td); }
private void makeSiteConfig(SitePaths site, Config cfg, SshInfo sshInfo) throws IOException { if (!Files.exists(site.tmp_dir)) { Files.createDirectories(site.tmp_dir); } Path myconf = Files.createTempFile(site.tmp_dir, "gitweb_config", ".perl"); // To make our configuration file only readable or writable by us; // this reduces the chances of someone tampering with the file. // // TODO(dborowitz): Is there a portable way to do this with NIO? File myconfFile = myconf.toFile(); myconfFile.setWritable(false, false /* all */); myconfFile.setReadable(false, false /* all */); myconfFile.setExecutable(false, false /* all */); myconfFile.setWritable(true, true /* owner only */); myconfFile.setReadable(true, true /* owner only */); myconfFile.deleteOnExit(); _env.set("GIT_DIR", "."); _env.set("GITWEB_CONFIG", myconf.toAbsolutePath().toString()); try (PrintWriter p = new PrintWriter(Files.newBufferedWriter(myconf, UTF_8))) { p.print("# Autogenerated by Gerrit Code Review \n"); p.print("# DO NOT EDIT\n"); p.print("\n"); // We are mounted at the same level in the context as the main // UI, so we can include the same header and footer scheme. // Path hdr = site.site_header; if (Files.isRegularFile(hdr)) { p.print("$site_header = " + quoteForPerl(hdr) + ";\n"); } Path ftr = site.site_footer; if (Files.isRegularFile(ftr)) { p.print("$site_footer = " + quoteForPerl(ftr) + ";\n"); } // Top level should return to Gerrit's UI. // p.print("$home_link = $ENV{'GERRIT_CONTEXT_PATH'};\n"); p.print("$home_link_str = 'Code Review';\n"); p.print("$favicon = 'favicon.ico';\n"); p.print("$logo = 'gitweb-logo.png';\n"); p.print("$javascript = 'gitweb.js';\n"); p.print("@stylesheets = ('gitweb-default.css');\n"); Path css = site.site_css; if (Files.isRegularFile(css)) { p.print("push @stylesheets, 'gitweb-site.css';\n"); } // Try to make the title match Gerrit's normal window title // scheme of host followed by 'Code Review'. // p.print("$site_name = $home_link_str;\n"); p.print("$site_name = qq{$1 $site_name} if "); p.print("$ENV{'SERVER_NAME'} =~ m,^([^.]+(?:\\.[^.]+)?)(?:\\.|$),;\n"); // Assume by default that XSS is a problem, and try to prevent it. // p.print("$prevent_xss = 1;\n"); // Generate URLs using smart http:// // p.print("{\n"); p.print(" my $secure = $ENV{'HTTPS'} =~ /^ON$/i;\n"); p.print(" my $http_url = $secure ? 'https://' : 'http://';\n"); p.print(" $http_url .= qq{$ENV{'GERRIT_USER_NAME'}@}\n"); p.print(" unless $ENV{'GERRIT_ANONYMOUS_READ'};\n"); p.print(" $http_url .= $ENV{'SERVER_NAME'};\n"); p.print(" $http_url .= qq{:$ENV{'SERVER_PORT'}}\n"); p.print(" if (( $secure && $ENV{'SERVER_PORT'} != 443)\n"); p.print(" || (!$secure && $ENV{'SERVER_PORT'} != 80)\n"); p.print(" );\n"); p.print(" $http_url .= qq{$ENV{'GERRIT_CONTEXT_PATH'}p};\n"); p.print(" push @git_base_url_list, $http_url;\n"); p.print("}\n"); // Generate URLs using anonymous git:// // String url = cfg.getString("gerrit", null, "canonicalGitUrl"); if (url != null) { if (url.endsWith("/")) { url = url.substring(0, url.length() - 1); } p.print("if ($ENV{'GERRIT_ANONYMOUS_READ'}) {\n"); p.print(" push @git_base_url_list, "); p.print(quoteForPerl(url)); p.print(";\n"); p.print("}\n"); } // Generate URLs using authenticated ssh:// // if (sshInfo != null && !sshInfo.getHostKeys().isEmpty()) { String sshAddr = sshInfo.getHostKeys().get(0).getHost(); p.print("if ($ENV{'GERRIT_USER_NAME'}) {\n"); p.print(" push @git_base_url_list, join('', 'ssh://'"); p.print(", $ENV{'GERRIT_USER_NAME'}"); p.print(", '@'"); if (sshAddr.startsWith("*:") || "".equals(sshAddr)) { p.print(", $ENV{'SERVER_NAME'}"); } if (sshAddr.startsWith("*")) { sshAddr = sshAddr.substring(1); } p.print(", " + quoteForPerl(sshAddr)); p.print(");\n"); p.print("}\n"); } // Link back to Gerrit (when possible, to matching review record). // Supported gitweb's hash values are: // - (missing), // - HEAD, // - refs/heads/<branch>, // - refs/changes/*/<change>/*, // - <revision>. // p.print("sub add_review_link {\n"); p.print(" my $h = shift;\n"); p.print(" my $q;\n"); p.print(" if (!$h || $h eq 'HEAD') {\n"); p.print(" $q = qq{#q,project:$ENV{'GERRIT_PROJECT_NAME'}};\n"); p.print(" } elsif ($h =~ /^refs\\/heads\\/([-\\w]+)$/) {\n"); p.print(" $q = qq{#q,project:$ENV{'GERRIT_PROJECT_NAME'}"); p.print("+branch:$1};\n"); // wrapped p.print(" } elsif ($h =~ /^refs\\/changes\\/\\d{2}\\/(\\d+)\\/\\d+$/) "); p.print("{\n"); // wrapped p.print(" $q = qq{#/c/$1};\n"); p.print(" } else {\n"); p.print(" $q = qq{#/q/$h};\n"); p.print(" }\n"); p.print(" my $r = qq{$ENV{'GERRIT_CONTEXT_PATH'}$q};\n"); p.print(" push @{$feature{'actions'}{'default'}},\n"); p.print(" ('review',$r,'commitdiff');\n"); p.print("}\n"); p.print("if ($cgi->param('hb')) {\n"); p.print(" add_review_link($cgi->param('hb'));\n"); p.print("} elsif ($cgi->param('h')) {\n"); p.print(" add_review_link($cgi->param('h'));\n"); p.print("} else {\n"); p.print(" add_review_link();\n"); p.print("}\n"); // If the administrator has created a site-specific gitweb_config, // load that before we perform any final overrides. // Path sitecfg = site.site_gitweb; if (Files.isRegularFile(sitecfg)) { p.print("$GITWEB_CONFIG = " + quoteForPerl(sitecfg) + ";\n"); p.print("if (-e $GITWEB_CONFIG) {\n"); p.print(" do " + quoteForPerl(sitecfg) + ";\n"); p.print("}\n"); } Path root = repoManager.getBasePath(); p.print("$projectroot = " + quoteForPerl(root) + ";\n"); // Permit exporting only the project we were started for. // We use the name under $projectroot in case symlinks // were involved in the path. // p.print("$export_auth_hook = sub {\n"); p.print(" my $dir = shift;\n"); p.print(" my $name = $ENV{'GERRIT_PROJECT_NAME'};\n"); p.print(" my $allow = qq{$projectroot/$name.git};\n"); p.print(" return $dir eq $allow;\n"); p.print(" };\n"); // Do not allow the administrator to enable path info, its // not a URL format we currently support. // p.print("$feature{'pathinfo'}{'override'} = 0;\n"); p.print("$feature{'pathinfo'}{'default'} = [0];\n"); // We don't do forking, so don't allow it to be enabled. // p.print("$feature{'forks'}{'override'} = 0;\n"); p.print("$feature{'forks'}{'default'} = [0];\n"); } myconfFile.setReadOnly(); }