Saya seorang pengembang Android dan saya tidak ingin melakukan pekerjaan manual.

Ketika saya menetap di Skyeng, matahari bersinar sedikit lebih terang, rumput tidak lebih hijau (itu adalah awal musim semi yang sama), dan pemimpin tim meminta saya untuk menulis kepada Jira berapa banyak waktu yang dihabiskan untuk pengkodean, dan berapa banyak bicara dan ulasan. Setidaknya sekali setiap dua minggu.


"Berdasarkan data ini, kami berusaha memahami apakah perlu untuk menyesuaikan estimasi dan apakah ada masalah dalam komunikasi dalam tim," kata mereka. Tapi siapa "babayka" seperti itu tidak pernah diberi tahu. .

Karena kita semua pekerja jarak jauh, ide itu terdengar masuk akal. Dan menarik bagi saya ke mana delapan jam ini telah berlalu: di sini mereka, tetapi untuk apa sebenarnya? Namun, penebangan tidak biasa. Dan secara umum kemalasan. Kemudian saya memutuskan untuk mencari sesuatu yang akan terus bekerja untuk saya. Dan dalam proses penelitian, saya sedikit terhanyut dan menulis plugin untuk IntelliJ IDEA.

Di bawah ini Anda akan menemukanUlasan subjektif alat jadi dan sepeda saya (dengan sumber).

Saya mempelajari solusi yang digunakan tim


Hal pertama yang saya lakukan adalah mencari tahu dari rekan saya yang menggunakan apa. Opsinya kira-kira sebagai berikut:

1. Clockify - satu tombol untuk mengatur segalanya


Apakah Anda perlu waktu untuk menulis kode atau menulis dok? Plugin ini akan menambahkan tombol (pacman abu-abu yang cukup mencolok) hampir di mana saja.


Jadi itu terlihat di Google Documents


Dan di GitHub

Anda dapat mengagumi Natrekannyi di dasbor, atau Anda dapat mengimpor ke dalam sebuah tabel dan menjatuhkannya ke Jira.


Integrasi ke Jira disediakan secara terpisah, juga oleh ekstensi browser.

Namun, dimungkinkan untuk mengunggah tabel dengan worklog yang diperoleh dari Clockify ke kalender kerja Anda. Dan untuk pelacakan waktu offline ada aplikasi desktop untuk windows, linux dan mac. Aplikasi seluler juga. Fungsionalitas utamanya adalah gratis, tetapi ada beberapa paket tarif dengan barang seperti privasi, pengingat dan template untuk proyek.

2. Beralih , hanya Beralih


Semuanya hampir sama, tetapi sedikit lebih banyak barang - misalnya, dalam aplikasi desktop, Anda dapat mengatur sendiri pengingat tentang pencatatan waktu, nyalakan mode pomodoro, bahkan ada peluang untuk menautkan aplikasi tertentu ke proyek tertentu dan mengatur pelacakan otomatis.


Tetapi ada nuansa: pada hari pertama penggunaan saya kagum dengan jendela ini dan pemberitahuan dengan pengingat. Meskipun teorinya terdengar keren)

3. Toggl + Python script : ketika hanya satu tombol tidak lagi cukup


Penemuan rekan saya. Entah bagaimana, dia memutuskan untuk mengurangi isyarat untuk mengekspor tabel ke Jira dan menggeser pembongkaran pajak di Toggl ke sebuah skrip. Anda bisa memasukkan cron dan menikmati hidup.

4. Wakatime - kemana kita pergi, tidak perlu tombol


Mencatat semuanya sendiri. Karena itu, hal pertama yang harus diingat ketika menghubungkan ekstensi browsernya adalah daftar hitam.

Selain ekstensi, ia menyediakan beberapa integrasi dan jumlah plugin yang layak untuk IDE dan editor yang paling umum.


Plugin untuk IDE melacak waktu yang dihabiskan baik dalam cabang git tertentu dan dalam file tertentu. Di layar, daftar yang tersedia sangat mengesankan. Serenyk - “dalam rencana”, untuk implementasi cepatnya, Anda dapat memilih. Beberapa plugin dalam langganan berbayar sebesar $ 9 per bulan.

Selain itu, di dasbor, Anda dapat melihat berapa banyak waktu yang dihabiskan sebagai persentase untuk menulis kode dalam bahasa yang berbeda: jika Anda ingat bahwa proyek android biasa melibatkan penggunaan Kotlin, Java, Groovy dan xml - ini masuk akal untuk dirinya sendiri). Dan jika Anda bekerja dengan plugin yang diinstal untuk sementara waktu, Anda akan melihat bahwa itu agak kejam: dasbor mendapatkan waktu membaca dan menulis kode aktif. Dan menempel tidak masuk ke monitor dengan tampilan kaca. Tak perlu dikatakan, seorang amatir.

Hmm, kode sumber untuk WakaTime terbuka: Anda dapat mencoba memahami cara kerjanya ...
, ? IDE JetBrains.

. WakaTime.java. , , Heartbeat (), WakaTime CLI . , , , .

Menulis sepeda Anda dengan analogi


Mungkin senjata kentang akan lebih berguna, tetapi Anda tidak akan melakukan apa pun untuk tujuan penelitian. Setelah bermeditasi pada sumber-sumber WakaTime, saya memutuskan untuk membuat plug-in saya sendiri yang dapat melacak aktivitas dalam IDE, mencatat waktu untuk menulis, dan mengirimkan semuanya ke Jira (dalam aliran kami, cabang diberi nama setelah tugas di Jira, sehingga terlihat cukup realistis).

Dan agar tidak memenuhi permintaan server saat mengerjakan kode, kami akan mengirimkan log ketika Android Studio ditutup, dan sampai saat ini menyimpannya secara lokal.

1. Entitas apa yang dapat kita temukan dalam kode sumber plugin (dan digunakan dalam milik kita sendiri)?


Kami tidak menggunakan Komponen (ini adalah Legacy ) , yang sebelumnya merupakan unit struktural utama dari plugin. Mungkin level aplikasi, level proyek, atau level modul. Ada ApplicationComponent di sumber WakaTime, tetapi mereka bisa, kode sumber sudah berusia lima tahun dan harus mempertahankan kompatibilitas ke belakang. Komponen terkait dengan siklus hidup tingkat yang terkait. Jadi, misalnya, ApplicationComponent dimuat ketika IDE dimulai. Ketika digunakan, mereka akan memblokir plugin dari memulai kembali tanpa me-restart IDE dan umumnya berperilaku tidak menyenangkan. Karena itu, lebih baik menggunakan layanan saja.

Kami menggunakan Layanan- unit struktural utama saat ini. Mereka dibagi ke dalam level aplikasi, proyek, dan modul yang sama, membantu kami merangkum logika pada level yang sesuai dan menyimpan status plugin.

Tidak seperti komponen, Layanan harus dimuat sendiri menggunakan metode ServiceManager.getService (). Platform ini memastikan bahwa setiap layanan adalah layanan tunggal.

Add Actions - mereka bisa berupa jalan pintas, item menu tambahan - dalam satu kata, mereka bertanggung jawab atas segala sesuatu yang entah bagaimana memengaruhi tindakan pengguna dalam IDE.

Kami menggunakan Ekstensi - setiap ekstensi fungsi yang akan lebih rumit daripada Tindakan: misalnya, terhubung ke siklus hidup IDE dan melakukan sesuatu sambil menampilkan layar splash atau sebelum keluar.

Semua ini harus dideklarasikan di file /META_INF/plugin.xml.

2. Plugin.xml dan build.gradle



Jendela pembuatan proyek. Kami akan menulis plugin kami di Kotlin, dan menggunakan Gradle untuk perakitan.

Ini adalah hal pertama yang kami lihat setelah membuat plugin kosong di IDEA (File -> New -> Project ... -> Gradle -> Plugin Platform IntelliJ). Ini berisi informasi tentang dependensi plugin dan deskripsi singkatnya. Ini harus mendeklarasikan komponen plug-in - komponen, layanan, tindakan, dan ekstensi yang disebutkan sebelumnya. Tidak akan ada titik masuk khusus - itu akan menjadi tindakan kustom atau peristiwa siklus hidup IDE, tergantung pada kebutuhan kita.

Kami akan memerlukan dependensi ini - lagipula, kami ingin menulis sebuah plugin untuk studio dan agar dapat bekerja dengan Git.

<depends>Git4Idea</depends>
<depends>com.intellij.modules.androidstudio</depends>

Git4Idea adalah plug-in untuk sistem file virtual (VCS) dan menyediakan topik, berkat yang nantinya kita bisa mendengarkan acara git - seperti checkout, misalnya.

Karena kami juga menginginkan plugin untuk dapat bekerja dengan Jira, kami akan menghubungkan melalui gradle perpustakaan yang disediakan dengan klien lain. Untuk melakukan ini, tambahkan repositori maven Atlassian di sana:

repositories {
   mavenCentral()
   maven {
       url "https://packages.atlassian.com/maven/repository/public"
   }
}

Dan sebenarnya perpustakaan:

implementation "joda-time:joda-time:2.10.4"
implementation("com.atlassian.jira:jira-rest-java-client-core:4.0.0") {
   exclude group: 'org.slf4j'
   dependencies {
       implementation "com.atlassian.fugue:fugue:2.6.1"
   }
}

Di sini kami menentukan versi IDE yang menarik bagi kami dan jalurnya (oh, jika Android Studio yang sebenarnya dimulai dan bekerja secepat versi ringan untuk debugging plugins):

intellij {
   version '2019.1'
   plugins 'git4idea'
   alternativeIdePath 'E:\\Android Studio'
}

Dan di sini, mungkin, suatu hari nanti kita akan menulis tentang fungsionalitas baru yang ditingkatkan. Tapi tidak sekarang.

patchPluginXml {
   changeNotes """
     Add change notes here.<br>
     <em>most HTML tags may be used</em>"""
}

3. Membuat UI


Untuk mendorong sesuatu ke Jira, Anda harus masuk terlebih dahulu. Adalah logis untuk melakukan ini segera setelah pembukaan proyek. Sepertinya kami memerlukan ekstensi, dan kami tidak akan ragu untuk menyatakannya di plugin.xml:

<postStartupActivity implementation="Heartbeat"/>

dan tunjukkan dialog di dalamnya.

Komponen UI terutama adalah komponen dari Swing dengan beberapa ekstensi dari platform SDK. Semua ini baru saja dibungkus dengan kotlin ui dsl. Pada saat penulisan, dokumentasi mencatat bahwa dsl dapat berubah sangat banyak antara versi utama, jadi kami menggunakannya dengan sedikit rasa takut:


override fun createCenterPanel(): JComponent? {

   title = "Jira credentials"
   setOKButtonText("Save")

   return panel {
       row {
           JLabel("Jira hostname")()
           hostname = JTextField("https://")
           hostname()
       }
       row {
           JLabel("Username:")()
           username = JTextField()
           username()
       }
       row {
           JLabel("Password:")()
           password = JPasswordField()
           password()
       }
   }
}

Kami membuat dialog, menunjukkannya, menerima kredensial dari Jira. Sekarang kita perlu menyelamatkan mereka, dan lebih baik dengan aman, sebanyak mungkin. PersistingStateComponent akan datang untuk menyelamatkan.

4. Perangkat PersistingStateComponent (tidak terlalu rumit)


PersistingStateComponent dapat melakukan dua hal - saveState dan loadState: membuat serial dan menyimpan objek yang diteruskan ke sana dan mengambilnya dari penyimpanan.

Di mana tepatnya ia harus menyimpan data, ia belajar dari penjelasan Negara. Dua opsi paling sederhana disebutkan dalam dokumentasi - tentukan file Anda atau simpan semuanya dalam pengaturan ruang kerja:

@Storage("yourName.xml")
@Storage(StoragePathMacros.WORKSPACE_FILE) 
@State(
   name = "JiraSettings",
   storages = [
       Storage("trackerSettings.xml")
   ])

Karena kami memiliki kasus khusus, kami beralih ke dokumentasi untuk penyimpanan data sensitif.

override fun getState(): Credentials? {
   if (credentials == null)  {
       val credentialAttributes = createCredentialAttributes()
       credentials = PasswordSafe.instance.get(credentialAttributes)
   }
   return credentials
}
override fun loadState(state: Credentials) {
   credentials = state
   val credentialAttributes = createCredentialAttributes()
   PasswordSafe.instance.set(credentialAttributes, credentials)
}

PersistingStateComponent lain akan berhadapan dengan penyimpanan waktu yang dicatat untuk cabang yang berbeda.

Jira menemukan login. Dengan penyimpanan data pengguna juga. Sekarang Anda perlu melacak acara checkout di cabang untuk memulai hitungan mundur.

5. Berlangganan acara


IntelliJ Platform memberikan kesempatan untuk menggantung Pengamat pada acara yang menarik bagi kami dengan berlangganan topik mereka di messageBus dari tingkat yang diinginkan. Ini dok , ini cukup menarik.

Topik adalah titik akhir tertentu, representasi dari suatu peristiwa. Yang perlu Anda lakukan hanyalah berlangganan dan laksanakan pendengar yang harus menangani apa yang terjadi.

Misalnya, saya perlu mendengarkan checkout di Git ...

subscribeToProjectTopic(project, GitRepository.GIT_REPO_CHANGE) {
    GitRepositoryChangeListener {
        currentBranch = it.currentBranch
    }
}

... menutup aplikasi (untuk menggadaikan waktu bahagia) ...

subscribeToAppTopic(AppLifecycleListener.TOPIC) {
    object: AppLifecycleListener {
        override fun appWillBeClosed(isRestart: Boolean) {
            if (!isRestart) {
                JiraClient.logTime(entry.key, DateTime.now(), entry.value)
            }
        }
    }
}

... dan menyimpan dokumen (hanya itu saja).

subscribeToAppTopic(AppTopics.FILE_DOCUMENT_SYNC) {
    CustomSaveListener()
}

Ini, pada prinsipnya, sudah cukup (jika tidak, Anda selalu dapat menulis sendiri). Tetapi bagaimana jika kita ingin mendengar sedikit gulir dan gerakan mouse?

6. EditorEventMulticaster


Ini mengumpulkan semua yang terjadi di jendela editor terbuka - mengedit, mengubah area yang terlihat, gerakan mouse - dan memungkinkan Anda untuk berlangganan di satu tempat dan segera.

Sekarang kami memiliki semua yang kami butuhkan. Kita dapat mengekstrak nama tugas di Jira dari cabang saat ini (jika ada), menghitung waktu yang dihabiskan untuk mengerjakannya, dan segera keluar dari studio untuk menambahkannya ke tugas.

7. Kode dan detail di sini


Untuk menjalankannya, Anda memerlukan Android Studio terbaru (3.6.1).
Untuk menguji kinerja - git dan cabang dengan nama yang setidaknya mirip dengan tugas di Jira.
Sehingga plugin tidak hanya menampilkan waktu ke konsol, tetapi melacaknya - batalkan komentar pada baris yang sesuai di Heartbeat.kt.

8. Tautan yang bermanfaat



PS Dan apa yang Anda pilih pada akhirnya?


- Sial, ini agak terlalu jahat. Dan jika saya tidak menulis kode? Dan jika saya mengambil hidung saya dan berusaha keras untuk memahami apa yang terjadi di dalamnya? Dalam kode, dalam arti. Bagaimanapun, ini membutuhkan sebagian besar waktu.

- Lalu setidaknya gulir.

- Jadi tidak jauh dari simulasi aktivitas kekerasan. Dan kemudian, saya tidak bisa mematikan studio selama berminggu-minggu dan tidak me-reboot. Mungkin kita tidak membutuhkan kebahagiaan seperti itu?

"Jelas tidak perlu." Maka diperlukan alasan lain, kalau tidak saya suka menulis plugin. Dan saya masih tidak terlalu mengerti VCS.

"Apakah kamu menggunakannya sendiri?"

- Tidak. Saya entah bagaimana belajar log dengan tangan saya, tanpa terasa bagi diri saya sendiri.

All Articles