├── .codecov.yml ├── .travis.yml ├── LICENSE ├── app ├── build.gradle └── src │ ├── main │ ├── java │ │ └── dev │ │ │ └── youshallnotpass │ │ │ ├── App.java │ │ │ ├── Badge.java │ │ │ ├── YsnpDb.java │ │ │ ├── YsnpException.java │ │ │ ├── cactoos │ │ │ ├── YsnpFunc.java │ │ │ └── YsnpScalar.java │ │ │ ├── inspection │ │ │ ├── Inspection.java │ │ │ ├── TkViolation.java │ │ │ ├── Violation.java │ │ │ ├── Violations.java │ │ │ ├── YsnpBadge.java │ │ │ ├── YsnpViolation.java │ │ │ ├── allfinal │ │ │ │ ├── DbAllfinal.java │ │ │ │ ├── DbNonfinals.java │ │ │ │ └── TkAllfinal.java │ │ │ ├── allpublic │ │ │ │ ├── DbAllpublic.java │ │ │ │ ├── DbNonpublics.java │ │ │ │ └── TkAllpublic.java │ │ │ ├── inheritancefree │ │ │ │ ├── DbInheritanceFree.java │ │ │ │ ├── DbInheritances.java │ │ │ │ └── TkInheritanceFree.java │ │ │ ├── nomultiplereturn │ │ │ │ ├── DbMultipleReturns.java │ │ │ │ ├── DbNoMultipleReturn.java │ │ │ │ └── TkNoMultipleReturn.java │ │ │ ├── nullfree │ │ │ │ ├── DbNullfree.java │ │ │ │ ├── DbNulls.java │ │ │ │ └── TkNullfree.java │ │ │ ├── setterfree │ │ │ │ ├── DbSetterFree.java │ │ │ │ ├── DbSetters.java │ │ │ │ └── TkSetterFree.java │ │ │ └── staticfree │ │ │ │ ├── DbStaticfree.java │ │ │ │ ├── DbStatics.java │ │ │ │ └── TkStaticfree.java │ │ │ ├── migrations │ │ │ ├── Migration0.java │ │ │ ├── Migration1.java │ │ │ ├── Migration2.java │ │ │ ├── Migration3.java │ │ │ ├── Migration4.java │ │ │ ├── Migration5.java │ │ │ ├── Migration6.java │ │ │ └── Migration7.java │ │ │ ├── readme │ │ │ └── TkReadme.java │ │ │ └── repo │ │ │ ├── DbRepo.java │ │ │ ├── DbRepos.java │ │ │ ├── Repo.java │ │ │ └── Repos.java │ └── resources │ │ ├── logback.xml │ │ └── readme │ │ └── readme.html │ └── test │ └── java │ └── dev │ └── youshallnotpass │ ├── AppTest.java │ ├── SqliteDb.java │ ├── migrations │ └── Migration3Test.java │ ├── readme │ └── TkReadmeTest.java │ └── repo │ └── DbReposTest.java ├── assets ├── logo.ai └── logo.png ├── build.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── readme.md └── settings.gradle /.codecov.yml: -------------------------------------------------------------------------------- 1 | coverage: 2 | status: 3 | project: 4 | default: 5 | target: 60% 6 | patch: no 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | sudo: false # faster builds 3 | 4 | script: 5 | - ./gradlew youshallnotpass check 6 | 7 | after_success: 8 | - bash <(curl -s https://codecov.io/bash) -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Alexey Nikitin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | id 'application' 4 | id 'jacoco' 5 | } 6 | 7 | group = ext.group 8 | version = ext.version 9 | 10 | sourceCompatibility = 1.8 11 | 12 | dependencies { 13 | implementation 'org.takes:takes:1.19' 14 | implementation 'org.apache.velocity:velocity-engine-core:2.2' 15 | implementation 'com.atlassian.commonmark:commonmark:0.12.1' 16 | implementation 'commons-io:commons-io:2.6' 17 | implementation 'com.nikialeksey:jood:3.0.0' 18 | implementation 'org.xerial:sqlite-jdbc:3.34.0' 19 | implementation 'com.mchange:c3p0:0.9.5.5' 20 | implementation 'ch.qos.logback:logback-classic:1.2.3' 21 | testImplementation 'com.nikialeksey:nullfree:1.4.3' 22 | testImplementation group: 'junit', name: 'junit', version: '4.12' 23 | } 24 | 25 | jacoco { 26 | toolVersion = "0.8.5" 27 | } 28 | jacocoTestReport { 29 | reports { 30 | xml.enabled = true 31 | html.enabled = false 32 | } 33 | } 34 | 35 | check.dependsOn jacocoTestReport 36 | 37 | mainClassName = 'dev.youshallnotpass.App' 38 | 39 | jar { 40 | manifest { 41 | attributes( 42 | 'Main-Class': 'dev.youshallnotpass.App' 43 | ) 44 | } 45 | from { 46 | configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/App.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass; 2 | 3 | import dev.youshallnotpass.inspection.allfinal.TkAllfinal; 4 | import dev.youshallnotpass.inspection.allpublic.TkAllpublic; 5 | import dev.youshallnotpass.inspection.inheritancefree.TkInheritanceFree; 6 | import dev.youshallnotpass.inspection.nomultiplereturn.TkNoMultipleReturn; 7 | import dev.youshallnotpass.inspection.nullfree.TkNullfree; 8 | import dev.youshallnotpass.inspection.setterfree.TkSetterFree; 9 | import dev.youshallnotpass.inspection.staticfree.TkStaticfree; 10 | import dev.youshallnotpass.readme.TkReadme; 11 | import dev.youshallnotpass.repo.DbRepos; 12 | import dev.youshallnotpass.repo.Repos; 13 | import com.nikialeksey.jood.JdDb; 14 | import org.cactoos.scalar.Solid; 15 | import org.takes.Request; 16 | import org.takes.Response; 17 | import org.takes.Take; 18 | import org.takes.facets.fallback.FbChain; 19 | import org.takes.facets.fallback.FbStatus; 20 | import org.takes.facets.fallback.TkFallback; 21 | import org.takes.facets.fork.FkRegex; 22 | import org.takes.facets.fork.TkFork; 23 | import org.takes.http.Exit; 24 | import org.takes.http.FtBasic; 25 | import org.takes.rs.RsText; 26 | 27 | import java.io.File; 28 | import java.net.URL; 29 | import java.sql.DriverManager; 30 | 31 | public final class App implements Take { 32 | 33 | private final Take origin; 34 | 35 | public App(final Repos repos) { 36 | this( 37 | new TkFallback( 38 | new TkFork( 39 | new FkRegex( 40 | "(/)?", 41 | new TkReadme( 42 | () -> new URL("https://raw.githubusercontent.com/youshallnotpass-dev/service/master/readme.md"), 43 | "Youshallnotpass", 44 | "https://github.com/youshallnotpass-dev/service" 45 | ) 46 | ), 47 | new FkRegex( 48 | "/nullfree(/)?", 49 | new TkReadme( 50 | () -> new URL("https://raw.githubusercontent.com/youshallnotpass-dev/service/master/readme.md"), 51 | "NullFree", 52 | "https://github.com/youshallnotpass-dev/service" 53 | ) 54 | ), 55 | new FkRegex( 56 | "/nullfree/.+", 57 | new TkFork( 58 | new FkRegex( 59 | "/nullfree/(?[^/]+)/(?[^/]+)", 60 | new TkNullfree( 61 | repos 62 | ) 63 | ) 64 | ) 65 | ), 66 | new FkRegex( 67 | "/staticfree(/)?", 68 | new TkReadme( 69 | () -> new URL("https://raw.githubusercontent.com/youshallnotpass-dev/service/master/readme.md"), 70 | "StaticFree", 71 | "https://github.com/youshallnotpass-dev/service" 72 | ) 73 | ), 74 | new FkRegex( 75 | "/staticfree/.+", 76 | new TkFork( 77 | new FkRegex( 78 | "/staticfree/(?[^/]+)/(?[^/]+)", 79 | new TkStaticfree( 80 | repos 81 | ) 82 | ) 83 | ) 84 | ), 85 | new FkRegex( 86 | "/allfinal(/)?", 87 | new TkReadme( 88 | () -> new URL("https://raw.githubusercontent.com/youshallnotpass-dev/service/master/readme.md"), 89 | "AllFinal", 90 | "https://github.com/youshallnotpass-dev/service" 91 | ) 92 | ), 93 | new FkRegex( 94 | "/allfinal/.+", 95 | new TkFork( 96 | new FkRegex( 97 | "/allfinal/(?[^/]+)/(?[^/]+)", 98 | new TkAllfinal( 99 | repos 100 | ) 101 | ) 102 | ) 103 | ), 104 | new FkRegex( 105 | "/allpublic(/)?", 106 | new TkReadme( 107 | () -> new URL("https://raw.githubusercontent.com/youshallnotpass-dev/service/master/readme.md"), 108 | "AllPublic", 109 | "https://github.com/youshallnotpass-dev/service" 110 | ) 111 | ), 112 | new FkRegex( 113 | "/allpublic/.+", 114 | new TkFork( 115 | new FkRegex( 116 | "/allpublic/(?[^/]+)/(?[^/]+)", 117 | new TkAllpublic( 118 | repos 119 | ) 120 | ) 121 | ) 122 | ), 123 | 124 | new FkRegex( 125 | "/nomultiplereturn(/)?", 126 | new TkReadme( 127 | () -> new URL("https://raw.githubusercontent.com/youshallnotpass-dev/service/master/readme.md"), 128 | "NoMultipleReturn", 129 | "https://github.com/youshallnotpass-dev/service" 130 | ) 131 | ), 132 | new FkRegex( 133 | "/nomultiplereturn/.+", 134 | new TkFork( 135 | new FkRegex( 136 | "/nomultiplereturn/(?[^/]+)/(?[^/]+)", 137 | new TkNoMultipleReturn( 138 | repos 139 | ) 140 | ) 141 | ) 142 | ), 143 | 144 | new FkRegex( 145 | "/setterfree(/)?", 146 | new TkReadme( 147 | () -> new URL("https://raw.githubusercontent.com/youshallnotpass-dev/service/master/readme.md"), 148 | "SetterFree", 149 | "https://github.com/youshallnotpass-dev/service" 150 | ) 151 | ), 152 | new FkRegex( 153 | "/setterfree/.+", 154 | new TkFork( 155 | new FkRegex( 156 | "/setterfree/(?[^/]+)/(?[^/]+)", 157 | new TkSetterFree( 158 | repos 159 | ) 160 | ) 161 | ) 162 | ), 163 | 164 | new FkRegex( 165 | "/inheritancefree(/)?", 166 | new TkReadme( 167 | () -> new URL("https://raw.githubusercontent.com/youshallnotpass-dev/service/master/readme.md"), 168 | "InheritanceFree", 169 | "https://github.com/youshallnotpass-dev/service" 170 | ) 171 | ), 172 | new FkRegex( 173 | "/inheritancefree/.+", 174 | new TkFork( 175 | new FkRegex( 176 | "/inheritancefree/(?[^/]+)/(?[^/]+)", 177 | new TkInheritanceFree( 178 | repos 179 | ) 180 | ) 181 | ) 182 | ) 183 | ), 184 | new FbChain( 185 | new FbStatus(404, new RsText("sorry, page is absent")), 186 | new FbStatus(405, new RsText("this method is not allowed here")) 187 | ) 188 | ) 189 | ); 190 | } 191 | 192 | private App(final Take origin) { 193 | this.origin = origin; 194 | } 195 | 196 | @Override 197 | public Response act(final Request req) throws Exception { 198 | return origin.act(req); 199 | } 200 | 201 | @SuppressWarnings("staticfree") 202 | public static void main(final String... args) throws Exception { 203 | new FtBasic( 204 | new App( 205 | new DbRepos( 206 | new YsnpDb( 207 | new JdDb( 208 | new Solid<>( 209 | () -> DriverManager.getConnection( 210 | String.format( 211 | "jdbc:sqlite:%s", 212 | new File("./iwfy.db").getAbsolutePath() 213 | ) 214 | ) 215 | ) 216 | ) 217 | ) 218 | ) 219 | ), 220 | 8080 221 | ).start(Exit.NEVER); 222 | } 223 | } 224 | -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/Badge.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass; 2 | 3 | public interface Badge { 4 | String asString() throws YsnpException; 5 | } 6 | -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/YsnpDb.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass; 2 | 3 | import dev.youshallnotpass.migrations.Migration0; 4 | import dev.youshallnotpass.migrations.Migration1; 5 | import dev.youshallnotpass.migrations.Migration2; 6 | import dev.youshallnotpass.migrations.Migration3; 7 | import dev.youshallnotpass.migrations.Migration4; 8 | import dev.youshallnotpass.migrations.Migration5; 9 | import dev.youshallnotpass.migrations.Migration6; 10 | import dev.youshallnotpass.migrations.Migration7; 11 | import com.nikialeksey.jood.Db; 12 | import com.nikialeksey.jood.JdException; 13 | import com.nikialeksey.jood.JdMigrations; 14 | import com.nikialeksey.jood.MigrationsDb; 15 | import com.nikialeksey.jood.QueryResult; 16 | import com.nikialeksey.jood.Transaction; 17 | import com.nikialeksey.jood.sql.Sql; 18 | 19 | public final class YsnpDb implements Db { 20 | 21 | private final Db origin; 22 | 23 | public YsnpDb(final Db db) { 24 | this( 25 | new MigrationsDb( 26 | db, 27 | new JdMigrations( 28 | new Migration0(), 29 | new Migration1(), 30 | new Migration2(), 31 | new Migration3(), 32 | new Migration4(), 33 | new Migration5(), 34 | new Migration6(), 35 | new Migration7() 36 | ), 37 | 8 38 | ) 39 | ); 40 | } 41 | 42 | public YsnpDb(final MigrationsDb origin) { 43 | this.origin = origin; 44 | } 45 | 46 | @Override 47 | public QueryResult read(final Sql sql) throws JdException { 48 | return origin.read(sql); 49 | } 50 | 51 | @Override 52 | public void write(final Sql sql) throws JdException { 53 | origin.write(sql); 54 | } 55 | 56 | @Override 57 | public QueryResult writeReturnGenerated(final Sql sql) throws JdException { 58 | return origin.writeReturnGenerated(sql); 59 | } 60 | 61 | @Override 62 | public void run(final Transaction transaction) throws JdException { 63 | origin.run(transaction); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/YsnpException.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass; 2 | 3 | @SuppressWarnings("inheritancefree") 4 | public final class YsnpException extends Exception { 5 | 6 | public YsnpException(final String message) { 7 | super(message); 8 | } 9 | 10 | public YsnpException(final String message, final Throwable cause) { 11 | super(message, cause); 12 | } 13 | 14 | public YsnpException(final Throwable cause) { 15 | super(cause); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/cactoos/YsnpFunc.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass.cactoos; 2 | 3 | import dev.youshallnotpass.YsnpException; 4 | import org.cactoos.Func; 5 | 6 | public final class YsnpFunc implements Func { 7 | 8 | private final Func func; 9 | 10 | public YsnpFunc(final Func fnc) { 11 | this.func = fnc; 12 | } 13 | 14 | @Override 15 | public Y apply(final X input) throws YsnpException { 16 | return new YsnpScalar<>(() -> this.func.apply(input)).value(); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/cactoos/YsnpScalar.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass.cactoos; 2 | 3 | import dev.youshallnotpass.YsnpException; 4 | import org.cactoos.Scalar; 5 | import org.cactoos.scalar.Checked; 6 | 7 | public final class YsnpScalar implements Scalar { 8 | 9 | private final Scalar origin; 10 | 11 | public YsnpScalar(final Scalar scalar) { 12 | this.origin = scalar; 13 | } 14 | 15 | @Override 16 | public T value() throws YsnpException { 17 | return new Checked<>( 18 | this.origin, 19 | YsnpException::new 20 | ).value(); 21 | } 22 | 23 | } -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/inspection/Inspection.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass.inspection; 2 | 3 | import dev.youshallnotpass.YsnpException; 4 | import org.cactoos.list.ListOf; 5 | 6 | import java.util.List; 7 | 8 | public interface Inspection { 9 | String badgeUrl() throws YsnpException; 10 | 11 | void calcBadge() throws YsnpException; 12 | 13 | void updateThreshold(final int threshold) throws YsnpException; 14 | 15 | Violations violations() throws YsnpException; 16 | 17 | final class Fake implements Inspection { 18 | 19 | private final List badge; 20 | private final Violations violations; 21 | private final List threshold; 22 | 23 | public Fake() { 24 | this(new ListOf<>(), new Violations.Fake(), new ListOf<>(0)); 25 | } 26 | 27 | public Fake(final String badgeUrl, final Violations violations) { 28 | this(new ListOf<>(badgeUrl), violations, new ListOf<>(0)); 29 | } 30 | 31 | private Fake( 32 | final List badge, 33 | final Violations violations, 34 | final List threshold 35 | ) { 36 | this.badge = badge; 37 | this.violations = violations; 38 | this.threshold = threshold; 39 | } 40 | 41 | @Override 42 | public String badgeUrl() throws YsnpException { 43 | if (badge.isEmpty()) { 44 | throw new YsnpException("Repo does not contain the badge."); 45 | } 46 | return badge.get(0); 47 | } 48 | 49 | @Override 50 | public void updateThreshold(final int threshold) throws YsnpException { 51 | this.threshold.set(0, threshold); 52 | } 53 | 54 | @Override 55 | public Violations violations() { 56 | return violations; 57 | } 58 | 59 | @Override 60 | public void calcBadge() throws YsnpException { 61 | final String url; 62 | if (violations.count() > threshold.get(0)) { 63 | url = "red"; 64 | } else { 65 | url = "green"; 66 | } 67 | 68 | if (badge.isEmpty()) { 69 | badge.add(url); 70 | } else { 71 | badge.set(0, url); 72 | } 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/inspection/TkViolation.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass.inspection; 2 | 3 | import dev.youshallnotpass.YsnpException; 4 | import dev.youshallnotpass.cactoos.YsnpFunc; 5 | import org.cactoos.text.TextOf; 6 | import org.takes.Response; 7 | import org.takes.facets.fork.RqRegex; 8 | import org.takes.facets.fork.TkRegex; 9 | import org.takes.misc.Sprintf; 10 | import org.takes.rq.RqMethod; 11 | import org.takes.rq.form.RqFormBase; 12 | import org.takes.rs.RsRedirect; 13 | import org.takes.rs.RsWithBody; 14 | import org.takes.rs.RsWithStatus; 15 | 16 | import java.io.IOException; 17 | import java.net.HttpURLConnection; 18 | import java.util.Iterator; 19 | 20 | public final class TkViolation implements TkRegex { 21 | 22 | private final YsnpFunc reqInspection; 23 | 24 | public TkViolation(final YsnpFunc reqInspection) { 25 | this.reqInspection = reqInspection; 26 | } 27 | 28 | @Override 29 | public Response act(final RqRegex req) throws IOException { 30 | final String method = new RqMethod.Base(req).method(); 31 | final Response response; 32 | 33 | if ("POST".equals(method)) { 34 | @SuppressWarnings("allfinal") 35 | Response postResponse; 36 | try { 37 | final Inspection inspection = reqInspection.apply(req); 38 | final RqFormBase form = new RqFormBase(req); 39 | final Iterator thresholdIterator = form.param("threshold").iterator(); 40 | final int threshold; 41 | if (thresholdIterator.hasNext()) { 42 | threshold = Integer.parseInt(thresholdIterator.next()); 43 | } else { 44 | threshold = 0; 45 | } 46 | inspection.updateThreshold(threshold); 47 | final Violations violations = inspection.violations(); 48 | violations.clear(); 49 | final Iterable newViolations = form.param("violation"); 50 | for (final String violation : newViolations) { 51 | violations.add(new YsnpViolation(violation)); 52 | } 53 | inspection.calcBadge(); 54 | postResponse = new RsWithStatus( 55 | new RsWithBody("Saved!\n"), 56 | HttpURLConnection.HTTP_OK 57 | ); 58 | } catch (final YsnpException e) { 59 | postResponse = new RsWithStatus( 60 | new RsWithBody( 61 | new Sprintf( 62 | "%s\n%s", 63 | "Can not save or update the badge.", 64 | new TextOf(e) 65 | ) 66 | ), 67 | HttpURLConnection.HTTP_INTERNAL_ERROR 68 | ); 69 | } 70 | response = postResponse; 71 | } else { 72 | @SuppressWarnings("allfinal") 73 | Response getResponse; 74 | try { 75 | getResponse = new RsRedirect( 76 | reqInspection.apply(req).badgeUrl() 77 | ); 78 | } catch (final YsnpException e) { 79 | getResponse = new RsWithStatus( 80 | new RsWithBody( 81 | new Sprintf( 82 | "%s\n%s", 83 | "Could not not get the badge.", 84 | new TextOf(e) 85 | ) 86 | ), 87 | HttpURLConnection.HTTP_INTERNAL_ERROR 88 | ); 89 | } 90 | response = getResponse; 91 | } 92 | return response; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/inspection/Violation.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass.inspection; 2 | 3 | import dev.youshallnotpass.YsnpException; 4 | 5 | public interface Violation { 6 | 7 | String description() throws YsnpException; 8 | 9 | final class Fake implements Violation { 10 | private final String description; 11 | 12 | public Fake(final String description) { 13 | this.description = description; 14 | } 15 | 16 | @Override 17 | public String description() throws YsnpException { 18 | return description; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/inspection/Violations.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass.inspection; 2 | 3 | import dev.youshallnotpass.YsnpException; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | public interface Violations { 9 | void clear() throws YsnpException; 10 | 11 | void add(final Violation violation) throws YsnpException; 12 | 13 | int count() throws YsnpException; 14 | 15 | final class Fake implements Violations { 16 | private final List violations; 17 | 18 | public Fake() { 19 | this(new ArrayList<>()); 20 | } 21 | 22 | public Fake(final List violations) { 23 | this.violations = violations; 24 | } 25 | 26 | @Override 27 | public void clear() throws YsnpException { 28 | violations.clear(); 29 | } 30 | 31 | @Override 32 | public void add(final Violation violation) throws YsnpException { 33 | violations.add(violation); 34 | } 35 | 36 | @Override 37 | public int count() throws YsnpException { 38 | return violations.size(); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/inspection/YsnpBadge.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass.inspection; 2 | 3 | import dev.youshallnotpass.Badge; 4 | import dev.youshallnotpass.YsnpException; 5 | import org.cactoos.Scalar; 6 | 7 | public final class YsnpBadge implements Badge { 8 | 9 | private final String title; 10 | private final Scalar isGreen; 11 | 12 | public YsnpBadge(final String title, final Scalar isGreen) { 13 | this.title = title; 14 | this.isGreen = isGreen; 15 | } 16 | 17 | @Override 18 | public String asString() throws YsnpException { 19 | final boolean green; 20 | try { 21 | green = isGreen.value(); 22 | } catch (final Exception e) { 23 | throw new YsnpException( 24 | "Could not determine the badge color.", 25 | e 26 | ); 27 | } 28 | final String message; 29 | final String color; 30 | if (green) { 31 | message = "approved"; 32 | color = "green"; 33 | } else { 34 | message = "declined"; 35 | color = "red"; 36 | } 37 | return String.format( 38 | "https://img.shields.io/badge/%s-%s-%s.svg", 39 | title, 40 | message, 41 | color 42 | ); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/inspection/YsnpViolation.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass.inspection; 2 | 3 | import dev.youshallnotpass.YsnpException; 4 | 5 | public final class YsnpViolation implements Violation { 6 | 7 | private final String description; 8 | 9 | public YsnpViolation(final String description) { 10 | this.description = description; 11 | } 12 | 13 | @Override 14 | public String description() throws YsnpException { 15 | return description; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/inspection/allfinal/DbAllfinal.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass.inspection.allfinal; 2 | 3 | import dev.youshallnotpass.YsnpException; 4 | import dev.youshallnotpass.inspection.Inspection; 5 | import dev.youshallnotpass.inspection.YsnpBadge; 6 | import dev.youshallnotpass.inspection.Violations; 7 | import com.nikialeksey.jood.Db; 8 | import com.nikialeksey.jood.JdException; 9 | import com.nikialeksey.jood.QueryResult; 10 | import com.nikialeksey.jood.args.IntArg; 11 | import com.nikialeksey.jood.args.StringArg; 12 | import com.nikialeksey.jood.sql.JdSql; 13 | import org.takes.misc.Sprintf; 14 | 15 | import java.sql.ResultSet; 16 | import java.sql.SQLException; 17 | 18 | public final class DbAllfinal implements Inspection { 19 | 20 | private final Db db; 21 | private final String id; 22 | 23 | public DbAllfinal(final Db db, final String id) { 24 | this.db = db; 25 | this.id = id; 26 | } 27 | 28 | @Override 29 | public String badgeUrl() throws YsnpException { 30 | try ( 31 | final QueryResult result = db.read( 32 | new JdSql( 33 | "SELECT badgeUrl FROM allfinal WHERE id = ?", 34 | new StringArg(id) 35 | ) 36 | ) 37 | ) { 38 | final ResultSet rs = result.rs(); 39 | if (!rs.next()) { 40 | throw new YsnpException( 41 | "allfinal does not exists for id " + id 42 | ); 43 | } 44 | return rs.getString("badgeUrl"); 45 | } catch (final SQLException | JdException e) { 46 | throw new YsnpException("Can not get the badge.", e); 47 | } 48 | } 49 | 50 | @Override 51 | public void calcBadge() throws YsnpException { 52 | try ( 53 | final QueryResult result = db.read( 54 | new JdSql( 55 | "SELECT threshold FROM allfinal WHERE id = ?", 56 | new StringArg(id) 57 | ) 58 | ) 59 | ) { 60 | final ResultSet rs = result.rs(); 61 | if (!rs.next()) { 62 | throw new YsnpException( 63 | new Sprintf( 64 | "Can not find the allfinal with id '%s'.", 65 | id 66 | ).toString() 67 | ); 68 | } 69 | final int threshold = rs.getInt("threshold"); 70 | db.write( 71 | new JdSql( 72 | "UPDATE allfinal SET badgeUrl = ? WHERE id = ?", 73 | new StringArg( 74 | new YsnpBadge( 75 | "allfinal", 76 | () -> violations().count() <= threshold 77 | ).asString() 78 | ), 79 | new StringArg(id) 80 | ) 81 | ); 82 | } catch (final SQLException | JdException e) { 83 | throw new YsnpException( 84 | new Sprintf( 85 | "Can not calc the badge by allfinal '%s'", 86 | id 87 | ).toString(), 88 | e 89 | ); 90 | } 91 | } 92 | 93 | @Override 94 | public void updateThreshold(final int threshold) throws YsnpException { 95 | try { 96 | db.write( 97 | new JdSql( 98 | "UPDATE allfinal SET threshold = ? WHERE id = ?", 99 | new IntArg(threshold), 100 | new StringArg(id) 101 | ) 102 | ); 103 | } catch (final JdException e) { 104 | throw new YsnpException( 105 | new Sprintf( 106 | "Can not update the threshold in allfinal with id '%s'", 107 | id 108 | ).toString(), 109 | e 110 | ); 111 | } 112 | } 113 | 114 | @Override 115 | public Violations violations() throws YsnpException { 116 | try ( 117 | final QueryResult qr = db.read( 118 | new JdSql( 119 | "SELECT repo FROM allfinal WHERE id = ?", 120 | new StringArg(id) 121 | ) 122 | ) 123 | ) { 124 | final ResultSet rs = qr.rs(); 125 | if (!rs.next()) { 126 | throw new YsnpException( 127 | "Could not find the allfinal by id " + id 128 | ); 129 | } 130 | return new DbNonfinals(db, rs.getString("repo")); 131 | } catch (final JdException | SQLException e) { 132 | throw new YsnpException( 133 | "Could not get the allfinal info by id " + id, 134 | e 135 | ); 136 | } 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/inspection/allfinal/DbNonfinals.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass.inspection.allfinal; 2 | 3 | import dev.youshallnotpass.YsnpException; 4 | import dev.youshallnotpass.inspection.Violation; 5 | import dev.youshallnotpass.inspection.Violations; 6 | import com.nikialeksey.jood.Db; 7 | import com.nikialeksey.jood.JdException; 8 | import com.nikialeksey.jood.QueryResult; 9 | import com.nikialeksey.jood.args.StringArg; 10 | import com.nikialeksey.jood.sql.JdSql; 11 | import org.takes.misc.Sprintf; 12 | 13 | import java.sql.ResultSet; 14 | import java.sql.SQLException; 15 | import java.util.UUID; 16 | 17 | public final class DbNonfinals implements Violations { 18 | 19 | private final Db db; 20 | private final String repo; 21 | 22 | public DbNonfinals(final Db db, final String repo) { 23 | this.db = db; 24 | this.repo = repo; 25 | } 26 | 27 | @Override 28 | public void clear() throws YsnpException { 29 | try { 30 | db.write( 31 | new JdSql( 32 | "DELETE FROM allfinal_violation WHERE repo = ?", 33 | new StringArg(repo) 34 | ) 35 | ); 36 | db.write( 37 | new JdSql( 38 | "UPDATE allfinal SET badgeUrl = '' WHERE repo = ?", 39 | new StringArg(repo) 40 | ) 41 | ); 42 | } catch (final JdException e) { 43 | throw new YsnpException( 44 | new Sprintf( 45 | "Can not clear the nonfinals for repo '%s'", 46 | repo 47 | ).toString(), 48 | e 49 | ); 50 | } 51 | } 52 | 53 | @Override 54 | public void add(final Violation violation) throws YsnpException { 55 | try { 56 | final String id = UUID.randomUUID().toString(); 57 | db.write( 58 | new JdSql( 59 | "INSERT OR REPLACE INTO allfinal_violation VALUES(?, ?, ?)", 60 | new StringArg(id), 61 | new StringArg(repo), 62 | new StringArg(violation.description()) 63 | ) 64 | ); 65 | } catch (final JdException e) { 66 | throw new YsnpException( 67 | new Sprintf( 68 | "Can not add the nonfinal '%s' in repo '%s'", 69 | repo, 70 | violation.description() 71 | ).toString(), 72 | e 73 | ); 74 | } 75 | } 76 | 77 | @Override 78 | public int count() throws YsnpException { 79 | try ( 80 | final QueryResult result = db.read( 81 | new JdSql( 82 | "SELECT count(*) FROM allfinal_violation WHERE repo = ?", 83 | new StringArg(repo) 84 | ) 85 | ); 86 | ) { 87 | final ResultSet rs = result.rs(); 88 | if (!rs.next()) { 89 | throw new YsnpException("'SELECT count(*)' returned nothing."); 90 | } 91 | return rs.getInt(1); 92 | } catch (final SQLException | JdException e) { 93 | throw new YsnpException("Can not get the nonfinals count.", e); 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/inspection/allfinal/TkAllfinal.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass.inspection.allfinal; 2 | 3 | import dev.youshallnotpass.cactoos.YsnpFunc; 4 | import dev.youshallnotpass.inspection.TkViolation; 5 | import dev.youshallnotpass.repo.Repos; 6 | import org.takes.Response; 7 | import org.takes.facets.fork.RqRegex; 8 | import org.takes.facets.fork.TkRegex; 9 | 10 | import java.io.IOException; 11 | import java.util.regex.Matcher; 12 | 13 | public final class TkAllfinal implements TkRegex { 14 | 15 | private final TkViolation origin; 16 | 17 | public TkAllfinal(final Repos repos) { 18 | this( 19 | new TkViolation( 20 | new YsnpFunc<>((final RqRegex rq) -> { 21 | final Matcher matcher = rq.matcher(); 22 | final String user = matcher.group("user"); 23 | final String repo = matcher.group("repo"); 24 | final String path = user + "/" + repo; 25 | return repos.repo(path).allfinal(); 26 | }) 27 | ) 28 | ); 29 | } 30 | 31 | public TkAllfinal(final TkViolation origin) { 32 | this.origin = origin; 33 | } 34 | 35 | @Override 36 | public Response act(final RqRegex req) throws IOException { 37 | return origin.act(req); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/inspection/allpublic/DbAllpublic.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass.inspection.allpublic; 2 | 3 | import dev.youshallnotpass.YsnpException; 4 | import dev.youshallnotpass.inspection.Inspection; 5 | import dev.youshallnotpass.inspection.YsnpBadge; 6 | import dev.youshallnotpass.inspection.Violations; 7 | import com.nikialeksey.jood.Db; 8 | import com.nikialeksey.jood.JdException; 9 | import com.nikialeksey.jood.QueryResult; 10 | import com.nikialeksey.jood.args.IntArg; 11 | import com.nikialeksey.jood.args.StringArg; 12 | import com.nikialeksey.jood.sql.JdSql; 13 | import org.takes.misc.Sprintf; 14 | 15 | import java.sql.ResultSet; 16 | import java.sql.SQLException; 17 | 18 | public final class DbAllpublic implements Inspection { 19 | 20 | private final Db db; 21 | private final String id; 22 | 23 | public DbAllpublic(final Db db, final String id) { 24 | this.db = db; 25 | this.id = id; 26 | } 27 | 28 | @Override 29 | public String badgeUrl() throws YsnpException { 30 | try ( 31 | final QueryResult result = db.read( 32 | new JdSql( 33 | "SELECT badgeUrl FROM allpublic WHERE id = ?", 34 | new StringArg(id) 35 | ) 36 | ) 37 | ) { 38 | final ResultSet rs = result.rs(); 39 | if (!rs.next()) { 40 | throw new YsnpException( 41 | "allpublic does not exists for id " + id 42 | ); 43 | } 44 | return rs.getString("badgeUrl"); 45 | } catch (final SQLException | JdException e) { 46 | throw new YsnpException("Can not get the badge.", e); 47 | } 48 | } 49 | 50 | @Override 51 | public void calcBadge() throws YsnpException { 52 | try ( 53 | final QueryResult result = db.read( 54 | new JdSql( 55 | "SELECT threshold FROM allpublic WHERE id = ?", 56 | new StringArg(id) 57 | ) 58 | ) 59 | ) { 60 | final ResultSet rs = result.rs(); 61 | if (!rs.next()) { 62 | throw new YsnpException( 63 | new Sprintf( 64 | "Can not find the allpublic with id '%s'.", 65 | id 66 | ).toString() 67 | ); 68 | } 69 | final int threshold = rs.getInt("threshold"); 70 | db.write( 71 | new JdSql( 72 | "UPDATE allpublic SET badgeUrl = ? WHERE id = ?", 73 | new StringArg( 74 | new YsnpBadge( 75 | "allpublic", 76 | () -> violations().count() <= threshold 77 | ).asString() 78 | ), 79 | new StringArg(id) 80 | ) 81 | ); 82 | } catch (final SQLException | JdException e) { 83 | throw new YsnpException( 84 | new Sprintf( 85 | "Can not calc the badge by allpublic '%s'", 86 | id 87 | ).toString(), 88 | e 89 | ); 90 | } 91 | } 92 | 93 | @Override 94 | public void updateThreshold(final int threshold) throws YsnpException { 95 | try { 96 | db.write( 97 | new JdSql( 98 | "UPDATE allpublic SET threshold = ? WHERE id = ?", 99 | new IntArg(threshold), 100 | new StringArg(id) 101 | ) 102 | ); 103 | } catch (final JdException e) { 104 | throw new YsnpException( 105 | new Sprintf( 106 | "Can not update the threshold in allpublic with id '%s'", 107 | id 108 | ).toString(), 109 | e 110 | ); 111 | } 112 | } 113 | 114 | @Override 115 | public Violations violations() throws YsnpException { 116 | try ( 117 | final QueryResult qr = db.read( 118 | new JdSql( 119 | "SELECT repo FROM allpublic WHERE id = ?", 120 | new StringArg(id) 121 | ) 122 | ) 123 | ) { 124 | final ResultSet rs = qr.rs(); 125 | if (!rs.next()) { 126 | throw new YsnpException( 127 | "Could not find the allpublic by id " + id 128 | ); 129 | } 130 | return new DbNonpublics(db, rs.getString("repo")); 131 | } catch (final JdException | SQLException e) { 132 | throw new YsnpException( 133 | "Could not get the allpublic info by id " + id, 134 | e 135 | ); 136 | } 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/inspection/allpublic/DbNonpublics.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass.inspection.allpublic; 2 | 3 | import dev.youshallnotpass.YsnpException; 4 | import dev.youshallnotpass.inspection.Violation; 5 | import dev.youshallnotpass.inspection.Violations; 6 | import com.nikialeksey.jood.Db; 7 | import com.nikialeksey.jood.JdException; 8 | import com.nikialeksey.jood.QueryResult; 9 | import com.nikialeksey.jood.args.StringArg; 10 | import com.nikialeksey.jood.sql.JdSql; 11 | import org.takes.misc.Sprintf; 12 | 13 | import java.sql.ResultSet; 14 | import java.sql.SQLException; 15 | import java.util.UUID; 16 | 17 | public final class DbNonpublics implements Violations { 18 | 19 | private final Db db; 20 | private final String repo; 21 | 22 | public DbNonpublics(final Db db, final String repo) { 23 | this.db = db; 24 | this.repo = repo; 25 | } 26 | 27 | @Override 28 | public void clear() throws YsnpException { 29 | try { 30 | db.write( 31 | new JdSql( 32 | "DELETE FROM allpublic_violation WHERE repo = ?", 33 | new StringArg(repo) 34 | ) 35 | ); 36 | db.write( 37 | new JdSql( 38 | "UPDATE allpublic SET badgeUrl = '' WHERE repo = ?", 39 | new StringArg(repo) 40 | ) 41 | ); 42 | } catch (final JdException e) { 43 | throw new YsnpException( 44 | new Sprintf( 45 | "Can not clear the nonpublics for repo '%s'", 46 | repo 47 | ).toString(), 48 | e 49 | ); 50 | } 51 | } 52 | 53 | @Override 54 | public void add(final Violation violation) throws YsnpException { 55 | try { 56 | final String id = UUID.randomUUID().toString(); 57 | db.write( 58 | new JdSql( 59 | "INSERT OR REPLACE INTO allpublic_violation VALUES(?, ?, ?)", 60 | new StringArg(id), 61 | new StringArg(repo), 62 | new StringArg(violation.description()) 63 | ) 64 | ); 65 | } catch (final JdException e) { 66 | throw new YsnpException( 67 | new Sprintf( 68 | "Can not add the nonpublic '%s' in repo '%s'", 69 | repo, 70 | violation.description() 71 | ).toString(), 72 | e 73 | ); 74 | } 75 | } 76 | 77 | @Override 78 | public int count() throws YsnpException { 79 | try ( 80 | final QueryResult result = db.read( 81 | new JdSql( 82 | "SELECT count(*) FROM allpublic_violation WHERE repo = ?", 83 | new StringArg(repo) 84 | ) 85 | ); 86 | ) { 87 | final ResultSet rs = result.rs(); 88 | if (!rs.next()) { 89 | throw new YsnpException("'SELECT count(*)' returned nothing."); 90 | } 91 | return rs.getInt(1); 92 | } catch (final SQLException | JdException e) { 93 | throw new YsnpException("Can not get the nonpublics count.", e); 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/inspection/allpublic/TkAllpublic.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass.inspection.allpublic; 2 | 3 | import dev.youshallnotpass.cactoos.YsnpFunc; 4 | import dev.youshallnotpass.inspection.TkViolation; 5 | import dev.youshallnotpass.repo.Repos; 6 | import org.takes.Response; 7 | import org.takes.facets.fork.RqRegex; 8 | import org.takes.facets.fork.TkRegex; 9 | 10 | import java.io.IOException; 11 | import java.util.regex.Matcher; 12 | 13 | public final class TkAllpublic implements TkRegex { 14 | 15 | private final TkViolation origin; 16 | 17 | public TkAllpublic(final Repos repos) { 18 | this( 19 | new TkViolation( 20 | new YsnpFunc<>((final RqRegex rq) -> { 21 | final Matcher matcher = rq.matcher(); 22 | final String user = matcher.group("user"); 23 | final String repo = matcher.group("repo"); 24 | final String path = user + "/" + repo; 25 | return repos.repo(path).allpublic(); 26 | }) 27 | ) 28 | ); 29 | } 30 | 31 | public TkAllpublic(final TkViolation origin) { 32 | this.origin = origin; 33 | } 34 | 35 | @Override 36 | public Response act(final RqRegex req) throws IOException { 37 | return origin.act(req); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/inspection/inheritancefree/DbInheritanceFree.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass.inspection.inheritancefree; 2 | 3 | import dev.youshallnotpass.YsnpException; 4 | import dev.youshallnotpass.inspection.Inspection; 5 | import dev.youshallnotpass.inspection.YsnpBadge; 6 | import dev.youshallnotpass.inspection.Violations; 7 | import com.nikialeksey.jood.Db; 8 | import com.nikialeksey.jood.JdException; 9 | import com.nikialeksey.jood.QueryResult; 10 | import com.nikialeksey.jood.args.IntArg; 11 | import com.nikialeksey.jood.args.StringArg; 12 | import com.nikialeksey.jood.sql.JdSql; 13 | import java.sql.ResultSet; 14 | import java.sql.SQLException; 15 | 16 | import org.takes.misc.Sprintf; 17 | 18 | public final class DbInheritanceFree implements Inspection { 19 | 20 | private final Db db; 21 | private final String id; 22 | 23 | public DbInheritanceFree(final Db db, final String id) { 24 | this.db = db; 25 | this.id = id; 26 | } 27 | 28 | @Override 29 | public String badgeUrl() throws YsnpException { 30 | try ( 31 | final QueryResult result = db.read( 32 | new JdSql( 33 | "SELECT badgeUrl FROM inheritancefree WHERE id = ?", 34 | new StringArg(id) 35 | ) 36 | ) 37 | ) { 38 | final ResultSet rs = result.rs(); 39 | if (!rs.next()) { 40 | throw new YsnpException( 41 | "Inheritancefree does not exists for id " + id 42 | ); 43 | } 44 | return rs.getString("badgeUrl"); 45 | } catch (final SQLException | JdException e) { 46 | throw new YsnpException("Can not get the badge.", e); 47 | } 48 | } 49 | 50 | @Override 51 | public void calcBadge() throws YsnpException { 52 | try ( 53 | final QueryResult result = db.read( 54 | new JdSql( 55 | "SELECT threshold FROM inheritancefree WHERE id = ?", 56 | new StringArg(id) 57 | ) 58 | ) 59 | ) { 60 | final ResultSet rs = result.rs(); 61 | if (!rs.next()) { 62 | throw new YsnpException( 63 | new Sprintf( 64 | "Can not find the inheritancefree with id '%s'.", 65 | id 66 | ).toString() 67 | ); 68 | } 69 | final int threshold = rs.getInt("threshold"); 70 | db.write( 71 | new JdSql( 72 | "UPDATE inheritancefree SET badgeUrl = ? WHERE id = ?", 73 | new StringArg( 74 | new YsnpBadge( 75 | "inheritancefree", 76 | () -> violations().count() <= threshold 77 | ).asString() 78 | ), 79 | new StringArg(id) 80 | ) 81 | ); 82 | } catch (final SQLException | JdException e) { 83 | throw new YsnpException( 84 | new Sprintf( 85 | "Can not calc the badge by inheritancefree '%s'", 86 | id 87 | ).toString(), 88 | e 89 | ); 90 | } 91 | } 92 | 93 | @Override 94 | public void updateThreshold(final int threshold) throws YsnpException { 95 | try { 96 | db.write( 97 | new JdSql( 98 | "UPDATE inheritancefree SET threshold = ? WHERE id = ?", 99 | new IntArg(threshold), 100 | new StringArg(id) 101 | ) 102 | ); 103 | } catch (final JdException e) { 104 | throw new YsnpException( 105 | new Sprintf( 106 | "Can not update the threshold in inheritancefree with id '%s'", 107 | id 108 | ).toString(), 109 | e 110 | ); 111 | } 112 | } 113 | 114 | @Override 115 | public Violations violations() throws YsnpException { 116 | try ( 117 | final QueryResult qr = db.read( 118 | new JdSql( 119 | "SELECT repo FROM inheritancefree WHERE id = ?", 120 | new StringArg(id) 121 | ) 122 | ) 123 | ) { 124 | final ResultSet rs = qr.rs(); 125 | if (!rs.next()) { 126 | throw new YsnpException( 127 | "Could not find the inheritancefree by id " + id 128 | ); 129 | } 130 | return new DbInheritances(db, rs.getString("repo")); 131 | } catch (final JdException | SQLException e) { 132 | throw new YsnpException( 133 | "Could not get the inheritancefree info by id " + id, 134 | e 135 | ); 136 | } 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/inspection/inheritancefree/DbInheritances.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass.inspection.inheritancefree; 2 | 3 | import dev.youshallnotpass.YsnpException; 4 | import dev.youshallnotpass.inspection.Violation; 5 | import dev.youshallnotpass.inspection.Violations; 6 | import com.nikialeksey.jood.Db; 7 | import com.nikialeksey.jood.JdException; 8 | import com.nikialeksey.jood.QueryResult; 9 | import com.nikialeksey.jood.args.StringArg; 10 | import com.nikialeksey.jood.sql.JdSql; 11 | import java.sql.ResultSet; 12 | import java.sql.SQLException; 13 | import java.util.UUID; 14 | 15 | import org.takes.misc.Sprintf; 16 | 17 | public final class DbInheritances implements Violations { 18 | 19 | private final Db db; 20 | private final String repo; 21 | 22 | public DbInheritances(final Db db, final String repo) { 23 | this.db = db; 24 | this.repo = repo; 25 | } 26 | 27 | @Override 28 | public void clear() throws YsnpException { 29 | try { 30 | db.write( 31 | new JdSql( 32 | "DELETE FROM inheritancefree_violation WHERE repo = ?", 33 | new StringArg(repo) 34 | ) 35 | ); 36 | db.write( 37 | new JdSql( 38 | "UPDATE inheritancefree SET badgeUrl = '' WHERE repo = ?", 39 | new StringArg(repo) 40 | ) 41 | ); 42 | } catch (final JdException e) { 43 | throw new YsnpException( 44 | new Sprintf( 45 | "Can not clear the inheritances for repo '%s'", 46 | repo 47 | ).toString(), 48 | e 49 | ); 50 | } 51 | } 52 | 53 | @Override 54 | public void add(final Violation violation) throws YsnpException { 55 | try { 56 | final String id = UUID.randomUUID().toString(); 57 | db.write( 58 | new JdSql( 59 | "INSERT OR REPLACE INTO inheritancefree_violation VALUES(?, ?, ?)", 60 | new StringArg(id), 61 | new StringArg(repo), 62 | new StringArg(violation.description()) 63 | ) 64 | ); 65 | } catch (final JdException e) { 66 | throw new YsnpException( 67 | new Sprintf( 68 | "Can not add the inheritances '%s' in repo '%s'", 69 | repo, 70 | violation.description() 71 | ).toString(), 72 | e 73 | ); 74 | } 75 | } 76 | 77 | @Override 78 | public int count() throws YsnpException { 79 | try ( 80 | final QueryResult result = db.read( 81 | new JdSql( 82 | "SELECT count(*) FROM inheritancefree_violation WHERE repo = ?", 83 | new StringArg(repo) 84 | ) 85 | ); 86 | ) { 87 | final ResultSet rs = result.rs(); 88 | if (!rs.next()) { 89 | throw new YsnpException("'SELECT count(*)' returned nothing."); 90 | } 91 | return rs.getInt(1); 92 | } catch (final SQLException | JdException e) { 93 | throw new YsnpException("Can not get the inheritance count.", e); 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/inspection/inheritancefree/TkInheritanceFree.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass.inspection.inheritancefree; 2 | 3 | import dev.youshallnotpass.cactoos.YsnpFunc; 4 | import dev.youshallnotpass.inspection.TkViolation; 5 | import dev.youshallnotpass.repo.Repos; 6 | import java.io.IOException; 7 | import java.util.regex.Matcher; 8 | 9 | import org.takes.Response; 10 | import org.takes.facets.fork.RqRegex; 11 | import org.takes.facets.fork.TkRegex; 12 | 13 | public final class TkInheritanceFree implements TkRegex { 14 | 15 | private final TkViolation origin; 16 | 17 | public TkInheritanceFree(final Repos repos) { 18 | this( 19 | new TkViolation( 20 | new YsnpFunc<>((final RqRegex rq) -> { 21 | final Matcher matcher = rq.matcher(); 22 | final String user = matcher.group("user"); 23 | final String repo = matcher.group("repo"); 24 | final String path = user + "/" + repo; 25 | return repos.repo(path).inheritancefree(); 26 | }) 27 | ) 28 | ); 29 | } 30 | 31 | public TkInheritanceFree(final TkViolation origin) { 32 | this.origin = origin; 33 | } 34 | 35 | @Override 36 | public Response act(final RqRegex req) throws IOException { 37 | return origin.act(req); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/inspection/nomultiplereturn/DbMultipleReturns.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass.inspection.nomultiplereturn; 2 | 3 | import dev.youshallnotpass.YsnpException; 4 | import dev.youshallnotpass.inspection.Violation; 5 | import dev.youshallnotpass.inspection.Violations; 6 | import com.nikialeksey.jood.Db; 7 | import com.nikialeksey.jood.JdException; 8 | import com.nikialeksey.jood.QueryResult; 9 | import com.nikialeksey.jood.args.StringArg; 10 | import com.nikialeksey.jood.sql.JdSql; 11 | import org.takes.misc.Sprintf; 12 | 13 | import java.sql.ResultSet; 14 | import java.sql.SQLException; 15 | import java.util.UUID; 16 | 17 | public final class DbMultipleReturns implements Violations { 18 | 19 | private final Db db; 20 | private final String repo; 21 | 22 | public DbMultipleReturns(final Db db, final String repo) { 23 | this.db = db; 24 | this.repo = repo; 25 | } 26 | 27 | @Override 28 | public void clear() throws YsnpException { 29 | try { 30 | db.write( 31 | new JdSql( 32 | "DELETE FROM nomultiplereturn_violation WHERE repo = ?", 33 | new StringArg(repo) 34 | ) 35 | ); 36 | db.write( 37 | new JdSql( 38 | "UPDATE nomultiplereturn SET badgeUrl = '' WHERE repo = ?", 39 | new StringArg(repo) 40 | ) 41 | ); 42 | } catch (final JdException e) { 43 | throw new YsnpException( 44 | new Sprintf( 45 | "Can not clear the multiplereturns for repo '%s'", 46 | repo 47 | ).toString(), 48 | e 49 | ); 50 | } 51 | } 52 | 53 | @Override 54 | public void add(final Violation violation) throws YsnpException { 55 | try { 56 | final String id = UUID.randomUUID().toString(); 57 | db.write( 58 | new JdSql( 59 | "INSERT OR REPLACE INTO nomultiplereturn_violation VALUES(?, ?, ?)", 60 | new StringArg(id), 61 | new StringArg(repo), 62 | new StringArg(violation.description()) 63 | ) 64 | ); 65 | } catch (final JdException e) { 66 | throw new YsnpException( 67 | new Sprintf( 68 | "Can not add the multiplereturn '%s' in repo '%s'", 69 | repo, 70 | violation.description() 71 | ).toString(), 72 | e 73 | ); 74 | } 75 | } 76 | 77 | @Override 78 | public int count() throws YsnpException { 79 | try ( 80 | final QueryResult result = db.read( 81 | new JdSql( 82 | "SELECT count(*) FROM nomultiplereturn_violation WHERE repo = ?", 83 | new StringArg(repo) 84 | ) 85 | ); 86 | ) { 87 | final ResultSet rs = result.rs(); 88 | if (!rs.next()) { 89 | throw new YsnpException("'SELECT count(*)' returned nothing."); 90 | } 91 | return rs.getInt(1); 92 | } catch (final SQLException | JdException e) { 93 | throw new YsnpException("Can not get the multiplereturn count.", e); 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/inspection/nomultiplereturn/DbNoMultipleReturn.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass.inspection.nomultiplereturn; 2 | 3 | import dev.youshallnotpass.YsnpException; 4 | import dev.youshallnotpass.inspection.Inspection; 5 | import dev.youshallnotpass.inspection.YsnpBadge; 6 | import dev.youshallnotpass.inspection.Violations; 7 | import com.nikialeksey.jood.Db; 8 | import com.nikialeksey.jood.JdException; 9 | import com.nikialeksey.jood.QueryResult; 10 | import com.nikialeksey.jood.args.IntArg; 11 | import com.nikialeksey.jood.args.StringArg; 12 | import com.nikialeksey.jood.sql.JdSql; 13 | import org.takes.misc.Sprintf; 14 | 15 | import java.sql.ResultSet; 16 | import java.sql.SQLException; 17 | 18 | public final class DbNoMultipleReturn implements Inspection { 19 | 20 | private final Db db; 21 | private final String id; 22 | 23 | public DbNoMultipleReturn(final Db db, final String id) { 24 | this.db = db; 25 | this.id = id; 26 | } 27 | 28 | @Override 29 | public String badgeUrl() throws YsnpException { 30 | try ( 31 | final QueryResult result = db.read( 32 | new JdSql( 33 | "SELECT badgeUrl FROM nomultiplereturn WHERE id = ?", 34 | new StringArg(id) 35 | ) 36 | ) 37 | ) { 38 | final ResultSet rs = result.rs(); 39 | if (!rs.next()) { 40 | throw new YsnpException( 41 | "Nomultiplereturn does not exists for id " + id 42 | ); 43 | } 44 | return rs.getString("badgeUrl"); 45 | } catch (final SQLException | JdException e) { 46 | throw new YsnpException("Can not get the badge.", e); 47 | } 48 | } 49 | 50 | @Override 51 | public void calcBadge() throws YsnpException { 52 | try ( 53 | final QueryResult result = db.read( 54 | new JdSql( 55 | "SELECT threshold FROM nomultiplereturn WHERE id = ?", 56 | new StringArg(id) 57 | ) 58 | ) 59 | ) { 60 | final ResultSet rs = result.rs(); 61 | if (!rs.next()) { 62 | throw new YsnpException( 63 | new Sprintf( 64 | "Can not find the nomultiplereturn with id '%s'.", 65 | id 66 | ).toString() 67 | ); 68 | } 69 | final int threshold = rs.getInt("threshold"); 70 | db.write( 71 | new JdSql( 72 | "UPDATE nomultiplereturn SET badgeUrl = ? WHERE id = ?", 73 | new StringArg( 74 | new YsnpBadge( 75 | "nomultiplereturn", 76 | () -> violations().count() <= threshold 77 | ).asString() 78 | ), 79 | new StringArg(id) 80 | ) 81 | ); 82 | } catch (final SQLException | JdException e) { 83 | throw new YsnpException( 84 | new Sprintf( 85 | "Can not calc the badge by nomultiplereturn '%s'", 86 | id 87 | ).toString(), 88 | e 89 | ); 90 | } 91 | } 92 | 93 | @Override 94 | public void updateThreshold(final int threshold) throws YsnpException { 95 | try { 96 | db.write( 97 | new JdSql( 98 | "UPDATE nomultiplereturn SET threshold = ? WHERE id = ?", 99 | new IntArg(threshold), 100 | new StringArg(id) 101 | ) 102 | ); 103 | } catch (final JdException e) { 104 | throw new YsnpException( 105 | new Sprintf( 106 | "Can not update the threshold in nomultiplereturn with id '%s'", 107 | id 108 | ).toString(), 109 | e 110 | ); 111 | } 112 | } 113 | 114 | @Override 115 | public Violations violations() throws YsnpException { 116 | try ( 117 | final QueryResult qr = db.read( 118 | new JdSql( 119 | "SELECT repo FROM nomultiplereturn WHERE id = ?", 120 | new StringArg(id) 121 | ) 122 | ) 123 | ) { 124 | final ResultSet rs = qr.rs(); 125 | if (!rs.next()) { 126 | throw new YsnpException( 127 | "Could not find the nomultiplereturn by id " + id 128 | ); 129 | } 130 | return new DbMultipleReturns(db, rs.getString("repo")); 131 | } catch (final JdException | SQLException e) { 132 | throw new YsnpException( 133 | "Could not get the nomultiplereturn info by id " + id, 134 | e 135 | ); 136 | } 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/inspection/nomultiplereturn/TkNoMultipleReturn.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass.inspection.nomultiplereturn; 2 | 3 | import dev.youshallnotpass.cactoos.YsnpFunc; 4 | import dev.youshallnotpass.inspection.TkViolation; 5 | import dev.youshallnotpass.repo.Repos; 6 | import org.takes.Response; 7 | import org.takes.facets.fork.RqRegex; 8 | import org.takes.facets.fork.TkRegex; 9 | 10 | import java.io.IOException; 11 | import java.util.regex.Matcher; 12 | 13 | public final class TkNoMultipleReturn implements TkRegex { 14 | 15 | private final TkViolation origin; 16 | 17 | public TkNoMultipleReturn(final Repos repos) { 18 | this( 19 | new TkViolation( 20 | new YsnpFunc<>((final RqRegex rq) -> { 21 | final Matcher matcher = rq.matcher(); 22 | final String user = matcher.group("user"); 23 | final String repo = matcher.group("repo"); 24 | final String path = user + "/" + repo; 25 | return repos.repo(path).nomultiplereturn(); 26 | }) 27 | ) 28 | ); 29 | } 30 | 31 | public TkNoMultipleReturn(final TkViolation origin) { 32 | this.origin = origin; 33 | } 34 | 35 | @Override 36 | public Response act(final RqRegex req) throws IOException { 37 | return origin.act(req); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/inspection/nullfree/DbNullfree.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass.inspection.nullfree; 2 | 3 | import dev.youshallnotpass.YsnpException; 4 | import dev.youshallnotpass.inspection.Inspection; 5 | import dev.youshallnotpass.inspection.YsnpBadge; 6 | import dev.youshallnotpass.inspection.Violations; 7 | import com.nikialeksey.jood.Db; 8 | import com.nikialeksey.jood.JdException; 9 | import com.nikialeksey.jood.QueryResult; 10 | import com.nikialeksey.jood.args.IntArg; 11 | import com.nikialeksey.jood.args.StringArg; 12 | import com.nikialeksey.jood.sql.JdSql; 13 | import org.takes.misc.Sprintf; 14 | 15 | import java.sql.ResultSet; 16 | import java.sql.SQLException; 17 | 18 | public final class DbNullfree implements Inspection { 19 | 20 | private final Db db; 21 | private final String id; 22 | 23 | public DbNullfree(final Db db, final String id) { 24 | this.db = db; 25 | this.id = id; 26 | } 27 | 28 | @Override 29 | public String badgeUrl() throws YsnpException { 30 | try ( 31 | final QueryResult result = db.read( 32 | new JdSql( 33 | "SELECT badgeUrl FROM nullfree WHERE id = ?", 34 | new StringArg(id) 35 | ) 36 | ) 37 | ) { 38 | final ResultSet rs = result.rs(); 39 | if (!rs.next()) { 40 | throw new YsnpException("Nullfree does not contain the repo."); 41 | } 42 | return rs.getString("badgeUrl"); 43 | } catch (final SQLException | JdException e) { 44 | throw new YsnpException("Can not get the badge.", e); 45 | } 46 | } 47 | 48 | @Override 49 | public void calcBadge() throws YsnpException { 50 | try ( 51 | final QueryResult result = db.read( 52 | new JdSql( 53 | "SELECT threshold FROM nullfree WHERE id = ?", 54 | new StringArg(id) 55 | ) 56 | ) 57 | ) { 58 | final ResultSet rs = result.rs(); 59 | if (!rs.next()) { 60 | throw new YsnpException( 61 | new Sprintf( 62 | "Can not find the nullfree with id '%s'.", 63 | id 64 | ).toString() 65 | ); 66 | } 67 | final int threshold = rs.getInt("threshold"); 68 | db.write( 69 | new JdSql( 70 | "UPDATE nullfree SET badgeUrl = ? WHERE id = ?", 71 | new StringArg( 72 | new YsnpBadge( 73 | "nullfree", 74 | () -> violations().count() <= threshold 75 | ).asString() 76 | ), 77 | new StringArg(id) 78 | ) 79 | ); 80 | } catch (final SQLException | JdException e) { 81 | throw new YsnpException( 82 | new Sprintf( 83 | "Can not calc the badge by nullfree '%s'", 84 | id 85 | ).toString(), 86 | e 87 | ); 88 | } 89 | } 90 | 91 | @Override 92 | public void updateThreshold(final int threshold) throws YsnpException { 93 | try { 94 | db.write( 95 | new JdSql( 96 | "UPDATE nullfree SET threshold = ? WHERE id = ?", 97 | new IntArg(threshold), 98 | new StringArg(id) 99 | ) 100 | ); 101 | } catch (final JdException e) { 102 | throw new YsnpException( 103 | new Sprintf( 104 | "Can not update the threshold in nullfree with id '%s'", 105 | id 106 | ).toString(), 107 | e 108 | ); 109 | } 110 | } 111 | 112 | @Override 113 | public Violations violations() throws YsnpException { 114 | try ( 115 | final QueryResult qr = db.read( 116 | new JdSql( 117 | "SELECT repo FROM nullfree WHERE id = ?", 118 | new StringArg(id) 119 | ) 120 | ) 121 | ) { 122 | final ResultSet rs = qr.rs(); 123 | if (!rs.next()) { 124 | throw new YsnpException( 125 | "Could not find the nullfree by id " + id 126 | ); 127 | } 128 | return new DbNulls(db, rs.getString("repo")); 129 | } catch (final JdException | SQLException e) { 130 | throw new YsnpException( 131 | "Could not get the nullfree info by id " + id, 132 | e 133 | ); 134 | } 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/inspection/nullfree/DbNulls.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass.inspection.nullfree; 2 | 3 | import dev.youshallnotpass.YsnpException; 4 | import dev.youshallnotpass.inspection.Violation; 5 | import dev.youshallnotpass.inspection.Violations; 6 | import com.nikialeksey.jood.Db; 7 | import com.nikialeksey.jood.JdException; 8 | import com.nikialeksey.jood.QueryResult; 9 | import com.nikialeksey.jood.args.StringArg; 10 | import com.nikialeksey.jood.sql.JdSql; 11 | import org.takes.misc.Sprintf; 12 | 13 | import java.sql.ResultSet; 14 | import java.sql.SQLException; 15 | import java.util.UUID; 16 | 17 | public final class DbNulls implements Violations { 18 | 19 | private final Db db; 20 | private final String repo; 21 | 22 | public DbNulls(final Db db, final String repo) { 23 | this.db = db; 24 | this.repo = repo; 25 | } 26 | 27 | @Override 28 | public void clear() throws YsnpException { 29 | try { 30 | db.write( 31 | new JdSql( 32 | "DELETE FROM null_description WHERE repo = ?", 33 | new StringArg(repo) 34 | ) 35 | ); 36 | db.write( 37 | new JdSql( 38 | "UPDATE nullfree SET badgeUrl = '' WHERE repo = ?", 39 | new StringArg(repo) 40 | ) 41 | ); 42 | } catch (final JdException e) { 43 | throw new YsnpException( 44 | new Sprintf( 45 | "Can not clear the nulls for repo '%s'", 46 | repo 47 | ).toString(), 48 | e 49 | ); 50 | } 51 | } 52 | 53 | @Override 54 | public void add(final Violation violation) throws YsnpException { 55 | try { 56 | final String id = UUID.randomUUID().toString(); 57 | db.write( 58 | new JdSql( 59 | "INSERT OR REPLACE INTO null_description VALUES(?, ?, ?)", 60 | new StringArg(id), 61 | new StringArg(repo), 62 | new StringArg(violation.description()) 63 | ) 64 | ); 65 | } catch (final JdException e) { 66 | throw new YsnpException( 67 | new Sprintf( 68 | "Can not add the null '%s' in repo '%s'", 69 | repo, 70 | violation.description() 71 | ).toString(), 72 | e 73 | ); 74 | } 75 | } 76 | 77 | @Override 78 | public int count() throws YsnpException { 79 | try ( 80 | final QueryResult result = db.read( 81 | new JdSql( 82 | "SELECT count(*) FROM null_description WHERE repo = ?", 83 | new StringArg(repo) 84 | ) 85 | ); 86 | ) { 87 | final ResultSet rs = result.rs(); 88 | if (!rs.next()) { 89 | throw new YsnpException("'SELECT count(*)' returned nothing."); 90 | } 91 | return rs.getInt(1); 92 | } catch (final SQLException | JdException e) { 93 | throw new YsnpException("Can not get the nulls count.", e); 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/inspection/nullfree/TkNullfree.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass.inspection.nullfree; 2 | 3 | import dev.youshallnotpass.cactoos.YsnpFunc; 4 | import dev.youshallnotpass.inspection.TkViolation; 5 | import dev.youshallnotpass.repo.Repos; 6 | import org.takes.Response; 7 | import org.takes.facets.fork.RqRegex; 8 | import org.takes.facets.fork.TkRegex; 9 | 10 | import java.io.IOException; 11 | import java.util.regex.Matcher; 12 | 13 | public final class TkNullfree implements TkRegex { 14 | 15 | private final TkViolation origin; 16 | 17 | public TkNullfree(final Repos repos) { 18 | this( 19 | new TkViolation( 20 | new YsnpFunc<>((final RqRegex rq) -> { 21 | final Matcher matcher = rq.matcher(); 22 | final String user = matcher.group("user"); 23 | final String repo = matcher.group("repo"); 24 | final String path = user + "/" + repo; 25 | return repos.repo(path).nullfree(); 26 | }) 27 | ) 28 | ); 29 | } 30 | 31 | public TkNullfree(final TkViolation origin) { 32 | this.origin = origin; 33 | } 34 | 35 | @Override 36 | public Response act(final RqRegex req) throws IOException { 37 | return this.origin.act(req); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/inspection/setterfree/DbSetterFree.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass.inspection.setterfree; 2 | 3 | import dev.youshallnotpass.YsnpException; 4 | import dev.youshallnotpass.inspection.Inspection; 5 | import dev.youshallnotpass.inspection.YsnpBadge; 6 | import dev.youshallnotpass.inspection.Violations; 7 | import com.nikialeksey.jood.Db; 8 | import com.nikialeksey.jood.JdException; 9 | import com.nikialeksey.jood.QueryResult; 10 | import com.nikialeksey.jood.args.IntArg; 11 | import com.nikialeksey.jood.args.StringArg; 12 | import com.nikialeksey.jood.sql.JdSql; 13 | import org.takes.misc.Sprintf; 14 | 15 | import java.sql.ResultSet; 16 | import java.sql.SQLException; 17 | 18 | public final class DbSetterFree implements Inspection { 19 | 20 | private final Db db; 21 | private final String id; 22 | 23 | public DbSetterFree(final Db db, final String id) { 24 | this.db = db; 25 | this.id = id; 26 | } 27 | 28 | @Override 29 | public String badgeUrl() throws YsnpException { 30 | try ( 31 | final QueryResult result = db.read( 32 | new JdSql( 33 | "SELECT badgeUrl FROM setterfree WHERE id = ?", 34 | new StringArg(id) 35 | ) 36 | ) 37 | ) { 38 | final ResultSet rs = result.rs(); 39 | if (!rs.next()) { 40 | throw new YsnpException( 41 | "Setterfree does not exists for id " + id 42 | ); 43 | } 44 | return rs.getString("badgeUrl"); 45 | } catch (final SQLException | JdException e) { 46 | throw new YsnpException("Can not get the badge.", e); 47 | } 48 | } 49 | 50 | @Override 51 | public void calcBadge() throws YsnpException { 52 | try ( 53 | final QueryResult result = db.read( 54 | new JdSql( 55 | "SELECT threshold FROM setterfree WHERE id = ?", 56 | new StringArg(id) 57 | ) 58 | ) 59 | ) { 60 | final ResultSet rs = result.rs(); 61 | if (!rs.next()) { 62 | throw new YsnpException( 63 | new Sprintf( 64 | "Can not find the setterfree with id '%s'.", 65 | id 66 | ).toString() 67 | ); 68 | } 69 | final int threshold = rs.getInt("threshold"); 70 | db.write( 71 | new JdSql( 72 | "UPDATE setterfree SET badgeUrl = ? WHERE id = ?", 73 | new StringArg( 74 | new YsnpBadge( 75 | "setterfree", 76 | () -> violations().count() <= threshold 77 | ).asString() 78 | ), 79 | new StringArg(id) 80 | ) 81 | ); 82 | } catch (final SQLException | JdException e) { 83 | throw new YsnpException( 84 | new Sprintf( 85 | "Can not calc the badge by setterfree '%s'", 86 | id 87 | ).toString(), 88 | e 89 | ); 90 | } 91 | } 92 | 93 | @Override 94 | public void updateThreshold(final int threshold) throws YsnpException { 95 | try { 96 | db.write( 97 | new JdSql( 98 | "UPDATE setterfree SET threshold = ? WHERE id = ?", 99 | new IntArg(threshold), 100 | new StringArg(id) 101 | ) 102 | ); 103 | } catch (final JdException e) { 104 | throw new YsnpException( 105 | new Sprintf( 106 | "Can not update the threshold in setterfree with id '%s'", 107 | id 108 | ).toString(), 109 | e 110 | ); 111 | } 112 | } 113 | 114 | @Override 115 | public Violations violations() throws YsnpException { 116 | try ( 117 | final QueryResult qr = db.read( 118 | new JdSql( 119 | "SELECT repo FROM setterfree WHERE id = ?", 120 | new StringArg(id) 121 | ) 122 | ) 123 | ) { 124 | final ResultSet rs = qr.rs(); 125 | if (!rs.next()) { 126 | throw new YsnpException( 127 | "Could not find the setterfree by id " + id 128 | ); 129 | } 130 | return new DbSetters(db, rs.getString("repo")); 131 | } catch (final JdException | SQLException e) { 132 | throw new YsnpException( 133 | "Could not get the setterfree info by id " + id, 134 | e 135 | ); 136 | } 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/inspection/setterfree/DbSetters.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass.inspection.setterfree; 2 | 3 | import dev.youshallnotpass.YsnpException; 4 | import dev.youshallnotpass.inspection.Violation; 5 | import dev.youshallnotpass.inspection.Violations; 6 | import com.nikialeksey.jood.Db; 7 | import com.nikialeksey.jood.JdException; 8 | import com.nikialeksey.jood.QueryResult; 9 | import com.nikialeksey.jood.args.StringArg; 10 | import com.nikialeksey.jood.sql.JdSql; 11 | import org.takes.misc.Sprintf; 12 | 13 | import java.sql.ResultSet; 14 | import java.sql.SQLException; 15 | import java.util.UUID; 16 | 17 | public final class DbSetters implements Violations { 18 | 19 | private final Db db; 20 | private final String repo; 21 | 22 | public DbSetters(final Db db, final String repo) { 23 | this.db = db; 24 | this.repo = repo; 25 | } 26 | 27 | @Override 28 | public void clear() throws YsnpException { 29 | try { 30 | db.write( 31 | new JdSql( 32 | "DELETE FROM setterfree_violation WHERE repo = ?", 33 | new StringArg(repo) 34 | ) 35 | ); 36 | db.write( 37 | new JdSql( 38 | "UPDATE setterfree SET badgeUrl = '' WHERE repo = ?", 39 | new StringArg(repo) 40 | ) 41 | ); 42 | } catch (final JdException e) { 43 | throw new YsnpException( 44 | new Sprintf( 45 | "Can not clear the setters for repo '%s'", 46 | repo 47 | ).toString(), 48 | e 49 | ); 50 | } 51 | } 52 | 53 | @Override 54 | public void add(final Violation violation) throws YsnpException { 55 | try { 56 | final String id = UUID.randomUUID().toString(); 57 | db.write( 58 | new JdSql( 59 | "INSERT OR REPLACE INTO setterfree_violation VALUES(?, ?, ?)", 60 | new StringArg(id), 61 | new StringArg(repo), 62 | new StringArg(violation.description()) 63 | ) 64 | ); 65 | } catch (final JdException e) { 66 | throw new YsnpException( 67 | new Sprintf( 68 | "Can not add the setter '%s' in repo '%s'", 69 | repo, 70 | violation.description() 71 | ).toString(), 72 | e 73 | ); 74 | } 75 | } 76 | 77 | @Override 78 | public int count() throws YsnpException { 79 | try ( 80 | final QueryResult result = db.read( 81 | new JdSql( 82 | "SELECT count(*) FROM setterfree_violation WHERE repo = ?", 83 | new StringArg(repo) 84 | ) 85 | ); 86 | ) { 87 | final ResultSet rs = result.rs(); 88 | if (!rs.next()) { 89 | throw new YsnpException("'SELECT count(*)' returned nothing."); 90 | } 91 | return rs.getInt(1); 92 | } catch (final SQLException | JdException e) { 93 | throw new YsnpException("Can not get the setters count.", e); 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/inspection/setterfree/TkSetterFree.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass.inspection.setterfree; 2 | 3 | import dev.youshallnotpass.cactoos.YsnpFunc; 4 | import dev.youshallnotpass.inspection.TkViolation; 5 | import dev.youshallnotpass.repo.Repos; 6 | import org.takes.Response; 7 | import org.takes.facets.fork.RqRegex; 8 | import org.takes.facets.fork.TkRegex; 9 | 10 | import java.io.IOException; 11 | import java.util.regex.Matcher; 12 | 13 | public final class TkSetterFree implements TkRegex { 14 | 15 | private final TkViolation origin; 16 | 17 | public TkSetterFree(final Repos repos) { 18 | this( 19 | new TkViolation( 20 | new YsnpFunc<>((final RqRegex rq) -> { 21 | final Matcher matcher = rq.matcher(); 22 | final String user = matcher.group("user"); 23 | final String repo = matcher.group("repo"); 24 | final String path = user + "/" + repo; 25 | return repos.repo(path).setterfree(); 26 | }) 27 | ) 28 | ); 29 | } 30 | 31 | public TkSetterFree(final TkViolation origin) { 32 | this.origin = origin; 33 | } 34 | 35 | @Override 36 | public Response act(final RqRegex req) throws IOException { 37 | return origin.act(req); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/inspection/staticfree/DbStaticfree.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass.inspection.staticfree; 2 | 3 | import dev.youshallnotpass.YsnpException; 4 | import dev.youshallnotpass.inspection.Inspection; 5 | import dev.youshallnotpass.inspection.YsnpBadge; 6 | import dev.youshallnotpass.inspection.Violations; 7 | import com.nikialeksey.jood.Db; 8 | import com.nikialeksey.jood.JdException; 9 | import com.nikialeksey.jood.QueryResult; 10 | import com.nikialeksey.jood.args.IntArg; 11 | import com.nikialeksey.jood.args.StringArg; 12 | import com.nikialeksey.jood.sql.JdSql; 13 | import org.takes.misc.Sprintf; 14 | 15 | import java.sql.ResultSet; 16 | import java.sql.SQLException; 17 | 18 | public final class DbStaticfree implements Inspection { 19 | 20 | private final Db db; 21 | private final String id; 22 | 23 | public DbStaticfree(final Db db, final String id) { 24 | this.db = db; 25 | this.id = id; 26 | } 27 | 28 | @Override 29 | public String badgeUrl() throws YsnpException { 30 | try ( 31 | final QueryResult result = db.read( 32 | new JdSql( 33 | "SELECT badgeUrl FROM staticfree WHERE id = ?", 34 | new StringArg(id) 35 | ) 36 | ) 37 | ) { 38 | final ResultSet rs = result.rs(); 39 | if (!rs.next()) { 40 | throw new YsnpException( 41 | "Staticfree does not exists for id " + id 42 | ); 43 | } 44 | return rs.getString("badgeUrl"); 45 | } catch (final SQLException | JdException e) { 46 | throw new YsnpException("Can not get the badge.", e); 47 | } 48 | } 49 | 50 | @Override 51 | public void calcBadge() throws YsnpException { 52 | try ( 53 | final QueryResult result = db.read( 54 | new JdSql( 55 | "SELECT threshold FROM staticfree WHERE id = ?", 56 | new StringArg(id) 57 | ) 58 | ) 59 | ) { 60 | final ResultSet rs = result.rs(); 61 | if (!rs.next()) { 62 | throw new YsnpException( 63 | new Sprintf( 64 | "Can not find the staticfree with id '%s'.", 65 | id 66 | ).toString() 67 | ); 68 | } 69 | final int threshold = rs.getInt("threshold"); 70 | db.write( 71 | new JdSql( 72 | "UPDATE staticfree SET badgeUrl = ? WHERE id = ?", 73 | new StringArg( 74 | new YsnpBadge( 75 | "staticfree", 76 | () -> violations().count() <= threshold 77 | ).asString() 78 | ), 79 | new StringArg(id) 80 | ) 81 | ); 82 | } catch (final SQLException | JdException e) { 83 | throw new YsnpException( 84 | new Sprintf( 85 | "Can not calc the badge by staticfree '%s'", 86 | id 87 | ).toString(), 88 | e 89 | ); 90 | } 91 | } 92 | 93 | @Override 94 | public void updateThreshold(final int threshold) throws YsnpException { 95 | try { 96 | db.write( 97 | new JdSql( 98 | "UPDATE staticfree SET threshold = ? WHERE id = ?", 99 | new IntArg(threshold), 100 | new StringArg(id) 101 | ) 102 | ); 103 | } catch (final JdException e) { 104 | throw new YsnpException( 105 | new Sprintf( 106 | "Can not update the threshold in staticfree with id '%s'", 107 | id 108 | ).toString(), 109 | e 110 | ); 111 | } 112 | } 113 | 114 | @Override 115 | public Violations violations() throws YsnpException { 116 | try ( 117 | final QueryResult qr = db.read( 118 | new JdSql( 119 | "SELECT repo FROM staticfree WHERE id = ?", 120 | new StringArg(id) 121 | ) 122 | ) 123 | ) { 124 | final ResultSet rs = qr.rs(); 125 | if (!rs.next()) { 126 | throw new YsnpException( 127 | "Could not find the staticfree by id " + id 128 | ); 129 | } 130 | return new DbStatics(db, rs.getString("repo")); 131 | } catch (final JdException | SQLException e) { 132 | throw new YsnpException( 133 | "Could not get the staticfree info by id " + id, 134 | e 135 | ); 136 | } 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/inspection/staticfree/DbStatics.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass.inspection.staticfree; 2 | 3 | import dev.youshallnotpass.YsnpException; 4 | import dev.youshallnotpass.inspection.Violation; 5 | import dev.youshallnotpass.inspection.Violations; 6 | import com.nikialeksey.jood.Db; 7 | import com.nikialeksey.jood.JdException; 8 | import com.nikialeksey.jood.QueryResult; 9 | import com.nikialeksey.jood.args.StringArg; 10 | import com.nikialeksey.jood.sql.JdSql; 11 | import org.takes.misc.Sprintf; 12 | 13 | import java.sql.ResultSet; 14 | import java.sql.SQLException; 15 | import java.util.UUID; 16 | 17 | public final class DbStatics implements Violations { 18 | 19 | private final Db db; 20 | private final String repo; 21 | 22 | public DbStatics(final Db db, final String repo) { 23 | this.db = db; 24 | this.repo = repo; 25 | } 26 | 27 | @Override 28 | public void clear() throws YsnpException { 29 | try { 30 | db.write( 31 | new JdSql( 32 | "DELETE FROM staticfree_violation WHERE repo = ?", 33 | new StringArg(repo) 34 | ) 35 | ); 36 | db.write( 37 | new JdSql( 38 | "UPDATE staticfree SET badgeUrl = '' WHERE repo = ?", 39 | new StringArg(repo) 40 | ) 41 | ); 42 | } catch (final JdException e) { 43 | throw new YsnpException( 44 | new Sprintf( 45 | "Can not clear the statics for repo '%s'", 46 | repo 47 | ).toString(), 48 | e 49 | ); 50 | } 51 | } 52 | 53 | @Override 54 | public void add(final Violation violation) throws YsnpException { 55 | try { 56 | final String id = UUID.randomUUID().toString(); 57 | db.write( 58 | new JdSql( 59 | "INSERT OR REPLACE INTO staticfree_violation VALUES(?, ?, ?)", 60 | new StringArg(id), 61 | new StringArg(repo), 62 | new StringArg(violation.description()) 63 | ) 64 | ); 65 | } catch (final JdException e) { 66 | throw new YsnpException( 67 | new Sprintf( 68 | "Can not add the static '%s' in repo '%s'", 69 | repo, 70 | violation.description() 71 | ).toString(), 72 | e 73 | ); 74 | } 75 | } 76 | 77 | @Override 78 | public int count() throws YsnpException { 79 | try ( 80 | final QueryResult result = db.read( 81 | new JdSql( 82 | "SELECT count(*) FROM staticfree_violation WHERE repo = ?", 83 | new StringArg(repo) 84 | ) 85 | ); 86 | ) { 87 | final ResultSet rs = result.rs(); 88 | if (!rs.next()) { 89 | throw new YsnpException("'SELECT count(*)' returned nothing."); 90 | } 91 | return rs.getInt(1); 92 | } catch (final SQLException | JdException e) { 93 | throw new YsnpException("Can not get the statics count.", e); 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/inspection/staticfree/TkStaticfree.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass.inspection.staticfree; 2 | 3 | import dev.youshallnotpass.cactoos.YsnpFunc; 4 | import dev.youshallnotpass.inspection.TkViolation; 5 | import dev.youshallnotpass.repo.Repos; 6 | import org.takes.Response; 7 | import org.takes.facets.fork.RqRegex; 8 | import org.takes.facets.fork.TkRegex; 9 | 10 | import java.io.IOException; 11 | import java.util.regex.Matcher; 12 | 13 | public final class TkStaticfree implements TkRegex { 14 | 15 | private final TkViolation origin; 16 | 17 | public TkStaticfree(final Repos repos) { 18 | this( 19 | new TkViolation( 20 | new YsnpFunc<>((final RqRegex rq) -> { 21 | final Matcher matcher = rq.matcher(); 22 | final String user = matcher.group("user"); 23 | final String repo = matcher.group("repo"); 24 | final String path = user + "/" + repo; 25 | return repos.repo(path).staticfree(); 26 | }) 27 | ) 28 | ); 29 | } 30 | 31 | public TkStaticfree(final TkViolation origin) { 32 | this.origin = origin; 33 | } 34 | 35 | @Override 36 | public Response act(final RqRegex req) throws IOException { 37 | return origin.act(req); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/migrations/Migration0.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass.migrations; 2 | 3 | import com.nikialeksey.jood.Db; 4 | import com.nikialeksey.jood.JdException; 5 | import com.nikialeksey.jood.Migration; 6 | import com.nikialeksey.jood.sql.JdSql; 7 | 8 | public final class Migration0 implements Migration { 9 | @Override 10 | public int number() { 11 | return 0; 12 | } 13 | 14 | @Override 15 | public void execute(final Db db) throws JdException { 16 | db.write( 17 | new JdSql( 18 | "CREATE TABLE repo (" + 19 | "path TEXT NOT NULL PRIMARY KEY, " + 20 | "badgeUrl TEXT NOT NULL" + 21 | ")" 22 | ) 23 | ); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/migrations/Migration1.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass.migrations; 2 | 3 | import com.nikialeksey.jood.Db; 4 | import com.nikialeksey.jood.JdException; 5 | import com.nikialeksey.jood.Migration; 6 | import com.nikialeksey.jood.sql.JdSql; 7 | 8 | public final class Migration1 implements Migration { 9 | @Override 10 | public int number() { 11 | return 1; 12 | } 13 | 14 | @Override 15 | public void execute(final Db db) throws JdException { 16 | db.write( 17 | new JdSql( 18 | "CREATE TABLE null_description (" + 19 | "id TEXT NOT NULL PRIMARY KEY," + 20 | "repo TEXT NOT NULL," + 21 | "description TEXT NOT NULL," + 22 | "FOREIGN KEY(repo) REFERENCES repo(path) ON UPDATE CASCADE ON DELETE CASCADE" + 23 | ")" 24 | ) 25 | ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/migrations/Migration2.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass.migrations; 2 | 3 | import com.nikialeksey.jood.Db; 4 | import com.nikialeksey.jood.JdException; 5 | import com.nikialeksey.jood.Migration; 6 | import com.nikialeksey.jood.sql.JdSql; 7 | 8 | public final class Migration2 implements Migration { 9 | @Override 10 | public int number() { 11 | return 2; 12 | } 13 | 14 | @Override 15 | public void execute(final Db db) throws JdException { 16 | db.write( 17 | new JdSql( 18 | "ALTER TABLE repo ADD COLUMN threshold INTEGER NOT NULL DEFAULT 0" 19 | ) 20 | ); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/migrations/Migration3.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass.migrations; 2 | 3 | import com.nikialeksey.jood.Db; 4 | import com.nikialeksey.jood.JdException; 5 | import com.nikialeksey.jood.Migration; 6 | import com.nikialeksey.jood.sql.JdSql; 7 | 8 | public final class Migration3 implements Migration { 9 | @Override 10 | public int number() { 11 | return 3; 12 | } 13 | 14 | @Override 15 | public void execute(final Db db) throws JdException { 16 | db.write( 17 | new JdSql( 18 | "CREATE TABLE nullfree (" + 19 | "id TEXT NOT NULL PRIMARY KEY, " + 20 | "repo TEXT NOT NULL, " + 21 | "threshold INTEGER NOT NULL DEFAULT 0, " + 22 | "badgeUrl TEXT NOT NULL DEFAULT '', " + 23 | "FOREIGN KEY(repo) REFERENCES repo(path) ON UPDATE CASCADE ON DELETE CASCADE" + 24 | ")" 25 | ) 26 | ); 27 | db.write( 28 | new JdSql( 29 | "INSERT INTO nullfree (id, repo, threshold, badgeUrl) " + 30 | "SELECT " + 31 | " (hex(randomblob(4)) || " + 32 | " '-' || " + 33 | " hex(randomblob(2)) || " + 34 | " '-' || " + 35 | " '4' || " + 36 | " substr(hex(randomblob(2)), 2) || " + 37 | " '-' || " + 38 | " substr('AB89', 1 + (abs(random()) % 4) , 1) || " + 39 | " substr(hex(randomblob(2)), 2) || " + 40 | " '-' || " + 41 | " hex(randomblob(6))" + 42 | " ) as id, " + 43 | " path, " + 44 | " threshold, " + 45 | " badgeUrl " + 46 | "FROM repo" 47 | ) 48 | ); 49 | 50 | // We can't just rename table with ALTER: https://github.com/xerial/sqlite-jdbc/issues/497 51 | db.write( 52 | new JdSql( 53 | "CREATE TABLE repo_new (" + 54 | "path TEXT NOT NULL PRIMARY KEY" + 55 | ")" 56 | ) 57 | ); 58 | db.write( 59 | new JdSql( 60 | "INSERT INTO repo_new(path) SELECT path FROM repo" 61 | ) 62 | ); 63 | db.write( 64 | new JdSql( 65 | "DROP TABLE repo" 66 | ) 67 | ); 68 | db.write( 69 | new JdSql( 70 | "CREATE TABLE repo (" + 71 | "path TEXT NOT NULL PRIMARY KEY" + 72 | ")" 73 | ) 74 | ); 75 | db.write( 76 | new JdSql( 77 | "INSERT INTO repo(path) SELECT path FROM repo_new" 78 | ) 79 | ); 80 | db.write( 81 | new JdSql( 82 | "DROP TABLE repo_new" 83 | ) 84 | ); 85 | 86 | db.write( 87 | new JdSql( 88 | "CREATE TABLE staticfree (" + 89 | "id TEXT NOT NULL PRIMARY KEY, " + 90 | "repo TEXT NOT NULL, " + 91 | "threshold INTEGER NOT NULL DEFAULT 0, " + 92 | "badgeUrl TEXT NOT NULL DEFAULT '', " + 93 | "FOREIGN KEY(repo) REFERENCES repo(path) ON UPDATE CASCADE ON DELETE CASCADE" + 94 | ")" 95 | ) 96 | ); 97 | db.write( 98 | new JdSql( 99 | "CREATE TABLE staticfree_violation (" + 100 | "id TEXT NOT NULL PRIMARY KEY," + 101 | "repo TEXT NOT NULL," + 102 | "description TEXT NOT NULL," + 103 | "FOREIGN KEY(repo) REFERENCES repo(path) ON UPDATE CASCADE ON DELETE CASCADE" + 104 | ")" 105 | ) 106 | ); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/migrations/Migration4.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass.migrations; 2 | 3 | import com.nikialeksey.jood.Db; 4 | import com.nikialeksey.jood.JdException; 5 | import com.nikialeksey.jood.Migration; 6 | import com.nikialeksey.jood.sql.JdSql; 7 | 8 | public final class Migration4 implements Migration { 9 | @Override 10 | public int number() { 11 | return 4; 12 | } 13 | 14 | @Override 15 | public void execute(final Db db) throws JdException { 16 | db.write( 17 | new JdSql( 18 | "CREATE TABLE allfinal (" + 19 | "id TEXT NOT NULL PRIMARY KEY, " + 20 | "repo TEXT NOT NULL, " + 21 | "threshold INTEGER NOT NULL DEFAULT 0, " + 22 | "badgeUrl TEXT NOT NULL DEFAULT '', " + 23 | "FOREIGN KEY(repo) REFERENCES repo(path) ON UPDATE CASCADE ON DELETE CASCADE" + 24 | ")" 25 | ) 26 | ); 27 | db.write( 28 | new JdSql( 29 | "CREATE TABLE allfinal_violation (" + 30 | "id TEXT NOT NULL PRIMARY KEY," + 31 | "repo TEXT NOT NULL," + 32 | "description TEXT NOT NULL," + 33 | "FOREIGN KEY(repo) REFERENCES repo(path) ON UPDATE CASCADE ON DELETE CASCADE" + 34 | ")" 35 | ) 36 | ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/migrations/Migration5.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass.migrations; 2 | 3 | import com.nikialeksey.jood.Db; 4 | import com.nikialeksey.jood.JdException; 5 | import com.nikialeksey.jood.Migration; 6 | import com.nikialeksey.jood.sql.JdSql; 7 | 8 | public final class Migration5 implements Migration { 9 | @Override 10 | public int number() { 11 | return 5; 12 | } 13 | 14 | @Override 15 | public void execute(final Db db) throws JdException { 16 | db.write( 17 | new JdSql( 18 | "CREATE TABLE allpublic (" + 19 | "id TEXT NOT NULL PRIMARY KEY, " + 20 | "repo TEXT NOT NULL, " + 21 | "threshold INTEGER NOT NULL DEFAULT 0, " + 22 | "badgeUrl TEXT NOT NULL DEFAULT '', " + 23 | "FOREIGN KEY(repo) REFERENCES repo(path) ON UPDATE CASCADE ON DELETE CASCADE" + 24 | ")" 25 | ) 26 | ); 27 | db.write( 28 | new JdSql( 29 | "CREATE TABLE allpublic_violation (" + 30 | "id TEXT NOT NULL PRIMARY KEY," + 31 | "repo TEXT NOT NULL," + 32 | "description TEXT NOT NULL," + 33 | "FOREIGN KEY(repo) REFERENCES repo(path) ON UPDATE CASCADE ON DELETE CASCADE" + 34 | ")" 35 | ) 36 | ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/migrations/Migration6.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass.migrations; 2 | 3 | import com.nikialeksey.jood.Db; 4 | import com.nikialeksey.jood.JdException; 5 | import com.nikialeksey.jood.Migration; 6 | import com.nikialeksey.jood.sql.JdSql; 7 | 8 | public final class Migration6 implements Migration { 9 | @Override 10 | public int number() { 11 | return 6; 12 | } 13 | 14 | @Override 15 | public void execute(final Db db) throws JdException { 16 | db.write( 17 | new JdSql( 18 | "CREATE TABLE setterfree (" + 19 | "id TEXT NOT NULL PRIMARY KEY, " + 20 | "repo TEXT NOT NULL, " + 21 | "threshold INTEGER NOT NULL DEFAULT 0, " + 22 | "badgeUrl TEXT NOT NULL DEFAULT '', " + 23 | "FOREIGN KEY(repo) REFERENCES repo(path) ON UPDATE CASCADE ON DELETE CASCADE" + 24 | ")" 25 | ) 26 | ); 27 | db.write( 28 | new JdSql( 29 | "CREATE TABLE setterfree_violation (" + 30 | "id TEXT NOT NULL PRIMARY KEY," + 31 | "repo TEXT NOT NULL," + 32 | "description TEXT NOT NULL," + 33 | "FOREIGN KEY(repo) REFERENCES repo(path) ON UPDATE CASCADE ON DELETE CASCADE" + 34 | ")" 35 | ) 36 | ); 37 | 38 | db.write( 39 | new JdSql( 40 | "CREATE TABLE nomultiplereturn (" + 41 | "id TEXT NOT NULL PRIMARY KEY, " + 42 | "repo TEXT NOT NULL, " + 43 | "threshold INTEGER NOT NULL DEFAULT 0, " + 44 | "badgeUrl TEXT NOT NULL DEFAULT '', " + 45 | "FOREIGN KEY(repo) REFERENCES repo(path) ON UPDATE CASCADE ON DELETE CASCADE" + 46 | ")" 47 | ) 48 | ); 49 | db.write( 50 | new JdSql( 51 | "CREATE TABLE nomultiplereturn_violation (" + 52 | "id TEXT NOT NULL PRIMARY KEY," + 53 | "repo TEXT NOT NULL," + 54 | "description TEXT NOT NULL," + 55 | "FOREIGN KEY(repo) REFERENCES repo(path) ON UPDATE CASCADE ON DELETE CASCADE" + 56 | ")" 57 | ) 58 | ); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/migrations/Migration7.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass.migrations; 2 | 3 | import com.nikialeksey.jood.Db; 4 | import com.nikialeksey.jood.JdException; 5 | import com.nikialeksey.jood.Migration; 6 | import com.nikialeksey.jood.sql.JdSql; 7 | 8 | public final class Migration7 implements Migration { 9 | @Override 10 | public int number() { 11 | return 7; 12 | } 13 | 14 | @Override 15 | public void execute(final Db db) throws JdException { 16 | db.write( 17 | new JdSql( 18 | "CREATE TABLE inheritancefree (" + 19 | "id TEXT NOT NULL PRIMARY KEY, " + 20 | "repo TEXT NOT NULL, " + 21 | "threshold INTEGER NOT NULL DEFAULT 0, " + 22 | "badgeUrl TEXT NOT NULL DEFAULT '', " + 23 | "FOREIGN KEY(repo) REFERENCES repo(path) ON UPDATE CASCADE ON DELETE CASCADE" + 24 | ")" 25 | ) 26 | ); 27 | db.write( 28 | new JdSql( 29 | "CREATE TABLE inheritancefree_violation (" + 30 | "id TEXT NOT NULL PRIMARY KEY," + 31 | "repo TEXT NOT NULL," + 32 | "description TEXT NOT NULL," + 33 | "FOREIGN KEY(repo) REFERENCES repo(path) ON UPDATE CASCADE ON DELETE CASCADE" + 34 | ")" 35 | ) 36 | ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/readme/TkReadme.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass.readme; 2 | 3 | import org.apache.velocity.VelocityContext; 4 | import org.apache.velocity.app.VelocityEngine; 5 | import org.cactoos.Scalar; 6 | import org.cactoos.map.MapEntry; 7 | import org.cactoos.map.MapOf; 8 | import org.cactoos.scalar.Checked; 9 | import org.cactoos.text.TextOf; 10 | import org.commonmark.node.Node; 11 | import org.commonmark.parser.Parser; 12 | import org.commonmark.renderer.html.HtmlRenderer; 13 | import org.takes.Request; 14 | import org.takes.Response; 15 | import org.takes.Take; 16 | import org.takes.rs.RsHtml; 17 | 18 | import java.io.ByteArrayInputStream; 19 | import java.io.IOException; 20 | import java.io.InputStream; 21 | import java.io.InputStreamReader; 22 | import java.io.Reader; 23 | import java.io.StringWriter; 24 | import java.net.URL; 25 | 26 | public final class TkReadme implements Take { 27 | 28 | private final Parser mdParser; 29 | private final HtmlRenderer mdRenderer; 30 | private final Checked readme; 31 | private final String title; 32 | private final String link; 33 | 34 | public TkReadme(final Scalar readmeUrl, final String title, final String link) { 35 | this( 36 | new Checked(() -> readmeUrl.value().openStream(), IOException::new), 37 | title, 38 | link 39 | ); 40 | } 41 | 42 | public TkReadme(final URL readmeUrl, final String title, final String link) { 43 | this( 44 | new Checked(readmeUrl::openStream, IOException::new), 45 | title, 46 | link 47 | ); 48 | } 49 | 50 | public TkReadme(final String readme, final String title, final String link) { 51 | this( 52 | new Checked(() -> new ByteArrayInputStream(readme.getBytes()), IOException::new), 53 | title, 54 | link 55 | ); 56 | } 57 | 58 | public TkReadme(final Checked readme, final String title, final String link) { 59 | this( 60 | Parser.builder().build(), 61 | HtmlRenderer.builder().build(), 62 | readme, 63 | title, 64 | link 65 | ); 66 | } 67 | 68 | public TkReadme( 69 | final Parser mdParser, 70 | final HtmlRenderer mdRenderer, 71 | final Checked readme, 72 | final String title, 73 | final String link 74 | ) { 75 | this.mdParser = mdParser; 76 | this.mdRenderer = mdRenderer; 77 | this.readme = readme; 78 | this.title = title; 79 | this.link = link; 80 | } 81 | 82 | @Override 83 | public Response act(final Request req) throws IOException { 84 | try ( 85 | final InputStream urlStream = readme.value(); 86 | final Reader urlReader = new InputStreamReader(urlStream) 87 | ) { 88 | 89 | final Node document = mdParser.parseReader(urlReader); 90 | final String html = mdRenderer.render(document); 91 | final VelocityEngine engine = new VelocityEngine(); 92 | final ClassLoader classLoader = Thread.currentThread() 93 | .getContextClassLoader(); 94 | final StringWriter writer = new StringWriter(); 95 | engine.evaluate( 96 | new VelocityContext( 97 | new MapOf<>( 98 | new MapEntry<>("readme", html), 99 | new MapEntry<>("title", title), 100 | new MapEntry<>("link", link) 101 | ) 102 | ), 103 | writer, 104 | "", 105 | new InputStreamReader( 106 | classLoader.getResourceAsStream("readme/readme.html") 107 | ) 108 | ); 109 | 110 | return new RsHtml(new TextOf(writer.toString()).asString()); 111 | } 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/repo/DbRepo.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass.repo; 2 | 3 | import dev.youshallnotpass.YsnpException; 4 | import dev.youshallnotpass.inspection.Inspection; 5 | import dev.youshallnotpass.inspection.allfinal.DbAllfinal; 6 | import dev.youshallnotpass.inspection.allpublic.DbAllpublic; 7 | import dev.youshallnotpass.inspection.inheritancefree.DbInheritanceFree; 8 | import dev.youshallnotpass.inspection.nomultiplereturn.DbNoMultipleReturn; 9 | import dev.youshallnotpass.inspection.nullfree.DbNullfree; 10 | import dev.youshallnotpass.inspection.setterfree.DbSetterFree; 11 | import dev.youshallnotpass.inspection.staticfree.DbStaticfree; 12 | import com.nikialeksey.jood.Db; 13 | import com.nikialeksey.jood.JdException; 14 | import com.nikialeksey.jood.QueryResult; 15 | import com.nikialeksey.jood.args.StringArg; 16 | import com.nikialeksey.jood.sql.JdSql; 17 | 18 | import java.sql.ResultSet; 19 | import java.sql.SQLException; 20 | import java.util.UUID; 21 | 22 | public final class DbRepo implements Repo { 23 | 24 | private final Db db; 25 | private final String path; 26 | 27 | public DbRepo(final Db db, final String path) { 28 | this.db = db; 29 | this.path = path; 30 | } 31 | 32 | @Override 33 | public Inspection nullfree() throws YsnpException { 34 | try ( 35 | final QueryResult qr = db.read( 36 | new JdSql( 37 | "SELECT id FROM nullfree WHERE repo = ?", 38 | new StringArg(path) 39 | ) 40 | ) 41 | ) { 42 | final String id; 43 | final ResultSet rs = qr.rs(); 44 | if (!rs.next()) { 45 | id = UUID.randomUUID().toString(); 46 | db.write( 47 | new JdSql( 48 | "INSERT INTO nullfree (id, repo) VALUES(?, ?)", 49 | new StringArg(id), 50 | new StringArg(path) 51 | ) 52 | ); 53 | } else { 54 | id = rs.getString("id"); 55 | } 56 | return new DbNullfree(db, id); 57 | } catch (final JdException | SQLException e) { 58 | throw new YsnpException( 59 | "Could not get the nullfree for repo " + path, 60 | e 61 | ); 62 | } 63 | } 64 | 65 | @Override 66 | public Inspection staticfree() throws YsnpException { 67 | try ( 68 | final QueryResult qr = db.read( 69 | new JdSql( 70 | "SELECT id FROM staticfree WHERE repo = ?", 71 | new StringArg(path) 72 | ) 73 | ) 74 | ) { 75 | final String id; 76 | final ResultSet rs = qr.rs(); 77 | if (!rs.next()) { 78 | id = UUID.randomUUID().toString(); 79 | db.write( 80 | new JdSql( 81 | "INSERT INTO staticfree (id, repo) VALUES(?, ?)", 82 | new StringArg(id), 83 | new StringArg(path) 84 | ) 85 | ); 86 | } else { 87 | id = rs.getString("id"); 88 | } 89 | return new DbStaticfree(db, id); 90 | } catch (final JdException | SQLException e) { 91 | throw new YsnpException( 92 | "Could not get the staticfree for repo " + path, 93 | e 94 | ); 95 | } 96 | } 97 | 98 | @Override 99 | public Inspection allfinal() throws YsnpException { 100 | try ( 101 | final QueryResult qr = db.read( 102 | new JdSql( 103 | "SELECT id FROM allfinal WHERE repo = ?", 104 | new StringArg(path) 105 | ) 106 | ) 107 | ) { 108 | final String id; 109 | final ResultSet rs = qr.rs(); 110 | if (!rs.next()) { 111 | id = UUID.randomUUID().toString(); 112 | db.write( 113 | new JdSql( 114 | "INSERT INTO allfinal (id, repo) VALUES(?, ?)", 115 | new StringArg(id), 116 | new StringArg(path) 117 | ) 118 | ); 119 | } else { 120 | id = rs.getString("id"); 121 | } 122 | return new DbAllfinal(db, id); 123 | } catch (final JdException | SQLException e) { 124 | throw new YsnpException( 125 | "Could not get the allfinal for repo " + path, 126 | e 127 | ); 128 | } 129 | } 130 | 131 | @Override 132 | public Inspection allpublic() throws YsnpException { 133 | try ( 134 | final QueryResult qr = db.read( 135 | new JdSql( 136 | "SELECT id FROM allpublic WHERE repo = ?", 137 | new StringArg(path) 138 | ) 139 | ) 140 | ) { 141 | final String id; 142 | final ResultSet rs = qr.rs(); 143 | if (!rs.next()) { 144 | id = UUID.randomUUID().toString(); 145 | db.write( 146 | new JdSql( 147 | "INSERT INTO allpublic (id, repo) VALUES(?, ?)", 148 | new StringArg(id), 149 | new StringArg(path) 150 | ) 151 | ); 152 | } else { 153 | id = rs.getString("id"); 154 | } 155 | return new DbAllpublic(db, id); 156 | } catch (final JdException | SQLException e) { 157 | throw new YsnpException( 158 | "Could not get the allpublic for repo " + path, 159 | e 160 | ); 161 | } 162 | } 163 | 164 | @Override 165 | public Inspection setterfree() throws YsnpException { 166 | try ( 167 | final QueryResult qr = db.read( 168 | new JdSql( 169 | "SELECT id FROM setterfree WHERE repo = ?", 170 | new StringArg(path) 171 | ) 172 | ) 173 | ) { 174 | final String id; 175 | final ResultSet rs = qr.rs(); 176 | if (!rs.next()) { 177 | id = UUID.randomUUID().toString(); 178 | db.write( 179 | new JdSql( 180 | "INSERT INTO setterfree (id, repo) VALUES(?, ?)", 181 | new StringArg(id), 182 | new StringArg(path) 183 | ) 184 | ); 185 | } else { 186 | id = rs.getString("id"); 187 | } 188 | return new DbSetterFree(db, id); 189 | } catch (final JdException | SQLException e) { 190 | throw new YsnpException( 191 | "Could not get the setterfree for repo " + path, 192 | e 193 | ); 194 | } 195 | } 196 | 197 | @Override 198 | public Inspection nomultiplereturn() throws YsnpException { 199 | try ( 200 | final QueryResult qr = db.read( 201 | new JdSql( 202 | "SELECT id FROM nomultiplereturn WHERE repo = ?", 203 | new StringArg(path) 204 | ) 205 | ) 206 | ) { 207 | final String id; 208 | final ResultSet rs = qr.rs(); 209 | if (!rs.next()) { 210 | id = UUID.randomUUID().toString(); 211 | db.write( 212 | new JdSql( 213 | "INSERT INTO nomultiplereturn (id, repo) VALUES(?, ?)", 214 | new StringArg(id), 215 | new StringArg(path) 216 | ) 217 | ); 218 | } else { 219 | id = rs.getString("id"); 220 | } 221 | return new DbNoMultipleReturn(db, id); 222 | } catch (final JdException | SQLException e) { 223 | throw new YsnpException( 224 | "Could not get the nomultiplereturn for repo " + path, 225 | e 226 | ); 227 | } 228 | } 229 | 230 | @Override 231 | public Inspection inheritancefree() throws YsnpException { 232 | try ( 233 | final QueryResult qr = db.read( 234 | new JdSql( 235 | "SELECT id FROM inheritancefree WHERE repo = ?", 236 | new StringArg(path) 237 | ) 238 | ) 239 | ) { 240 | final String id; 241 | final ResultSet rs = qr.rs(); 242 | if (!rs.next()) { 243 | id = UUID.randomUUID().toString(); 244 | db.write( 245 | new JdSql( 246 | "INSERT INTO inheritancefree (id, repo) VALUES(?, ?)", 247 | new StringArg(id), 248 | new StringArg(path) 249 | ) 250 | ); 251 | } else { 252 | id = rs.getString("id"); 253 | } 254 | return new DbInheritanceFree(db, id); 255 | } catch (final JdException | SQLException e) { 256 | throw new YsnpException( 257 | "Could not get the inheritancefree for repo " + path, 258 | e 259 | ); 260 | } 261 | } 262 | } 263 | -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/repo/DbRepos.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass.repo; 2 | 3 | import dev.youshallnotpass.YsnpException; 4 | import com.nikialeksey.jood.Db; 5 | import com.nikialeksey.jood.JdException; 6 | import com.nikialeksey.jood.QueryResult; 7 | import com.nikialeksey.jood.args.StringArg; 8 | import com.nikialeksey.jood.sql.JdSql; 9 | 10 | import java.sql.ResultSet; 11 | import java.sql.SQLException; 12 | 13 | public final class DbRepos implements Repos { 14 | 15 | private final Db db; 16 | 17 | public DbRepos(final Db db) { 18 | this.db = db; 19 | } 20 | 21 | @Override 22 | public Repo repo(final String path) throws YsnpException { 23 | try ( 24 | final QueryResult qr = db.read( 25 | new JdSql( 26 | "SELECT 1 FROM repo WHERE path = ?", 27 | new StringArg(path) 28 | ) 29 | ) 30 | ) { 31 | final ResultSet rs = qr.rs(); 32 | if (!rs.next()) { 33 | db.write( 34 | new JdSql( 35 | "INSERT INTO repo VALUES(?)", 36 | new StringArg(path) 37 | ) 38 | ); 39 | } 40 | return new DbRepo(db, path); 41 | } catch (final JdException | SQLException e) { 42 | throw new YsnpException( 43 | "Could not get the repo by path " + path, 44 | e 45 | ); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/repo/Repo.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass.repo; 2 | 3 | import dev.youshallnotpass.YsnpException; 4 | import dev.youshallnotpass.inspection.Inspection; 5 | 6 | public interface Repo { 7 | Inspection nullfree() throws YsnpException; 8 | Inspection staticfree() throws YsnpException; 9 | Inspection allfinal() throws YsnpException; 10 | Inspection allpublic() throws YsnpException; 11 | Inspection setterfree() throws YsnpException; 12 | Inspection nomultiplereturn() throws YsnpException; 13 | Inspection inheritancefree() throws YsnpException; 14 | 15 | final class Fake implements Repo { 16 | 17 | @Override 18 | public Inspection nullfree() throws YsnpException { 19 | return new Inspection.Fake(); 20 | } 21 | 22 | @Override 23 | public Inspection staticfree() throws YsnpException { 24 | return new Inspection.Fake(); 25 | } 26 | 27 | @Override 28 | public Inspection allfinal() throws YsnpException { 29 | return new Inspection.Fake(); 30 | } 31 | 32 | @Override 33 | public Inspection allpublic() throws YsnpException { 34 | return new Inspection.Fake(); 35 | } 36 | 37 | @Override 38 | public Inspection setterfree() throws YsnpException { 39 | return new Inspection.Fake(); 40 | } 41 | 42 | @Override 43 | public Inspection nomultiplereturn() throws YsnpException { 44 | return new Inspection.Fake(); 45 | } 46 | 47 | @Override 48 | public Inspection inheritancefree() throws YsnpException { 49 | return new Inspection.Fake(); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /app/src/main/java/dev/youshallnotpass/repo/Repos.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass.repo; 2 | 3 | import dev.youshallnotpass.YsnpException; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | public interface Repos { 9 | Repo repo(final String path) throws YsnpException; 10 | 11 | final class Fake implements Repos { 12 | private final Map pathToRepo; 13 | 14 | public Fake() { 15 | this(new HashMap<>()); 16 | } 17 | 18 | public Fake(final Map pathToRepo) { 19 | this.pathToRepo = pathToRepo; 20 | } 21 | 22 | @Override 23 | public Repo repo(final String path) { 24 | final Repo repo; 25 | if (pathToRepo.containsKey(path)) { 26 | repo = pathToRepo.get(path); 27 | } else { 28 | repo = new Repo.Fake(); 29 | pathToRepo.put(path, repo); 30 | } 31 | return repo; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %m%n%rEx{full} 5 | 6 | 7 | 8 | 9 | logs/log.txt 10 | 11 | %d{HH:mm:ss.SSS} %-5level %logger{36} - %m%n%rEx{full} 12 | 13 | 14 | logs/log-%d{yyyy-MM-dd}.%i.log.gz 15 | 10MB 16 | 20 17 | 1GB 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /app/src/main/resources/readme/readme.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | ${title} 9 | 14 | 37 | 38 | 39 | 58 | 59 | -------------------------------------------------------------------------------- /app/src/test/java/dev/youshallnotpass/AppTest.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass; 2 | 3 | import dev.youshallnotpass.repo.DbRepos; 4 | import com.nikialeksey.jood.Db; 5 | import com.nikialeksey.jood.QueryResult; 6 | import com.nikialeksey.jood.sql.JdSql; 7 | import com.nikialeksey.nullfree.SimpleNullfree; 8 | import com.nikialeksey.nullfree.badge.SimpleBadge; 9 | import com.nikialeksey.nullfree.sources.SimpleSources; 10 | import com.nikialeksey.nullfree.sources.java.JavaSourceFileFactory; 11 | import org.apache.http.Consts; 12 | import org.apache.http.HttpResponse; 13 | import org.apache.http.NameValuePair; 14 | import org.apache.http.client.entity.UrlEncodedFormEntity; 15 | import org.apache.http.client.methods.CloseableHttpResponse; 16 | import org.apache.http.client.methods.HttpGet; 17 | import org.apache.http.client.methods.HttpPost; 18 | import org.apache.http.client.protocol.HttpClientContext; 19 | import org.apache.http.impl.client.CloseableHttpClient; 20 | import org.apache.http.impl.client.HttpClients; 21 | import org.apache.http.message.BasicNameValuePair; 22 | import org.apache.http.util.EntityUtils; 23 | import org.hamcrest.core.IsEqual; 24 | import org.hamcrest.core.StringContains; 25 | import org.junit.Assert; 26 | import org.junit.Test; 27 | import org.takes.http.FtRemote; 28 | 29 | import java.io.File; 30 | import java.net.HttpURLConnection; 31 | import java.net.URI; 32 | import java.net.URL; 33 | import java.sql.ResultSet; 34 | import java.util.ArrayList; 35 | import java.util.List; 36 | 37 | public final class AppTest { 38 | 39 | @Test 40 | public void checkNullfreeCurrentProject() throws Exception { 41 | final String user = "user"; 42 | final String repo = "repo"; 43 | new FtRemote(new App(new DbRepos(new YsnpDb(new SqliteDb())))).exec((final URI home) -> { 44 | try { 45 | new SimpleNullfree( 46 | new SimpleSources( 47 | new File("../"), 48 | new JavaSourceFileFactory() 49 | ), 50 | SimpleBadge::new 51 | ).badge().send( 52 | new URL( 53 | String.format( 54 | "%s/nullfree/%s/%s", 55 | home.toString(), 56 | user, 57 | repo 58 | ) 59 | ) 60 | ); 61 | 62 | final URL saved = new URL(home.toString() + "/nullfree/" + user + "/" + repo); 63 | final HttpGet request = new HttpGet(saved.toURI()); 64 | final CloseableHttpClient httpClient = HttpClients.createDefault(); 65 | final HttpClientContext context = HttpClientContext.create(); 66 | final CloseableHttpResponse response = httpClient.execute( 67 | request, 68 | context 69 | ); 70 | 71 | Assert.assertThat( 72 | response.getStatusLine().getStatusCode(), 73 | IsEqual.equalTo(HttpURLConnection.HTTP_OK) 74 | ); 75 | } catch (final Exception e) { 76 | throw new RuntimeException(e); 77 | } 78 | }); 79 | } 80 | 81 | @Test 82 | public void sendNullDescriptions() throws Exception { 83 | final String user = "user"; 84 | final String repo = "repo"; 85 | new FtRemote(new App(new DbRepos(new YsnpDb(new SqliteDb())))).exec((final URI home) -> { 86 | try ( 87 | final CloseableHttpClient httpClient = HttpClients.createDefault() 88 | ) { 89 | final URL queryUrl = new URL(home.toString() + "/nullfree/" + user + "/" + repo); 90 | 91 | final List form = new ArrayList<>(); 92 | form.add(new BasicNameValuePair("violation", "null 1")); 93 | form.add(new BasicNameValuePair("violation", "null 2")); 94 | 95 | final HttpPost sendDescription = new HttpPost(queryUrl.toURI()); 96 | sendDescription.setEntity(new UrlEncodedFormEntity(form, Consts.UTF_8)); 97 | final HttpResponse sendResponse = httpClient.execute(sendDescription); 98 | Assert.assertThat( 99 | EntityUtils.toString(sendResponse.getEntity()), 100 | sendResponse.getStatusLine().getStatusCode(), 101 | IsEqual.equalTo(HttpURLConnection.HTTP_OK) 102 | ); 103 | 104 | final HttpResponse response = httpClient.execute( 105 | new HttpGet(queryUrl.toURI()), 106 | HttpClientContext.create() 107 | ); 108 | 109 | final String responseEntity = EntityUtils.toString(response.getEntity()); 110 | Assert.assertThat( 111 | responseEntity, 112 | response.getStatusLine().getStatusCode(), 113 | IsEqual.equalTo(HttpURLConnection.HTTP_OK) 114 | ); 115 | Assert.assertThat( 116 | responseEntity, 117 | StringContains.containsString("declined") 118 | ); 119 | } catch (final Exception e) { 120 | throw new RuntimeException(e); 121 | } 122 | }); 123 | } 124 | 125 | @Test 126 | public void sendNullDescriptionsWithThreshold() throws Exception { 127 | final String user = "user"; 128 | final String repo = "repo"; 129 | final Db db = new YsnpDb(new SqliteDb()); 130 | new FtRemote(new App(new DbRepos(db))).exec((final URI home) -> { 131 | try ( 132 | final CloseableHttpClient httpClient = HttpClients.createDefault() 133 | ) { 134 | final URL queryUrl = new URL(home.toString() + "/nullfree/" + user + "/" + repo); 135 | 136 | final List form = new ArrayList<>(); 137 | form.add(new BasicNameValuePair("null", "null 1")); 138 | form.add(new BasicNameValuePair("null", "null 2")); 139 | form.add(new BasicNameValuePair("threshold", "2")); 140 | 141 | final HttpPost sendDescription = new HttpPost(queryUrl.toURI()); 142 | sendDescription.setEntity(new UrlEncodedFormEntity(form, Consts.UTF_8)); 143 | final HttpResponse sendResponse = httpClient.execute(sendDescription); 144 | Assert.assertThat( 145 | EntityUtils.toString(sendResponse.getEntity()), 146 | sendResponse.getStatusLine().getStatusCode(), 147 | IsEqual.equalTo(HttpURLConnection.HTTP_OK) 148 | ); 149 | 150 | final HttpResponse response = httpClient.execute( 151 | new HttpGet(queryUrl.toURI()), 152 | HttpClientContext.create() 153 | ); 154 | 155 | try ( 156 | final QueryResult qr = db.read( 157 | new JdSql( 158 | "SELECT threshold FROM nullfree " + 159 | "WHERE repo = 'user/repo'" 160 | ) 161 | ) 162 | ) { 163 | final ResultSet rs = qr.rs(); 164 | Assert.assertThat(rs.next(), IsEqual.equalTo(true)); 165 | final int threshold = rs.getInt("threshold"); 166 | Assert.assertThat(threshold, IsEqual.equalTo(2)); 167 | } 168 | 169 | final String responseEntity = EntityUtils.toString(response.getEntity()); 170 | Assert.assertThat( 171 | responseEntity, 172 | response.getStatusLine().getStatusCode(), 173 | IsEqual.equalTo(HttpURLConnection.HTTP_OK) 174 | ); 175 | Assert.assertThat( 176 | responseEntity, 177 | StringContains.containsString("approved") 178 | ); 179 | } catch (final Exception e) { 180 | throw new RuntimeException(e); 181 | } 182 | }); 183 | } 184 | 185 | @Test 186 | public void sendStaticDescriptionsWithThreshold() throws Exception { 187 | final String user = "user"; 188 | final String repo = "repo"; 189 | final Db db = new YsnpDb(new SqliteDb()); 190 | new FtRemote(new App(new DbRepos(db))).exec((final URI home) -> { 191 | try ( 192 | final CloseableHttpClient httpClient = HttpClients.createDefault() 193 | ) { 194 | final URL queryUrl = new URL(home.toString() + "/staticfree/" + user + "/" + repo); 195 | 196 | final List form = new ArrayList<>(); 197 | form.add(new BasicNameValuePair("violation", "violation 1")); 198 | form.add(new BasicNameValuePair("violation", "violation 2")); 199 | form.add(new BasicNameValuePair("threshold", "2")); 200 | 201 | final HttpPost sendDescription = new HttpPost(queryUrl.toURI()); 202 | sendDescription.setEntity(new UrlEncodedFormEntity(form, Consts.UTF_8)); 203 | final HttpResponse sendResponse = httpClient.execute(sendDescription); 204 | Assert.assertThat( 205 | EntityUtils.toString(sendResponse.getEntity()), 206 | sendResponse.getStatusLine().getStatusCode(), 207 | IsEqual.equalTo(HttpURLConnection.HTTP_OK) 208 | ); 209 | 210 | try ( 211 | final QueryResult qr = db.read( 212 | new JdSql( 213 | "SELECT threshold FROM staticfree " + 214 | "WHERE repo = 'user/repo'" 215 | ) 216 | ) 217 | ) { 218 | final ResultSet rs = qr.rs(); 219 | Assert.assertThat(rs.next(), IsEqual.equalTo(true)); 220 | final int threshold = rs.getInt("threshold"); 221 | Assert.assertThat(threshold, IsEqual.equalTo(2)); 222 | } 223 | 224 | try ( 225 | final QueryResult qr = db.read( 226 | new JdSql( 227 | "SELECT description FROM staticfree_violation " + 228 | "WHERE repo = 'user/repo'" 229 | ) 230 | ) 231 | ) { 232 | final ResultSet rs = qr.rs(); 233 | Assert.assertThat(rs.next(), IsEqual.equalTo(true)); 234 | Assert.assertThat( 235 | rs.getString("description"), 236 | StringContains.containsString("1") 237 | ); 238 | Assert.assertThat(rs.next(), IsEqual.equalTo(true)); 239 | Assert.assertThat( 240 | rs.getString("description"), 241 | StringContains.containsString("2") 242 | ); 243 | } 244 | 245 | final HttpResponse response = httpClient.execute( 246 | new HttpGet(queryUrl.toURI()), 247 | HttpClientContext.create() 248 | ); 249 | final String responseEntity = EntityUtils.toString(response.getEntity()); 250 | Assert.assertThat( 251 | responseEntity, 252 | response.getStatusLine().getStatusCode(), 253 | IsEqual.equalTo(HttpURLConnection.HTTP_OK) 254 | ); 255 | Assert.assertThat( 256 | responseEntity, 257 | StringContains.containsString("approved") 258 | ); 259 | Assert.assertThat( 260 | responseEntity, 261 | StringContains.containsString("staticfree") 262 | ); 263 | } catch (final Exception e) { 264 | throw new RuntimeException(e); 265 | } 266 | }); 267 | } 268 | 269 | @Test 270 | public void sendNonfinalDescriptionsWithThreshold() throws Exception { 271 | final String user = "user"; 272 | final String repo = "repo"; 273 | final Db db = new YsnpDb(new SqliteDb()); 274 | new FtRemote(new App(new DbRepos(db))).exec((final URI home) -> { 275 | try ( 276 | final CloseableHttpClient httpClient = HttpClients.createDefault() 277 | ) { 278 | final URL queryUrl = new URL(home.toString() + "/allfinal/" + user + "/" + repo); 279 | 280 | final List form = new ArrayList<>(); 281 | form.add(new BasicNameValuePair("violation", "violation 1")); 282 | form.add(new BasicNameValuePair("violation", "violation 2")); 283 | form.add(new BasicNameValuePair("threshold", "2")); 284 | 285 | final HttpPost sendDescription = new HttpPost(queryUrl.toURI()); 286 | sendDescription.setEntity(new UrlEncodedFormEntity(form, Consts.UTF_8)); 287 | final HttpResponse sendResponse = httpClient.execute(sendDescription); 288 | Assert.assertThat( 289 | EntityUtils.toString(sendResponse.getEntity()), 290 | sendResponse.getStatusLine().getStatusCode(), 291 | IsEqual.equalTo(HttpURLConnection.HTTP_OK) 292 | ); 293 | 294 | try ( 295 | final QueryResult qr = db.read( 296 | new JdSql( 297 | "SELECT threshold FROM allfinal " + 298 | "WHERE repo = 'user/repo'" 299 | ) 300 | ) 301 | ) { 302 | final ResultSet rs = qr.rs(); 303 | Assert.assertThat(rs.next(), IsEqual.equalTo(true)); 304 | final int threshold = rs.getInt("threshold"); 305 | Assert.assertThat(threshold, IsEqual.equalTo(2)); 306 | } 307 | 308 | try ( 309 | final QueryResult qr = db.read( 310 | new JdSql( 311 | "SELECT description FROM allfinal_violation " + 312 | "WHERE repo = 'user/repo'" 313 | ) 314 | ) 315 | ) { 316 | final ResultSet rs = qr.rs(); 317 | Assert.assertThat(rs.next(), IsEqual.equalTo(true)); 318 | Assert.assertThat( 319 | rs.getString("description"), 320 | StringContains.containsString("1") 321 | ); 322 | Assert.assertThat(rs.next(), IsEqual.equalTo(true)); 323 | Assert.assertThat( 324 | rs.getString("description"), 325 | StringContains.containsString("2") 326 | ); 327 | } 328 | 329 | final HttpResponse response = httpClient.execute( 330 | new HttpGet(queryUrl.toURI()), 331 | HttpClientContext.create() 332 | ); 333 | final String responseEntity = EntityUtils.toString(response.getEntity()); 334 | Assert.assertThat( 335 | responseEntity, 336 | response.getStatusLine().getStatusCode(), 337 | IsEqual.equalTo(HttpURLConnection.HTTP_OK) 338 | ); 339 | Assert.assertThat( 340 | responseEntity, 341 | StringContains.containsString("approved") 342 | ); 343 | Assert.assertThat( 344 | responseEntity, 345 | StringContains.containsString("allfinal") 346 | ); 347 | } catch (final Exception e) { 348 | throw new RuntimeException(e); 349 | } 350 | }); 351 | } 352 | 353 | @Test 354 | public void sendNonpublicDescriptionsWithThreshold() throws Exception { 355 | final String user = "user"; 356 | final String repo = "repo"; 357 | final Db db = new YsnpDb(new SqliteDb()); 358 | new FtRemote(new App(new DbRepos(db))).exec((final URI home) -> { 359 | try ( 360 | final CloseableHttpClient httpClient = HttpClients.createDefault() 361 | ) { 362 | final URL queryUrl = new URL(home.toString() + "/allpublic/" + user + "/" + repo); 363 | 364 | final List form = new ArrayList<>(); 365 | form.add(new BasicNameValuePair("violation", "violation 1")); 366 | form.add(new BasicNameValuePair("violation", "violation 2")); 367 | form.add(new BasicNameValuePair("threshold", "2")); 368 | 369 | final HttpPost sendDescription = new HttpPost(queryUrl.toURI()); 370 | sendDescription.setEntity(new UrlEncodedFormEntity(form, Consts.UTF_8)); 371 | final HttpResponse sendResponse = httpClient.execute(sendDescription); 372 | Assert.assertThat( 373 | EntityUtils.toString(sendResponse.getEntity()), 374 | sendResponse.getStatusLine().getStatusCode(), 375 | IsEqual.equalTo(HttpURLConnection.HTTP_OK) 376 | ); 377 | 378 | try ( 379 | final QueryResult qr = db.read( 380 | new JdSql( 381 | "SELECT threshold FROM allpublic " + 382 | "WHERE repo = 'user/repo'" 383 | ) 384 | ) 385 | ) { 386 | final ResultSet rs = qr.rs(); 387 | Assert.assertThat(rs.next(), IsEqual.equalTo(true)); 388 | final int threshold = rs.getInt("threshold"); 389 | Assert.assertThat(threshold, IsEqual.equalTo(2)); 390 | } 391 | 392 | try ( 393 | final QueryResult qr = db.read( 394 | new JdSql( 395 | "SELECT description FROM allpublic_violation " + 396 | "WHERE repo = 'user/repo'" 397 | ) 398 | ) 399 | ) { 400 | final ResultSet rs = qr.rs(); 401 | Assert.assertThat(rs.next(), IsEqual.equalTo(true)); 402 | Assert.assertThat( 403 | rs.getString("description"), 404 | StringContains.containsString("1") 405 | ); 406 | Assert.assertThat(rs.next(), IsEqual.equalTo(true)); 407 | Assert.assertThat( 408 | rs.getString("description"), 409 | StringContains.containsString("2") 410 | ); 411 | } 412 | 413 | final HttpResponse response = httpClient.execute( 414 | new HttpGet(queryUrl.toURI()), 415 | HttpClientContext.create() 416 | ); 417 | final String responseEntity = EntityUtils.toString(response.getEntity()); 418 | Assert.assertThat( 419 | responseEntity, 420 | response.getStatusLine().getStatusCode(), 421 | IsEqual.equalTo(HttpURLConnection.HTTP_OK) 422 | ); 423 | Assert.assertThat( 424 | responseEntity, 425 | StringContains.containsString("approved") 426 | ); 427 | Assert.assertThat( 428 | responseEntity, 429 | StringContains.containsString("allpublic") 430 | ); 431 | } catch (final Exception e) { 432 | throw new RuntimeException(e); 433 | } 434 | }); 435 | } 436 | 437 | @Test 438 | public void sendSetterFreeDescriptionsWithThreshold() throws Exception { 439 | final String user = "user"; 440 | final String repo = "repo"; 441 | final Db db = new YsnpDb(new SqliteDb()); 442 | new FtRemote(new App(new DbRepos(db))).exec((final URI home) -> { 443 | try ( 444 | final CloseableHttpClient httpClient = HttpClients.createDefault() 445 | ) { 446 | final URL queryUrl = new URL(home.toString() + "/setterfree/" + user + "/" + repo); 447 | 448 | final List form = new ArrayList<>(); 449 | form.add(new BasicNameValuePair("violation", "violation 1")); 450 | form.add(new BasicNameValuePair("violation", "violation 2")); 451 | form.add(new BasicNameValuePair("threshold", "2")); 452 | 453 | final HttpPost sendDescription = new HttpPost(queryUrl.toURI()); 454 | sendDescription.setEntity(new UrlEncodedFormEntity(form, Consts.UTF_8)); 455 | final HttpResponse sendResponse = httpClient.execute(sendDescription); 456 | Assert.assertThat( 457 | EntityUtils.toString(sendResponse.getEntity()), 458 | sendResponse.getStatusLine().getStatusCode(), 459 | IsEqual.equalTo(HttpURLConnection.HTTP_OK) 460 | ); 461 | 462 | try ( 463 | final QueryResult qr = db.read( 464 | new JdSql( 465 | "SELECT threshold FROM setterfree " + 466 | "WHERE repo = 'user/repo'" 467 | ) 468 | ) 469 | ) { 470 | final ResultSet rs = qr.rs(); 471 | Assert.assertThat(rs.next(), IsEqual.equalTo(true)); 472 | final int threshold = rs.getInt("threshold"); 473 | Assert.assertThat(threshold, IsEqual.equalTo(2)); 474 | } 475 | 476 | try ( 477 | final QueryResult qr = db.read( 478 | new JdSql( 479 | "SELECT description FROM setterfree_violation " + 480 | "WHERE repo = 'user/repo'" 481 | ) 482 | ) 483 | ) { 484 | final ResultSet rs = qr.rs(); 485 | Assert.assertThat(rs.next(), IsEqual.equalTo(true)); 486 | Assert.assertThat( 487 | rs.getString("description"), 488 | StringContains.containsString("1") 489 | ); 490 | Assert.assertThat(rs.next(), IsEqual.equalTo(true)); 491 | Assert.assertThat( 492 | rs.getString("description"), 493 | StringContains.containsString("2") 494 | ); 495 | } 496 | 497 | final HttpResponse response = httpClient.execute( 498 | new HttpGet(queryUrl.toURI()), 499 | HttpClientContext.create() 500 | ); 501 | final String responseEntity = EntityUtils.toString(response.getEntity()); 502 | Assert.assertThat( 503 | responseEntity, 504 | response.getStatusLine().getStatusCode(), 505 | IsEqual.equalTo(HttpURLConnection.HTTP_OK) 506 | ); 507 | Assert.assertThat( 508 | responseEntity, 509 | StringContains.containsString("approved") 510 | ); 511 | Assert.assertThat( 512 | responseEntity, 513 | StringContains.containsString("setterfree") 514 | ); 515 | } catch (final Exception e) { 516 | throw new RuntimeException(e); 517 | } 518 | }); 519 | } 520 | 521 | @Test 522 | public void sendMultipleReturnDescriptionsWithThreshold() throws Exception { 523 | final String user = "user"; 524 | final String repo = "repo"; 525 | final Db db = new YsnpDb(new SqliteDb()); 526 | new FtRemote(new App(new DbRepos(db))).exec((final URI home) -> { 527 | try ( 528 | final CloseableHttpClient httpClient = HttpClients.createDefault() 529 | ) { 530 | final URL queryUrl = new URL(home.toString() + "/nomultiplereturn/" + user + "/" + repo); 531 | 532 | final List form = new ArrayList<>(); 533 | form.add(new BasicNameValuePair("violation", "violation 1")); 534 | form.add(new BasicNameValuePair("violation", "violation 2")); 535 | form.add(new BasicNameValuePair("threshold", "2")); 536 | 537 | final HttpPost sendDescription = new HttpPost(queryUrl.toURI()); 538 | sendDescription.setEntity(new UrlEncodedFormEntity(form, Consts.UTF_8)); 539 | final HttpResponse sendResponse = httpClient.execute(sendDescription); 540 | Assert.assertThat( 541 | EntityUtils.toString(sendResponse.getEntity()), 542 | sendResponse.getStatusLine().getStatusCode(), 543 | IsEqual.equalTo(HttpURLConnection.HTTP_OK) 544 | ); 545 | 546 | try ( 547 | final QueryResult qr = db.read( 548 | new JdSql( 549 | "SELECT threshold FROM nomultiplereturn " + 550 | "WHERE repo = 'user/repo'" 551 | ) 552 | ) 553 | ) { 554 | final ResultSet rs = qr.rs(); 555 | Assert.assertThat(rs.next(), IsEqual.equalTo(true)); 556 | final int threshold = rs.getInt("threshold"); 557 | Assert.assertThat(threshold, IsEqual.equalTo(2)); 558 | } 559 | 560 | try ( 561 | final QueryResult qr = db.read( 562 | new JdSql( 563 | "SELECT description FROM nomultiplereturn_violation " + 564 | "WHERE repo = 'user/repo'" 565 | ) 566 | ) 567 | ) { 568 | final ResultSet rs = qr.rs(); 569 | Assert.assertThat(rs.next(), IsEqual.equalTo(true)); 570 | Assert.assertThat( 571 | rs.getString("description"), 572 | StringContains.containsString("1") 573 | ); 574 | Assert.assertThat(rs.next(), IsEqual.equalTo(true)); 575 | Assert.assertThat( 576 | rs.getString("description"), 577 | StringContains.containsString("2") 578 | ); 579 | } 580 | 581 | final HttpResponse response = httpClient.execute( 582 | new HttpGet(queryUrl.toURI()), 583 | HttpClientContext.create() 584 | ); 585 | final String responseEntity = EntityUtils.toString(response.getEntity()); 586 | Assert.assertThat( 587 | responseEntity, 588 | response.getStatusLine().getStatusCode(), 589 | IsEqual.equalTo(HttpURLConnection.HTTP_OK) 590 | ); 591 | Assert.assertThat( 592 | responseEntity, 593 | StringContains.containsString("approved") 594 | ); 595 | Assert.assertThat( 596 | responseEntity, 597 | StringContains.containsString("nomultiplereturn") 598 | ); 599 | } catch (final Exception e) { 600 | throw new RuntimeException(e); 601 | } 602 | }); 603 | } 604 | 605 | @Test 606 | public void sendInheritanceFreeDescriptionsWithThreshold() throws Exception { 607 | final String user = "user"; 608 | final String repo = "repo"; 609 | final Db db = new YsnpDb(new SqliteDb()); 610 | new FtRemote(new App(new DbRepos(db))).exec((final URI home) -> { 611 | try ( 612 | final CloseableHttpClient httpClient = HttpClients.createDefault() 613 | ) { 614 | final URL queryUrl = new URL(home.toString() + "/inheritancefree/" + user + "/" + repo); 615 | 616 | final List form = new ArrayList<>(); 617 | form.add(new BasicNameValuePair("violation", "violation 1")); 618 | form.add(new BasicNameValuePair("violation", "violation 2")); 619 | form.add(new BasicNameValuePair("threshold", "2")); 620 | 621 | final HttpPost sendDescription = new HttpPost(queryUrl.toURI()); 622 | sendDescription.setEntity(new UrlEncodedFormEntity(form, Consts.UTF_8)); 623 | final HttpResponse sendResponse = httpClient.execute(sendDescription); 624 | Assert.assertThat( 625 | EntityUtils.toString(sendResponse.getEntity()), 626 | sendResponse.getStatusLine().getStatusCode(), 627 | IsEqual.equalTo(HttpURLConnection.HTTP_OK) 628 | ); 629 | 630 | try ( 631 | final QueryResult qr = db.read( 632 | new JdSql( 633 | "SELECT threshold FROM inheritancefree " + 634 | "WHERE repo = 'user/repo'" 635 | ) 636 | ) 637 | ) { 638 | final ResultSet rs = qr.rs(); 639 | Assert.assertThat(rs.next(), IsEqual.equalTo(true)); 640 | final int threshold = rs.getInt("threshold"); 641 | Assert.assertThat(threshold, IsEqual.equalTo(2)); 642 | } 643 | 644 | try ( 645 | final QueryResult qr = db.read( 646 | new JdSql( 647 | "SELECT description FROM inheritancefree_violation " + 648 | "WHERE repo = 'user/repo'" 649 | ) 650 | ) 651 | ) { 652 | final ResultSet rs = qr.rs(); 653 | Assert.assertThat(rs.next(), IsEqual.equalTo(true)); 654 | Assert.assertThat( 655 | rs.getString("description"), 656 | StringContains.containsString("1") 657 | ); 658 | Assert.assertThat(rs.next(), IsEqual.equalTo(true)); 659 | Assert.assertThat( 660 | rs.getString("description"), 661 | StringContains.containsString("2") 662 | ); 663 | } 664 | 665 | final HttpResponse response = httpClient.execute( 666 | new HttpGet(queryUrl.toURI()), 667 | HttpClientContext.create() 668 | ); 669 | final String responseEntity = EntityUtils.toString(response.getEntity()); 670 | Assert.assertThat( 671 | responseEntity, 672 | response.getStatusLine().getStatusCode(), 673 | IsEqual.equalTo(HttpURLConnection.HTTP_OK) 674 | ); 675 | Assert.assertThat( 676 | responseEntity, 677 | StringContains.containsString("approved") 678 | ); 679 | Assert.assertThat( 680 | responseEntity, 681 | StringContains.containsString("inheritancefree") 682 | ); 683 | } catch (final Exception e) { 684 | throw new RuntimeException(e); 685 | } 686 | }); 687 | } 688 | 689 | } -------------------------------------------------------------------------------- /app/src/test/java/dev/youshallnotpass/SqliteDb.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass; 2 | 3 | import com.nikialeksey.jood.Db; 4 | import com.nikialeksey.jood.JdDb; 5 | import com.nikialeksey.jood.JdException; 6 | import com.nikialeksey.jood.QueryResult; 7 | import com.nikialeksey.jood.Transaction; 8 | import com.nikialeksey.jood.sql.Sql; 9 | import org.cactoos.Scalar; 10 | import org.cactoos.scalar.Solid; 11 | 12 | import java.io.File; 13 | import java.sql.Connection; 14 | import java.sql.DriverManager; 15 | 16 | public final class SqliteDb implements Db { 17 | 18 | private final JdDb db; 19 | 20 | public SqliteDb() { 21 | this(":memory:"); 22 | } 23 | 24 | public SqliteDb(final File dbFile) { 25 | this(dbFile.getAbsolutePath()); 26 | } 27 | 28 | public SqliteDb(final String name) { 29 | this( 30 | new Solid<>( 31 | () -> DriverManager.getConnection( 32 | String.format("jdbc:sqlite:%s", name) 33 | ) 34 | ) 35 | ); 36 | } 37 | 38 | public SqliteDb(final Scalar conn) { 39 | this(new JdDb(conn)); 40 | } 41 | 42 | public SqliteDb(final JdDb db) { 43 | this.db = db; 44 | } 45 | 46 | @Override 47 | public QueryResult read(final Sql sql) throws JdException { 48 | return db.read(sql); 49 | } 50 | 51 | @Override 52 | public void write(final Sql sql) throws JdException { 53 | db.write(sql); 54 | } 55 | 56 | @Override 57 | public QueryResult writeReturnGenerated(final Sql sql) throws JdException { 58 | return db.writeReturnGenerated(sql); 59 | } 60 | 61 | @Override 62 | public void run(final Transaction transaction) throws JdException { 63 | db.run(transaction); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /app/src/test/java/dev/youshallnotpass/migrations/Migration3Test.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass.migrations; 2 | 3 | import dev.youshallnotpass.SqliteDb; 4 | import com.nikialeksey.jood.Db; 5 | import com.nikialeksey.jood.JdMigrations; 6 | import com.nikialeksey.jood.MigrationsDb; 7 | import com.nikialeksey.jood.QueryResult; 8 | import com.nikialeksey.jood.sql.JdSql; 9 | import org.hamcrest.core.IsEqual; 10 | import org.junit.Assert; 11 | import org.junit.Test; 12 | 13 | import java.sql.ResultSet; 14 | 15 | public final class Migration3Test { 16 | 17 | @Test 18 | public void okFrom2to3Migration() throws Exception { 19 | final Db db = new SqliteDb(); 20 | 21 | final Db dbBefore = new MigrationsDb( 22 | db, 23 | new JdMigrations( 24 | new Migration0(), 25 | new Migration1(), 26 | new Migration2() 27 | ), 28 | 3 29 | ); 30 | 31 | dbBefore.write( 32 | new JdSql( 33 | "INSERT INTO repo (path, badgeUrl, threshold) " + 34 | "VALUES('path1', 'badge', 2)" 35 | ) 36 | ); 37 | dbBefore.write( 38 | new JdSql( 39 | "INSERT INTO null_description (id, repo, description) " + 40 | "VALUES ('1', 'path', 'violation 1')," + 41 | "('2', 'path1', 'violation 2')" 42 | ) 43 | ); 44 | dbBefore.write( 45 | new JdSql( 46 | "INSERT INTO repo (path, badgeUrl, threshold) " + 47 | "VALUES('path2', 'badge', 0)" 48 | ) 49 | ); 50 | 51 | final Db dbAfter = new MigrationsDb( 52 | db, 53 | new JdMigrations( 54 | new Migration0(), 55 | new Migration1(), 56 | new Migration2(), 57 | new Migration3() 58 | ), 59 | 4 60 | ); 61 | 62 | try ( 63 | final QueryResult qr = dbAfter.read( 64 | new JdSql("SELECT * FROM nullfree") 65 | ) 66 | ) { 67 | final ResultSet rs = qr.rs(); 68 | Assert.assertThat(rs.next(), IsEqual.equalTo(true)); 69 | Assert.assertThat(rs.getString("repo"), IsEqual.equalTo("path1")); 70 | Assert.assertThat(rs.next(), IsEqual.equalTo(true)); 71 | Assert.assertThat(rs.getString("repo"), IsEqual.equalTo("path2")); 72 | } 73 | } 74 | } -------------------------------------------------------------------------------- /app/src/test/java/dev/youshallnotpass/readme/TkReadmeTest.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass.readme; 2 | 3 | import org.hamcrest.core.StringContains; 4 | import org.junit.Assert; 5 | import org.junit.Test; 6 | import org.takes.rq.RqFake; 7 | import org.takes.rs.RsPrint; 8 | 9 | public final class TkReadmeTest { 10 | @Test 11 | public void mdReadme() throws Exception { 12 | Assert.assertThat( 13 | new RsPrint( 14 | new TkReadme( 15 | "This is *Sparta*", 16 | "Title", 17 | "https://google.com" 18 | ).act( 19 | new RqFake() 20 | ) 21 | ).print(), 22 | StringContains.containsString("Sparta") 23 | ); 24 | } 25 | 26 | } -------------------------------------------------------------------------------- /app/src/test/java/dev/youshallnotpass/repo/DbReposTest.java: -------------------------------------------------------------------------------- 1 | package dev.youshallnotpass.repo; 2 | 3 | import dev.youshallnotpass.YsnpDb; 4 | import dev.youshallnotpass.SqliteDb; 5 | import dev.youshallnotpass.inspection.Inspection; 6 | import dev.youshallnotpass.inspection.YsnpViolation; 7 | import dev.youshallnotpass.migrations.Migration0; 8 | import com.nikialeksey.jood.Db; 9 | import com.nikialeksey.jood.JdMigrations; 10 | import com.nikialeksey.jood.MigrationsDb; 11 | import com.nikialeksey.jood.QueryResult; 12 | import com.nikialeksey.jood.args.StringArg; 13 | import com.nikialeksey.jood.sql.JdSql; 14 | import org.hamcrest.core.IsEqual; 15 | import org.junit.Assert; 16 | import org.junit.Test; 17 | 18 | public final class DbReposTest { 19 | 20 | @Test 21 | public void okAfterFourMigration() throws Exception { 22 | final Db db = new SqliteDb(); 23 | 24 | final MigrationsDb firstMigration = new MigrationsDb( 25 | db, 26 | new JdMigrations( 27 | new Migration0() 28 | ), 29 | 1 30 | ); 31 | firstMigration.write( 32 | new JdSql( 33 | "INSERT INTO repo (path, badgeUrl) VALUES(?, ?)", 34 | new StringArg("repo1"), 35 | new StringArg("badge1") 36 | ) 37 | ); 38 | 39 | final Repos thirdMigration = new DbRepos(new YsnpDb(db)); 40 | 41 | final String badgeUrl = thirdMigration.repo("repo1").nullfree().badgeUrl(); 42 | 43 | Assert.assertThat(badgeUrl, IsEqual.equalTo("badge1")); 44 | } 45 | 46 | @Test 47 | public void addNullDescription() throws Exception { 48 | final Db db = new YsnpDb(new SqliteDb()); 49 | final Repos repos = new DbRepos(db); 50 | repos.repo("repo1").nullfree().violations().add(new YsnpViolation("null1")); 51 | 52 | final QueryResult qr = db.read(new JdSql("SELECT * FROM null_description")); 53 | Assert.assertThat(qr.rs().next(), IsEqual.equalTo(true)); 54 | Assert.assertThat(qr.rs().getString("repo"), IsEqual.equalTo("repo1")); 55 | Assert.assertThat(qr.rs().getString("description"), IsEqual.equalTo("null1")); 56 | } 57 | 58 | @Test 59 | public void clearNullDescriptions() throws Exception { 60 | final Db db = new YsnpDb(new SqliteDb()); 61 | final Repos repos = new DbRepos(db); 62 | final String repoId = "repo1"; 63 | final Inspection nullfree = repos.repo(repoId).nullfree(); 64 | nullfree.violations().add(new YsnpViolation("null1")); 65 | nullfree.violations().clear(); 66 | 67 | final QueryResult nullRes = db.read( 68 | new JdSql("SELECT * FROM null_description") 69 | ); 70 | Assert.assertThat(nullRes.rs().next(), IsEqual.equalTo(false)); 71 | final QueryResult repoRes = db.read( 72 | new JdSql( 73 | "SELECT * FROM nullfree WHERE repo = ?", 74 | new StringArg(repoId) 75 | ) 76 | ); 77 | Assert.assertThat(repoRes.rs().next(), IsEqual.equalTo(true)); 78 | Assert.assertThat(repoRes.rs().getString("badgeUrl"), IsEqual.equalTo("")); 79 | } 80 | 81 | } -------------------------------------------------------------------------------- /assets/logo.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/youshallnotpass-dev/service/7cb6aac02785f24de064c6c4927dc23a8ec06770/assets/logo.ai -------------------------------------------------------------------------------- /assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/youshallnotpass-dev/service/7cb6aac02785f24de064c6c4927dc23a8ec06770/assets/logo.png -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'dev.youshallnotpass' version '0.6.1' 3 | } 4 | 5 | youshallnotpass { 6 | } 7 | 8 | allprojects { 9 | ext { 10 | group = 'dev.youshallnotpass' 11 | version = '0.3.0' 12 | } 13 | repositories { 14 | mavenCentral() 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/youshallnotpass-dev/service/7cb6aac02785f24de064c6c4927dc23a8ec06770/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Apr 29 13:33:53 ICT 2019 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Youshallnotpass 2 | 3 | 4 | 5 | [![Elegant Objects Respected Here](https://www.elegantobjects.org/badge.svg)](https://www.elegantobjects.org/) 6 | 7 | ![nullfree status](https://youshallnotpass.dev/nullfree/youshallnotpass-dev/service) 8 | ![staticfree status](https://youshallnotpass.dev/staticfree/youshallnotpass-dev/service) 9 | ![allfinal status](https://youshallnotpass.dev/allfinal/youshallnotpass-dev/service) 10 | ![allpublic status](https://youshallnotpass.dev/allpublic/youshallnotpass-dev/service) 11 | ![setterfree status](https://youshallnotpass.dev/setterfree/youshallnotpass-dev/service) 12 | ![nomultiplereturn](https://youshallnotpass.dev/nomultiplereturn/youshallnotpass-dev/service) 13 | ![inheritancefree](https://youshallnotpass.dev/inheritancefree/youshallnotpass-dev/service) 14 | 15 | [![Build Status](https://travis-ci.com/youshallnotpass-dev/service.svg?branch=master)](https://travis-ci.com/youshallnotpass-dev/service) 16 | [![codecov](https://codecov.io/gh/youshallnotpass-dev/service/branch/master/graph/badge.svg)](https://codecov.io/gh/youshallnotpass-dev/service) 17 | 18 | [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/youshallnotpass-dev/service/blob/master/LICENSE) 19 | 20 | ## What is it? 21 | 22 | **Youshallnotpass** is the static analyser for your 23 | [elegant](https://www.elegantobjects.org/) code. 24 | 25 | ## How it works? 26 | 27 | Just see, what it can find in seemingly usual code: 28 | ```java 29 | package com.example; 30 | 31 | import java.util.Collection; 32 | import java.util.StringTokenizer; 33 | 34 | public class Words { 35 | public static final String DELIM = " ,."; 36 | 37 | private Collection words; 38 | 39 | public Words() { 40 | this.words = null; 41 | } 42 | 43 | public Words(Collection words) { 44 | this.words = words; 45 | } 46 | 47 | boolean containsIn(String text) { 48 | if (words == null) return false; 49 | 50 | StringTokenizer tokenizer = new StringTokenizer(text, DELIM); 51 | while (tokenizer.hasMoreTokens()) { 52 | String nextWord = tokenizer.nextToken(); 53 | if (words.contains(nextWord)) return true; 54 | } 55 | 56 | return false; 57 | } 58 | } 59 | ``` 60 | The violations of the **youshallnotpass** analysis: 61 | ``` 62 | nullfree 63 | com.example.Words(Words.java:12) > null 64 | com.example.Words.containsIn(Words.java:20) > null 65 | 66 | staticfree 67 | com.example.A.main(A.java:6) > static 68 | com.example.Words(Words.java:7) > static 69 | 70 | allfinal 71 | com.example.A.main(A.java:6) > String[] args 72 | com.example.A(A.java:5) > A 73 | com.example.Words(Words.java:9) > words 74 | com.example.Words.containsIn(Words.java:22) > StringTokenizer tokenizer = new StringTokenizer(text, DELIM) 75 | com.example.Words.containsIn(Words.java:24) > String nextWord = tokenizer.nextToken() 76 | com.example.Words(Words.java:15) > Collection words 77 | com.example.Words.containsIn(Words.java:19) > String text 78 | com.example.Words(Words.java:6) > Words 79 | 80 | allpublic 81 | com.example.Words.containsIn(Words.java:19) 82 | 83 | nomultiplereturn 84 | com.example.Words.containsIn(Words.java:19) 85 | ``` 86 | 87 | ## Get started 88 | 89 | ### Gradle 90 | Add the plugin to the root `build.gradle` 91 | ```groovy 92 | plugins { 93 | id 'dev.youshallnotpass' version 'x.y.z' 94 | } 95 | 96 | // then configure it, if you need: 97 | youshallnotpass { 98 | offline = true // default false 99 | nullfree { 100 | disabled = true // default false 101 | threshold = 3 // default 0 102 | skipComparisons = true // default false 103 | } 104 | staticfree { 105 | disabled = true // default false 106 | threshold = 2 // default 0 107 | } 108 | allfinal { 109 | disabled = true // default false 110 | threshold = 1 // default 0 111 | skipInterfaceMethodParams = false // default true 112 | skipLambdaParams = true // default false 113 | skipCatchParams = true // default false 114 | } 115 | allpublic { 116 | disabled = true // default false 117 | threshold = 4 // default 0 118 | } 119 | setterfree { 120 | disabled = true // default false 121 | threshold = 5 // default 0 122 | } 123 | nomultiplereturn { 124 | disabled = true // default false 125 | threshold = 6 // default 0 126 | } 127 | inheritancefree { 128 | disabled = true // default false 129 | threshold = 7 // default 0 130 | } 131 | } 132 | ``` 133 | Where `x.y.z` is actual version from gradle plugins 134 | [![Gradle plugin version](https://img.shields.io/maven-metadata/v/https/plugins.gradle.org/m2/dev/youshallnotpass/dev.youshallnotpass.gradle.plugin/maven-metadata.xml.svg?label=gradle-plugin)](https://plugins.gradle.org/plugin/dev.youshallnotpass) 135 | 136 | Invoke it: 137 | ```bash 138 | ./gradlew youshallnotpass 139 | ``` 140 | 141 | ### Maven 142 | Add the plugin to the `pom.xml` 143 | ```xml 144 | 145 | dev.youshallnotpass 146 | youshallnotpass-maven-plugin 147 | x.y.z 148 | 149 | 150 | 151 | true 152 | 153 | true 154 | 3 155 | true 156 | 157 | 158 | true 159 | 2 160 | 161 | 162 | true 163 | 1 164 | false 165 | true 166 | true 167 | 168 | 169 | true 170 | 4 171 | 172 | 173 | true 174 | 5 175 | 176 | 177 | true 178 | 6 179 | 180 | 181 | true 182 | 7 183 | 184 | 185 | 186 | ``` 187 | 188 | Invoke it: 189 | ```bash 190 | mvn youshallnotpass:youshallnotpass 191 | ``` 192 | 193 | Where `x.y.z` is actual version from maven central 194 | [![Maven plugin version](https://img.shields.io/maven-central/v/dev.youshallnotpass/youshallnotpass-maven-plugin.svg?label=maven-plugin)](https://maven-badges.herokuapp.com/maven-central/dev.youshallnotpass/youshallnotpass-maven-plugin) 195 | 196 | ## Inspections 197 | 198 | 1. ✅ [**NullFree**](https://github.com/youshallnotpass-dev/service#NullFree) 199 | ([Why `null` is bad?](https://www.yegor256.com/2014/05/13/why-null-is-bad.html)) 200 | elegant code must not use the `null` keywords 201 | 202 | 2. ✅ [**StaticFree**](https://github.com/youshallnotpass-dev/service#StaticFree) 203 | ([Why `static` is bad?](https://www.yegor256.com/2014/05/05/oop-alternative-to-utility-classes.html)) 204 | elegant code must not use the `static` keywords 205 | 206 | 3. ✅ [**AllFinal**](https://github.com/youshallnotpass-dev/service#AllFinal) 207 | every class, every field, every argument, every local variable must be `final` 208 | in the elegant code 209 | 210 | 4. 🔄 **instanceoffree** `[in progress]` 211 | elegant code must not use the `instanceof` keywords 212 | 213 | 5. ✅ [**inheritancefree**](https://github.com/youshallnotpass-dev/service#InheritanceFree) 214 | elegant code must not use the class inheritance (when one class `extends` 215 | another one), only composition and type inheritance has been allowed 216 | 217 | 6. 🔄 **enumfree** `[in progress]` 218 | elegant code must not use the `enum`s 219 | 220 | 7. 🔄 **switchfree** `[in progress]` 221 | elegant code must not use the `switch` blocks/expressions 222 | 223 | 8. ✅ [**NoMultipleReturn**](https://github.com/youshallnotpass-dev/service#NoMultipleReturn) 224 | elegant code must contain only one (or no one) return in an any method 225 | 226 | 9. 🔄 **getterfree** `[in progress]` 227 | elegant code must not contain any getters 228 | 229 | 10. ✅ [**SetterFree**](https://github.com/youshallnotpass-dev/service#SetterFree) 230 | elegant code must not contain any setters 231 | 232 | 11. ✅ [**AllPublic**](https://github.com/youshallnotpass-dev/service#AllPublic) 233 | elegant code must use only `public` methods 234 | 235 | 12. 🔄 **nopublicmethodnotoverrides** `[in progress]` 236 | every public method in the elegant code must be overrided from an interface 237 | 238 | ### NullFree 239 | Plugin configuration options: 240 | - `skipComparisons` allows use `null` in boolean expressions: 241 | ```java 242 | if (some == null) { 243 | ... 244 | } 245 | ``` 246 | 247 | Can be suppressed in the code by `@SuppressWarnings("nullfree")` 248 | 249 | 250 | ### StaticFree 251 | Can be suppressed in the code by `@SuppressWarnings("staticfree")` 252 | 253 | ### AllFinal 254 | Plugin configuration options: 255 | - `skipInterfaceMethodParams` allows restricting or not interface method 256 | parameter `final`s, by default there is no needed to set `final` for such 257 | places 258 | - `skipLambdaParams` allows skip `final` in lambda parameters, by default 259 | lambda parameter needs to be `final` 260 | - `skipCatchParams` allows skip `final` in `catch` parameters, by default 261 | `catch` parameter needs to be `final` 262 | 263 | Can be suppressed in the code by `@SuppressWarnings("allfinal")` 264 | 265 | ### AllPublic 266 | Can be suppressed in the code by `@SuppressWarnings("allpublic")` 267 | 268 | ### SetterFree 269 | Can be suppressed in the code by `@SuppressWarnings("setterfree")` 270 | 271 | ### NoMultipleReturn 272 | Can be suppressed in the code by `@SuppressWarnings("nomultiplereturn")` 273 | 274 | ### InheritanceFree 275 | Can be suppressed in the code by `@SuppressWarnings("inheritancefree")` 276 | 277 | ## Badges 278 | If you use youshallnotpass plugin without `offline = true` settings, then you 279 | can attach the inspection badges to your readme file: 280 | - `![nullfree status](https://youshallnotpass.dev/nullfree//)` 281 | - `![staticfree status](https://youshallnotpass.dev/staticfree//)` 282 | - `![allfinal status](https://youshallnotpass.dev/allfinal//)` 283 | - `![allpublic status](https://youshallnotpass.dev/allpublic//)` 284 | - `![setterfree status](https://youshallnotpass.dev/setterfree//)` 285 | - `![nomultiplereturn status](https://youshallnotpass.dev/nomultiplereturn//)` 286 | - `![inheritancefree status](https://youshallnotpass.dev/inheritancefree//)` 287 | 288 | 289 | ## Inspection threshold 290 | Any inspection can be configured with `threshold`: 291 | 292 | In `gradle` 293 | ```groovy 294 | youshallnotpass { 295 | ... 296 | staticfree { 297 | threshold = 19 298 | } 299 | ... 300 | } 301 | ``` 302 | 303 | In `maven` 304 | ```xml 305 | 306 | 307 | 19 308 | 309 | 310 | ``` 311 | 312 | 313 | ## Disabling inspections 314 | Any inspection can be disabled by `disabled` settings: 315 | 316 | In `gradle` 317 | ```groovy 318 | youshallnotpass { 319 | ... 320 | staticfree { 321 | disabled = true 322 | } 323 | ... 324 | } 325 | ``` 326 | 327 | In `maven` 328 | ```xml 329 | 330 | 331 | true 332 | 333 | 334 | ``` 335 | 336 | All inspections are enabled by default. 337 | 338 | ## Excluding files from inspects 339 | There is global `exclude` settings, which can be used for defining exclude 340 | patterns: 341 | In `gradle` 342 | ```groovy 343 | youshallnotpass { 344 | exclude = ["glob:**/test/**/*Test.java"] 345 | } 346 | ``` 347 | 348 | In `maven` 349 | ```xml 350 | 351 | glob:**/test/**/*Test.java 352 | 353 | ``` 354 | 355 | There is inspection local exclude configuration option, which has higher 356 | priority than global exclude configuration: 357 | 358 | In `gradle` 359 | ```groovy 360 | nullfree { 361 | exclude = ["glob:**/*SomeBadFile.java"] 362 | } 363 | ``` 364 | 365 | In `maven` 366 | ```xml 367 | 368 | glob:**/*SomeBadFile.java 369 | 370 | ``` 371 | 372 | ## License 373 | [MIT](https://github.com/youshallnotpass-dev/service/blob/master/LICENSE) -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = "youshallnotpass" 2 | include("app") 3 | 4 | --------------------------------------------------------------------------------