diff --git a/.gitignore b/.gitignore index 603b140..50fedab 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,7 @@ /captures .externalNativeBuild .cxx +/.idea/.name +/.idea/compiler.xml +/.idea/jarRepositories.xml +/.idea/deploymentTargetDropDown.xml diff --git a/.idea/gradle.xml b/.idea/gradle.xml index 8125d03..e7a1be7 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -1,10 +1,13 @@ + diff --git a/.idea/misc.xml b/.idea/misc.xml index 37a7509..ef61796 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,6 +1,6 @@ - + diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml deleted file mode 100644 index 7f68460..0000000 --- a/.idea/runConfigurations.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 62da86f..c647d8c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,16 +1,13 @@ apply plugin: 'com.android.application' - apply plugin: 'kotlin-android' -apply plugin: 'kotlin-android-extensions' - android { - compileSdkVersion 29 - buildToolsVersion "29.0.2" + compileSdkVersion 31 + buildToolsVersion "31.0.0" defaultConfig { applicationId "com.github.adriankuta.treedatastructure" minSdkVersion 15 - targetSdkVersion 29 + targetSdkVersion 31 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" @@ -26,10 +23,11 @@ android { dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" - implementation 'androidx.appcompat:appcompat:1.1.0' - implementation 'androidx.core:core-ktx:1.1.0' - implementation 'androidx.constraintlayout:constraintlayout:1.1.3' - testImplementation 'junit:junit:4.12' - androidTestImplementation 'androidx.test.ext:junit:1.1.1' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + implementation 'androidx.appcompat:appcompat:1.3.1' + implementation 'androidx.core:core-ktx:1.6.0' + implementation 'androidx.constraintlayout:constraintlayout:2.1.0' + implementation 'com.github.adriankuta:tree-structure:1.2.3' + testImplementation 'junit:junit:4.13.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.3' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0ebea85..4ff6c41 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -9,7 +9,8 @@ android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> - + diff --git a/app/src/main/java/com/github/adriankuta/treedatastructure/MainActivity.kt b/app/src/main/java/com/github/adriankuta/treedatastructure/MainActivity.kt index 7ba6f96..979282b 100644 --- a/app/src/main/java/com/github/adriankuta/treedatastructure/MainActivity.kt +++ b/app/src/main/java/com/github/adriankuta/treedatastructure/MainActivity.kt @@ -2,11 +2,28 @@ package com.github.adriankuta.treedatastructure import androidx.appcompat.app.AppCompatActivity import android.os.Bundle +import android.util.Log +import com.github.adriankuta.datastructure.tree.tree class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) + + val root = + tree("World") { + child("North America") { + child("USA") { + child("LA") + child("New York") + } + } + child("Europe") { + child("Poland") + child("Germany") + } + } + Log.d("DEBUG_TAG", root.prettyString()) } } diff --git a/build.gradle b/build.gradle index daed351..636974c 100644 --- a/build.gradle +++ b/build.gradle @@ -1,31 +1,32 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = '1.3.61' + ext.kotlin_version = '1.5.30' repositories { google() - jcenter() - + mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:3.5.3' + classpath 'com.android.tools.build:gradle:7.0.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - classpath "io.codearte.gradle.nexus:gradle-nexus-staging-plugin:0.21.2" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } +plugins { + id("io.github.gradle-nexus.publish-plugin") version "1.1.0" + id("org.jetbrains.dokka") version "1.5.0" +} + allprojects { repositories { google() - jcenter() - + mavenCentral() } } task clean(type: Delete) { delete rootProject.buildDir } - -apply plugin: 'io.codearte.nexus-staging' \ No newline at end of file +apply from: "${rootDir}/scripts/publish-root.gradle" \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 863ae4a..c08c94e 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-all.zip diff --git a/scripts/publish-mavencentral.gradle b/scripts/publish-mavencentral.gradle deleted file mode 100644 index 0c2d39f..0000000 --- a/scripts/publish-mavencentral.gradle +++ /dev/null @@ -1,122 +0,0 @@ -task androidSourcesJar(type: Jar) { - archiveClassifier.set("sources") - from android.sourceSets.main.java.source -} - -artifacts { - archives androidSourcesJar -} - -apply plugin: 'maven-publish' -apply plugin: 'signing' - -group = PUBLISH_GROUP_ID -version = PUBLISH_VERSION - -ext["signing.keyId"] = '' -ext["signing.password"] = '' -ext["signing.secretKeyRingFile"] = '' -ext["ossrhUsername"] = '' -ext["ossrhPassword"] = '' - -File secretPropsFile = project.rootProject.file('local.properties') -if (secretPropsFile.exists()) { - println "Found secret props file, loading props" - Properties p = new Properties() - p.load(new FileInputStream(secretPropsFile)) - p.each { name, value -> - ext[name] = value - } -} else { - println "No props file, loading env vars" - ext["signing.keyId"] = System.getenv('SIGNING_KEY_ID') - ext["signing.password"] = System.getenv('SIGNING_PASSWORD') - ext["signing.secretKeyRingFile"] = System.getenv('SIGNING_SECRET_KEY_RING_FILE') - ext["ossrhUsername"] = System.getenv('OSSRH_USERNAME') - ext["ossrhPassword"] = System.getenv('OSSRH_PASSWORD') -} - -nexusStaging { - packageGroup = PUBLISH_GROUP_ID - stagingProfileId = '2097bad464f778' - username = ossrhUsername - password = ossrhPassword -} - -publishing { - publications { - release(MavenPublication) { - // The coordinates of the library, being set from variables that - // we'll set up in a moment - groupId PUBLISH_GROUP_ID - artifactId PUBLISH_ARTIFACT_ID - version PUBLISH_VERSION - - // Two artifacts, the `aar` and the sources - artifact("$buildDir/outputs/aar/${project.getName()}-release.aar") - artifact androidSourcesJar - - // Self-explanatory metadata for the most part - pom { - name = PUBLISH_ARTIFACT_ID - description = 'Simple implementation to store object in tree structure.' - // If your project has a dedicated site, use its URL here - url = 'https://github.com/AdrianKuta/Tree-Data-Structure' - licenses { - license { - name = 'MIT License' - url = 'https://www.mit.edu/~amini/LICENSE.md' - } - } - developers { - developer { - name = 'Adrian Kuta' - email = 'adrian.kuta93@gmail.com' - } - } - // Version control info, if you're using GitHub, follow the format as seen here - scm { - connection = 'scm:git:github.com/AdrianKuta/Tree-Data-Structure.git' - developerConnection = 'scm:git:ssh://github.com/AdrianKuta/Tree-Data-Structure.git' - url = 'https://github.com/AdrianKuta/Tree-Data-Structure/tree/master' - } - // A slightly hacky fix so that your POM will include any transitive dependencies - // that your library builds upon - withXml { - def dependenciesNode = asNode().appendNode('dependencies') - - project.configurations.implementation.allDependencies.each { - def dependencyNode = dependenciesNode.appendNode('dependency') - dependencyNode.appendNode('groupId', it.group) - dependencyNode.appendNode('artifactId', it.name) - dependencyNode.appendNode('version', it.version) - } - } - } - } - } - repositories { - // The repository to publish to, Sonatype/MavenCentral - maven { - // This is an arbitrary name, you may also use "mavencentral" or - // any other name that's descriptive for you - name = "sonatype" - - def releasesRepoUrl = "https://oss.sonatype.org/service/local/staging/deploy/maven2/" - def snapshotsRepoUrl = "https://oss.sonatype.org/content/repositories/snapshots/" - // You only need this if you want to publish snapshots, otherwise just set the URL - // to the release repo directly - url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl - - // The username and password we've fetched earlier - credentials { - username ossrhUsername - password ossrhPassword - } - } - } -} - -signing { - sign publishing.publications -} \ No newline at end of file diff --git a/scripts/publish-module.gradle b/scripts/publish-module.gradle new file mode 100644 index 0000000..4428f78 --- /dev/null +++ b/scripts/publish-module.gradle @@ -0,0 +1,86 @@ +apply plugin: 'maven-publish' +apply plugin: 'signing' +apply plugin: 'org.jetbrains.dokka' + +task androidSourcesJar(type: Jar) { + archiveClassifier.set('sources') + if (project.plugins.findPlugin("com.android.library")) { + from android.sourceSets.main.java.srcDirs + from android.sourceSets.main.kotlin.srcDirs + } else { + from sourceSets.main.java.srcDirs + from sourceSets.main.kotlin.srcDirs + } +} + +tasks.withType(dokkaHtmlPartial.getClass()).configureEach { + pluginsMapConfiguration.set( + ["org.jetbrains.dokka.base.DokkaBase": """{ "separateInheritedMembers": true}"""] + ) +} + +task javadocJar(type: Jar, dependsOn: dokkaJavadoc) { + archiveClassifier.set('javadoc') + from dokkaJavadoc.outputDirectory +} + +artifacts { + archives androidSourcesJar + archives javadocJar +} + +group = PUBLISH_GROUP_ID +version = PUBLISH_VERSION + +afterEvaluate { + publishing { + publications { + release(MavenPublication) { + groupId PUBLISH_GROUP_ID + artifactId PUBLISH_ARTIFACT_ID + version PUBLISH_VERSION + if (project.plugins.findPlugin("com.android.library")) { + from components.release + } else { + from components.java + } + + artifact androidSourcesJar + artifact javadocJar + + pom { + name = PUBLISH_ARTIFACT_ID + description = 'Simple implementation to store object in tree structure.' + url = 'https://github.com/AdrianKuta/Tree-Data-Structure' + licenses { + license { + name = 'MIT License' + url = 'https://www.mit.edu/~amini/LICENSE.md' + } + } + developers { + developer { + name = 'Adrian Kuta' + email = 'adrian.kuta93@gmail.com' + } + } + // Version control info, if you're using GitHub, follow the format as seen here + scm { + connection = 'scm:git:github.com/AdrianKuta/Tree-Data-Structure.git' + developerConnection = 'scm:git:ssh://github.com/AdrianKuta/Tree-Data-Structure.git' + url = 'https://github.com/AdrianKuta/Tree-Data-Structure/tree/master' + } + } + } + } + } +} + +signing { + useInMemoryPgpKeys( + rootProject.ext["signing.keyId"], + rootProject.ext["signing.key"], + rootProject.ext["signing.password"], + ) + sign publishing.publications +} \ No newline at end of file diff --git a/scripts/publish-root.gradle b/scripts/publish-root.gradle new file mode 100644 index 0000000..4695fee --- /dev/null +++ b/scripts/publish-root.gradle @@ -0,0 +1,43 @@ +// Create variables with empty default values +ext["ossrhUsername"] = '' +ext["ossrhPassword"] = '' +ext["sonatypeStagingProfileId"] = '' +ext["signing.keyId"] = '' +ext["signing.password"] = '' +ext["signing.key"] = '' +ext["snapshot"] = '' + +File secretPropsFile = project.rootProject.file('local.properties') +if (secretPropsFile.exists()) { + // Read local.properties file first if it exists + Properties p = new Properties() + new FileInputStream(secretPropsFile).withCloseable { is -> p.load(is) } + p.each { name, value -> ext[name] = value } +} else { + // Use system environment variables + ext["ossrhUsername"] = System.getenv('OSSRH_USERNAME') + ext["ossrhPassword"] = System.getenv('OSSRH_PASSWORD') + ext["sonatypeStagingProfileId"] = System.getenv('SONATYPE_STAGING_PROFILE_ID') + ext["signing.keyId"] = System.getenv('SIGNING_KEY_ID') + ext["signing.password"] = System.getenv('SIGNING_PASSWORD') + ext["signing.key"] = System.getenv('SIGNING_KEY') + ext["snapshot"] = System.getenv('SNAPSHOT') +} + +//if (snapshot) { +// ext["rootVersionName"] = Configuration.snapshotVersionName +//} else { +// ext["rootVersionName"] = Configuration.versionName +//} + +// Set up Sonatype repository +nexusPublishing { + repositories { + sonatype { + stagingProfileId = sonatypeStagingProfileId + username = ossrhUsername + password = ossrhPassword + //version = rootVersionName + } + } +} \ No newline at end of file diff --git a/treedatastructure/build.gradle b/treedatastructure/build.gradle index 18f65ff..9f3b101 100644 --- a/treedatastructure/build.gradle +++ b/treedatastructure/build.gradle @@ -1,22 +1,19 @@ apply plugin: 'com.android.library' apply plugin: 'kotlin-android' -apply plugin: 'kotlin-android-extensions' afterEvaluate { generateReleaseBuildConfig.enabled = false } android { - compileSdkVersion 29 - buildToolsVersion "29.0.2" + compileSdkVersion 31 + buildToolsVersion "31.0.0" defaultConfig { minSdkVersion 15 - targetSdkVersion 29 - versionCode 1 - versionName "1.2.3" - + targetSdkVersion 31 + versionName "2.0.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" consumerProguardFiles 'consumer-rules.pro' } @@ -32,11 +29,11 @@ android { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" - implementation 'androidx.appcompat:appcompat:1.1.0' - implementation 'androidx.core:core-ktx:1.1.0' - testImplementation 'junit:junit:4.12' - androidTestImplementation 'androidx.test.ext:junit:1.1.1' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + implementation 'androidx.appcompat:appcompat:1.3.1' + implementation 'androidx.core:core-ktx:1.6.0' + testImplementation 'junit:junit:4.13.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.3' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' } ext { @@ -45,4 +42,4 @@ ext { PUBLISH_VERSION = android.defaultConfig.versionName } -apply from: "${rootProject.projectDir}/scripts/publish-mavencentral.gradle" +apply from: "${rootProject.projectDir}/scripts/publish-module.gradle" diff --git a/treedatastructure/src/main/AndroidManifest.xml b/treedatastructure/src/main/AndroidManifest.xml index db816ba..d643e17 100644 --- a/treedatastructure/src/main/AndroidManifest.xml +++ b/treedatastructure/src/main/AndroidManifest.xml @@ -1,2 +1 @@ - + diff --git a/treedatastructure/src/main/java/com/github/adriankuta/datastructure/tree/TreeNode.kt b/treedatastructure/src/main/java/com/github/adriankuta/datastructure/tree/TreeNode.kt index 1d19079..94f65c9 100644 --- a/treedatastructure/src/main/java/com/github/adriankuta/datastructure/tree/TreeNode.kt +++ b/treedatastructure/src/main/java/com/github/adriankuta/datastructure/tree/TreeNode.kt @@ -54,7 +54,7 @@ open class TreeNode(val value: T) : Iterable>, ChildDeclarationIn if (_children.isEmpty()) return 0 return _children.size + - _children.sumBy { it.nodeCount() } + _children.sumOf { it.nodeCount() } } /** @@ -62,7 +62,7 @@ open class TreeNode(val value: T) : Iterable>, ChildDeclarationIn */ fun height(): Int { val childrenMaxDepth = _children.map { it.height() } - .max() + .maxOrNull() ?: -1 // -1 because this method counts nodes, and edges are always one less then nodes. return childrenMaxDepth + 1 } @@ -72,14 +72,14 @@ open class TreeNode(val value: T) : Iterable>, ChildDeclarationIn * @return The distance between current node and the root. */ fun depth(): Int { - var _depth = 0 + var depth = 0 var tempParent = parent while (tempParent != null) { - _depth++ + depth++ tempParent = tempParent.parent } - return _depth + return depth } /** diff --git a/treedatastructure/src/main/res/values/strings.xml b/treedatastructure/src/main/res/values/strings.xml deleted file mode 100644 index 1b5bf2f..0000000 --- a/treedatastructure/src/main/res/values/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - Tree Data Structure - diff --git a/treedatastructure/src/test/java/com/github/adriankuta/datastructure/tree/TreeNodeTest.kt b/treedatastructure/src/test/java/com/github/adriankuta/datastructure/tree/TreeNodeTest.kt index 1d455e1..9d770dd 100644 --- a/treedatastructure/src/test/java/com/github/adriankuta/datastructure/tree/TreeNodeTest.kt +++ b/treedatastructure/src/test/java/com/github/adriankuta/datastructure/tree/TreeNodeTest.kt @@ -10,26 +10,26 @@ class TreeNodeTest { @Test fun removeNodeTest() { - val root = TreeNode("Root") - val beveragesNode = TreeNode("Beverages") - val curdNode = TreeNode("Curd") + val root = TreeNode("Root") + val beveragesNode = TreeNode("Beverages") + val curdNode = TreeNode("Curd") root.addChild(beveragesNode) root.addChild(curdNode) - val teaNode = TreeNode("tea") - val coffeeNode = TreeNode("coffee") - val milkShakeNode = TreeNode("Milk Shake") + val teaNode = TreeNode("tea") + val coffeeNode = TreeNode("coffee") + val milkShakeNode = TreeNode("Milk Shake") beveragesNode.addChild(teaNode) beveragesNode.addChild(coffeeNode) beveragesNode.addChild(milkShakeNode) - val gingerTeaNode = TreeNode("ginger tea") - val normalTeaNode = TreeNode("normal tea") + val gingerTeaNode = TreeNode("ginger tea") + val normalTeaNode = TreeNode("normal tea") teaNode.addChild(gingerTeaNode) teaNode.addChild(normalTeaNode) - val yogurtNode = TreeNode("yogurt") - val lassiNode = TreeNode("lassi") + val yogurtNode = TreeNode("yogurt") + val lassiNode = TreeNode("lassi") curdNode.addChild(yogurtNode) curdNode.addChild(lassiNode) @@ -46,9 +46,9 @@ class TreeNodeTest { " └── lassi\n", root.toString() ) - System.out.println("Remove: ${curdNode.value}") + println("Remove: ${curdNode.value}") root.removeChild(curdNode) - System.out.println("Remove: ${gingerTeaNode.value}") + println("Remove: ${gingerTeaNode.value}") root.removeChild(gingerTeaNode) assertEquals( "Root\n" + @@ -62,26 +62,26 @@ class TreeNodeTest { @Test fun clearTest() { - val root = TreeNode("Root") - val beveragesNode = TreeNode("Beverages") - val curdNode = TreeNode("Curd") + val root = TreeNode("Root") + val beveragesNode = TreeNode("Beverages") + val curdNode = TreeNode("Curd") root.addChild(beveragesNode) root.addChild(curdNode) - val teaNode = TreeNode("tea") - val coffeeNode = TreeNode("coffee") - val milkShakeNode = TreeNode("Milk Shake") + val teaNode = TreeNode("tea") + val coffeeNode = TreeNode("coffee") + val milkShakeNode = TreeNode("Milk Shake") beveragesNode.addChild(teaNode) beveragesNode.addChild(coffeeNode) beveragesNode.addChild(milkShakeNode) - val gingerTeaNode = TreeNode("ginger tea") - val normalTeaNode = TreeNode("normal tea") + val gingerTeaNode = TreeNode("ginger tea") + val normalTeaNode = TreeNode("normal tea") teaNode.addChild(gingerTeaNode) teaNode.addChild(normalTeaNode) - val yogurtNode = TreeNode("yogurt") - val lassiNode = TreeNode("lassi") + val yogurtNode = TreeNode("yogurt") + val lassiNode = TreeNode("lassi") curdNode.addChild(yogurtNode) curdNode.addChild(lassiNode)