Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Санитары кода — следим за чистотой силами автом...

Санитары кода — следим за чистотой силами автоматизации

Алена Манюхина, Авто.ру – MOSDROID #9 #Flourine – Видео https://youtu.be/4T3q5qXwhgY?t=1h26m42s

Как удерживать код чистым и при этом не довести коллегу-программиста до нервного тика мелкими правками? Как замерить «чистоту кода»? Как не допустить протухания кодовой базы? Как принести порядок в код старого проекта? И как сделать это в измеримые сроки? С такими вопросами хотя бы раз сталкивается каждый программист во время работы над проектами, особенно большими и долгоживущими.

MOSDROID

June 23, 2018
Tweet

More Decks by MOSDROID

Other Decks in Programming

Transcript

  1. 3

  2. 6

  3. 7

  4. buildTypes { release { shrinkResources true minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),

    'proguard-rules.pro' } } «Мне достаточно proguard и shrinkResources» 9
  5. @Nullable Action1<VASPurchase> onAfterPurchase) { return enrichVasInfosWithActivationState(purchases) .concatMapIterable(infos -> infos) .map(vas

    -> new VASPurchase(vas, vas.activated ? PurchaseState.SUCCESS : PurchaseState.WAITING)) .concatMap(purchase -> Observable.concat( Observable.just(purchase) .doOnNext(purchase1 -> purchase1.purchaseState = purchase1.isActivated() ? PurchaseState.SUCCESS : PurchaseState.IN_PROGRESS) .observeOn(AutoSchedulers.main()) .doOnNext(res -> { if (onBeforePurchase != null) onBeforePurchase.call(res); }), !purchase.isActivated() ? VASManager.getInstance().purchase(offerId, purchase.vas) .onErrorResumeNext(e -> processPurchaseError(e, purchase)) .observeOn(AutoSchedulers.main()) .doOnError(e -> { if (onAfterPurchase != null) onAfterPurchase.call(purchase); }) .map(res -> { purchase.vas.activated = res; purchase.purchaseState = res ? PurchaseState.SUCCESS : PurchaseState.FAIL; return purchase; }) .doOnNext(res -> AnalystManager.getInstance().logPurchase(purchase.vas)) .doOnNext(res -> { if (onAfterPurchase != null) onAfterPurchase.call(purchase); }) : Observable.just(new VASPurchase(purchase.vas, PurchaseState.SUCCESS)) )); } 10 РЕАЛЬНЫЙ КОД ИЗ ПРОЕКТА
  6. public class BaseFile { protected int id; protected String name;

    protected String path; protected long date; public BaseFile(int id, String name, String path, long date) { this.id = id; this.name = name; this.path = path; this.date = date; } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof BaseFile)) return false; BaseFile baseFile = (BaseFile) o; return id == baseFile.id; } } 11 РЕАЛЬНЫЙ КОД ИЗ ПРОЕКТА
  7. › @Nullable/@NonNull › @IntRange, @FloatRange, @Size › @DrawableRes, @ColorRes, @ColorInt,

    @IdRes, @StringRes … › @IntDef, @StringDef › @Px, @Dimension, @DimenRes, › @CheckResult, @CallSuper › @RequiresPermission, @RequiresApi Аннотации <3 14
  8. 15

  9. Использует скомпилированные .class файлы > 400 проверок Gradle plugin, standalone,

    IDE plugin https://github.com/spotbugs/spotbugs- gradle-plugin Findbugs / Spotbugs 17
  10. spotbugs { toolVersion "3.1.3" effort "max" ignoreFailures false reportsDir file("$buildDir/tools/reports/spotbugs")

    } // To generate an HTML report instead of XML tasks.withType(SpotBugsTask) { reports { xml.enabled = false html.enabled = true } } 20
  11. 22

  12. 25 <module name="Indentation"> <property name="basicOffset" value="2"/> <property name="braceAdjustment" value="0"/> <property

    name="caseIndent" value="2"/> <property name="throwsIndent" value="4"/> <property name="lineWrappingIndentation" value="4"/> <property name="arrayInitIndent" value="2"/> </module> <module name="AbbreviationAsWordInName"> <property name="ignoreFinal" value="false"/> <property name="allowedAbbreviationLength" value="1"/> </module>
  13. <?xml version="1.0" encoding="utf-8"?> <checkstyle version="8.0"> <file name="/androidProject/app/src/main/kotlin/ru/android/example/ DraftScreenTest.kt"> <error line="43"

    column="1" severity="error" message="Unexpected blank line(s) before &quot;}&quot;" source="no-blank-line-before-rbrace" /> <error line="45" column="1" severity="error" message="Unexpected blank line(s) before &quot;}&quot;" source="no-blank-line-before-rbrace" /> <error line="46" column="1" severity="error" message="Needless blank line(s)" source="no-consecutive-blank-lines" /> </file> </checkstyle> 28
  14. 29

  15. 31

  16. 32 build: warningThreshold: 0 failThreshold: 0 weights: complexity: 1 style:

    1 empty-blocks: 2 exceptions: 2 potential-bugs: 2 performance: 1 complexity: active: true LongMethod: active: false threshold: 20 ComplexInterface: active: false threshold: 10 includeStaticDeclarations: true
  17. 43

  18. 44

  19. 45