Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#1039 Use merged and validated of version .rultor.yml for merge command. #1070

Merged
merged 2 commits into from
Mar 26, 2016
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 91 additions & 12 deletions src/main/java/com/rultor/profiles/Profiles.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
import com.jcabi.aspects.Cacheable;
import com.jcabi.aspects.Immutable;
import com.jcabi.aspects.Tv;
import com.jcabi.github.Coordinates;
import com.jcabi.github.Github;
import com.jcabi.github.RtGithub;
import com.jcabi.github.wire.RetryCarefulWire;
Expand All @@ -42,6 +41,7 @@
import com.rultor.spi.Profile;
import com.rultor.spi.Talk;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import lombok.EqualsAndHashCode;
import lombok.ToString;
Expand All @@ -58,6 +58,11 @@
@EqualsAndHashCode
public final class Profiles {

/**
* Merge command.
*/
private static final String MERGE = "merge";

/**
* Fetch a profile from a talk.
* @param talk The talk
Expand All @@ -73,33 +78,107 @@ public Profile fetch(final Talk talk) throws IOException {
if (xml.nodes("/talk/wire").isEmpty()) {
profile = Profile.EMPTY;
} else {
profile = Profiles.fetch(xml);
profile = this.fetch(xml);
}
}
return profile;
}

/**
* Merge profile from master and fork. Merged profile must be profile
* from fork, but all lists for commanders and architects must be taken
* from master branch.
* @param master Profile from master branch
* @param fork Fork that will be merged
* @param branch Fork branch that will be merged
* @return Merged profile
*/
public Profile merged(final Profile master, final String fork,
final String branch) {
return master;
}

/**
* Validate merged profile: merged profile must have no changes in architect
* and commander sections (full match with master profile).
* @param master Profile from master branch
* @param merged Result of merging master and fork profiles
* @return Validated profile
* @throws IOException If fails
* @todo #1039:30min Add integration test to be sure that validation
* exception will eventually be posted as an Answer in GitHub.
* After you create integration test, add `validated` method call in
* `fetch` method: `...this.validated(master, this.merged(...`.
* Modify `merged` method implementation: merged profile is a
* `.rultor.yml` form result of real `git merge` of master branch and
* fork branch. We need real `git merge` result here. See some details
* here: https://github.com/yegor256/rultor/pull/1064/files#r56796959
*/
public Profile validated(final Profile master, final Profile merged)
throws IOException {
final String commanders = "commanders";
final String[][] security = {
{"architect"},
{Profiles.MERGE, commanders},
{"deploy", commanders},
{"release", commanders},
};
for (final String[] section : security) {
if (!Arrays.equals(
Profiles.section(master, section),
Profiles.section(merged, section)
)) {
throw new Profile.ConfigException(
String.format(
"You cannot change `%s` section for security reasons",
Arrays.toString(section)
)
);
}
}
return merged;
}

/**
* Get section content.
* @param profile Profile
* @param section Section of profile
* @return Content of section as array of strings
* @throws IOException If fails
*/
private static String[] section(final Profile profile,
final String... section)
throws IOException {
final StringBuilder path = new StringBuilder(Tv.HUNDRED);
for (final String element : section) {
path.append(String.format("/entry[@key='%s']", element));
}
final List<String> result = profile.read().xpath(
String.format("/%s/item/text()", path.toString())
);
return result.toArray(new String[result.size()]);
}

/**
* Fetch a profile from an XML.
* @param xml The XML
* @return Profile found
* @throws IOException If fails
*/
private static Profile fetch(final XML xml) {
private Profile fetch(final XML xml) throws IOException {
final Profile profile;
final List<String> type = xml.xpath("//request/type/text()");
if (type.isEmpty() || !"merge".equals(type.get(0))) {
if (type.isEmpty() || !Profiles.MERGE.equals(type.get(0))) {
profile = new GithubProfile(
new TalkIssues(Profiles.github(), xml).get().repo()
);
} else {
profile = new GithubProfile(
Profiles.github().repos().get(
new Coordinates.Simple(
xml.xpath(
"//request/args/arg[@name='fork']/text()"
).get(0)
)
),
final Profile master = new GithubProfile(
new TalkIssues(Profiles.github(), xml).get().repo()
);
profile = this.merged(
master,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@xupyprmv the variable master is redundant here, please inline this real quick :)

xml.xpath("//request/args/arg[@name='fork']/text()").get(0),
xml.xpath(
"//request/args/arg[@name='fork_branch']/text()"
).get(0)
Expand Down
Loading