1
0
Fork 0
mirror of https://github.com/ethauvin/kobalt.git synced 2025-04-26 08:27:12 -07:00

Merge pull request #222 from evanchooly/master

fix pom uploading with retrofit
This commit is contained in:
Cedric Beust 2016-06-01 22:28:40 -07:00
commit 898d7dcc0d

View file

@ -6,26 +6,35 @@ import com.beust.kobalt.api.Project
import com.beust.kobalt.maven.Gpg import com.beust.kobalt.maven.Gpg
import com.beust.kobalt.maven.Http import com.beust.kobalt.maven.Http
import com.beust.kobalt.maven.Md5 import com.beust.kobalt.maven.Md5
import com.beust.kobalt.misc.CountingFileRequestBody
import com.beust.kobalt.misc.KobaltExecutors import com.beust.kobalt.misc.KobaltExecutors
import com.beust.kobalt.misc.error import com.beust.kobalt.misc.error
import com.beust.kobalt.misc.log import com.beust.kobalt.misc.log
import com.beust.kobalt.misc.warn import com.beust.kobalt.misc.warn
import com.google.gson.Gson
import com.google.gson.JsonArray import com.google.gson.JsonArray
import com.google.gson.JsonObject import com.google.gson.JsonObject
import com.google.gson.JsonParser import com.google.gson.TypeAdapter
import com.google.gson.reflect.TypeToken
import com.google.inject.assistedinject.Assisted import com.google.inject.assistedinject.Assisted
import okhttp3.* import okhttp3.Credentials
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.RequestBody
import okhttp3.ResponseBody
import retrofit2.Call import retrofit2.Call
import retrofit2.Converter
import retrofit2.Retrofit import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory import retrofit2.http.Body
import retrofit2.http.* import retrofit2.http.GET
import retrofit2.http.Headers import retrofit2.http.POST
import retrofit2.http.PUT
import retrofit2.http.Path
import java.io.File import java.io.File
import java.lang.reflect.Type
import javax.annotation.Nullable import javax.annotation.Nullable
import javax.inject.Inject import javax.inject.Inject
class BintrayResponse()
class BintrayApi @Inject constructor(val http: Http, class BintrayApi @Inject constructor(val http: Http,
@Nullable @Assisted("username") val username: String?, @Nullable @Assisted("username") val username: String?,
@Nullable @Assisted("password") val password: String?, @Nullable @Assisted("password") val password: String?,
@ -34,7 +43,6 @@ class BintrayApi @Inject constructor(val http: Http,
companion object { companion object {
const val BINTRAY_URL_API = "https://api.bintray.com" const val BINTRAY_URL_API = "https://api.bintray.com"
const val BINTRAY_URL_API_CONTENT = BINTRAY_URL_API + "/content"
} }
interface IFactory { interface IFactory {
@ -52,18 +60,6 @@ class BintrayApi @Inject constructor(val http: Http,
fun createPackage(@Path("owner") owner: String, fun createPackage(@Path("owner") owner: String,
@Body content: JsonObject): Call<BintrayResponse> @Body content: JsonObject): Call<BintrayResponse>
@Multipart
@Headers("Content-Type: application/xml")
@PUT("/content/{owner}/maven/{repo}/{version}/{group}/{artifact}/{version}/{name}")
fun uploadPom(@Path("owner") owner: String,
@Path("repo") repo: String,
@Path("group", encoded = true) group: String,
@Path("artifact") artifact: String,
@Path("version") version: String,
@Path("name") name: String,
@Part file: MultipartBody.Part): Call<BintrayResponse>
@Multipart
@PUT("/content/{owner}/maven/{repo}/{version}/{group}/{artifact}/{version}/{name}") @PUT("/content/{owner}/maven/{repo}/{version}/{group}/{artifact}/{version}/{name}")
fun uploadArtifact(@Path("owner") owner: String, fun uploadArtifact(@Path("owner") owner: String,
@Path("repo") repo: String, @Path("repo") repo: String,
@ -71,9 +67,7 @@ class BintrayApi @Inject constructor(val http: Http,
@Path("artifact") artifact: String, @Path("artifact") artifact: String,
@Path("version") version: String, @Path("version") version: String,
@Path("name") name: String, @Path("name") name: String,
@Part file: MultipartBody.Part): Call<BintrayResponse> @Body file: File): Call<BintrayResponse>
} }
private val service: Api private val service: Api
@ -84,7 +78,7 @@ class BintrayApi @Inject constructor(val http: Http,
// level = HttpLoggingInterceptor.Level.BASIC // level = HttpLoggingInterceptor.Level.BASIC
// }) // })
builder.interceptors().add(Interceptor { chain -> builder.interceptors().add(Interceptor { chain ->
var original = chain.request(); val original = chain.request();
chain.proceed(original.newBuilder() chain.proceed(original.newBuilder()
.header("Authorization", Credentials.basic(username, password)) .header("Authorization", Credentials.basic(username, password))
@ -96,7 +90,7 @@ class BintrayApi @Inject constructor(val http: Http,
service = Retrofit.Builder() service = Retrofit.Builder()
.client(okHttpClient) .client(okHttpClient)
.baseUrl(BintrayApi.BINTRAY_URL_API) .baseUrl(BintrayApi.BINTRAY_URL_API)
.addConverterFactory(GsonConverterFactory.create()) .addConverterFactory(ConverterFactory())
.build() .build()
.create(Api::class.java) .create(Api::class.java)
} }
@ -180,33 +174,20 @@ class BintrayApi @Inject constructor(val http: Http,
val results = arrayListOf<Boolean>() val results = arrayListOf<Boolean>()
filesToUpload.forEachIndexed { i, file -> filesToUpload.forEachIndexed { i, file ->
val type = MediaType.parse("multipart/form-data") val owner = org ?: username!!
val repo = project.name
val group = project.group!!.replace('.', '/')
val artifact = project.artifactId!!
val version = project.version!!
val body = MultipartBody.Part.createFormData("artifact", file.name, RequestBody.create(type, file)); val result = service.uploadArtifact(owner, repo, group, artifact, version, file.name, file)
.execute()
if (file.extension != "pom") { val error = result.errorBody()?.string()
val upload = service.uploadArtifact(org ?: username!!, project.name, if (result.errorBody() != null) {
project.group!!.replace('.', '/'), project.artifactId!!, project.version!!, file.name, body) errorMessages.add(error!!)
val result = upload.execute() results.add(false)
val error = result.errorBody()?.string()
if (result.errorBody() != null) {
errorMessages.add(error!!)
results.add(false)
} else {
results.add(true)
}
} else { } else {
http.uploadFile(username, password, fileToPath(project, file) + optionPath, results.add(true)
Http.TypedFile(com.google.common.net.MediaType.ANY_APPLICATION_TYPE.toString(), file),
post = false, // Bintray requires PUT
success = { r: Response -> results.add(true) },
error = { r: Response ->
results.add(false)
val jcResponse = parseResponse(r)
errorMessages.add(jcResponse.errorMessage!!)
})
// service.uploadPom(org ?: username!!, project.name, project.group!!.replace('.', '/'),
// project.artifactId!!, project.version!!, file.name, body)
} }
log(1, " Uploading ${i + 1} / $fileCount " + dots(fileCount, results, file), false) log(1, " Uploading ${i + 1} / $fileCount " + dots(fileCount, results, file), false)
@ -228,37 +209,8 @@ class BintrayApi @Inject constructor(val http: Http,
} }
} }
fun fileToPath(project: Project, f: File) : String {
return listOf(
BINTRAY_URL_API_CONTENT,
org ?: username!!,
"maven",
project.name,
project.version!!,
project.group!!.replace(".", "/"),
project.artifactId!!,
project.version!!,
f.name)
.joinToString("/")
}
class BintrayResponse(val jo: JsonObject?, val errorMessage: String?) class BintrayResponse(val jo: JsonObject?, val errorMessage: String?)
fun parseResponse(r: Response): BintrayResponse {
val networkResponse = r.networkResponse()
if (networkResponse.code() != 200) {
val message = networkResponse.message()
try {
val errorObject = JsonParser().parse(r.body().string()).asJsonObject
return BintrayResponse(null, message + ": " + errorObject.get("message").asString)
} catch(ex: Exception) {
return BintrayResponse(null, message)
}
} else {
return BintrayResponse(JsonParser().parse(r.body().string()).asJsonObject, null)
}
}
fun JsonObject.addNonNull(name: String, value: String?) { fun JsonObject.addNonNull(name: String, value: String?) {
if (value != null) { if (value != null) {
addProperty(name, value); addProperty(name, value);
@ -266,3 +218,31 @@ class BintrayApi @Inject constructor(val http: Http,
} }
} }
class ConverterFactory : Converter.Factory() {
override fun responseBodyConverter(type: Type, annotations: Array<out Annotation>, retrofit: Retrofit): Converter<ResponseBody, *>? {
return GsonResponseBodyConverter(Gson(), Gson().getAdapter(TypeToken.get(type)))
}
override fun requestBodyConverter(type: Type, parameterAnnotations: Array<out Annotation>, methodAnnotations: Array<out Annotation>,
retrofit: Retrofit?): Converter<*, RequestBody>? {
return RequestBodyConverter()
}
}
class GsonResponseBodyConverter(private val gson: Gson, private val adapter: TypeAdapter<out Any>) : Converter<ResponseBody, Any> {
override fun convert(value: ResponseBody): Any {
val jsonReader = gson.newJsonReader(value.charStream())
try {
return adapter.read(jsonReader)
} finally {
value.close()
}
}
}
class RequestBodyConverter : Converter<File, RequestBody> {
override fun convert(value: File): RequestBody {
return CountingFileRequestBody(value, "application/*", { })
}
}