Mencegah kompilasi kode usang setelah mencapai tenggat waktu [ditutup]

68

Di tim saya, kami telah membersihkan banyak barang lama dalam proyek monolitik besar (seluruh kelas, metode, dll.).

Selama tugas pembersihan itu saya bertanya-tanya apakah ada semacam anotasi atau perpustakaan yang lebih bagus dari biasanya @Deprecated. Ini @FancyDeprecatedharus mencegah pembangunan proyek dari berhasil jika Anda belum membersihkan kode lama yang tidak digunakan setelah tanggal tertentu berlalu.

Saya telah mencari di internet dan tidak menemukan apa pun yang memiliki kemampuan yang dijelaskan di bawah ini:

  • harus berupa anotasi, atau sesuatu yang serupa, untuk dimasukkan ke dalam kode yang Anda ingin hapus sebelum tanggal tertentu
  • sebelum tanggal itu kode akan dikompilasi dan semuanya akan bekerja secara normal
  • setelah tanggal itu kode tidak akan dikompilasi dan itu akan memberi Anda pesan yang memperingatkan Anda tentang masalah tersebut

Saya rasa saya sedang mencari unicorn ... Apakah ada teknologi serupa untuk bahasa program apa pun?

Sebagai rencana, BI sedang memikirkan kemungkinan membuat keajaiban dengan beberapa unit test kode yang dimaksudkan untuk dihapus yang mulai gagal pada "batas waktu". Apa yang Anda pikirkan tentang ini? Ada ide yang lebih baik?

Arcones
sumber
168
Penghentian dilakukan untuk suatu versi , bukan tanggal . Jika Anda ingin orang berhenti menggunakan fitur-fitur usang, lepaskan versi tanpa mereka. Itu akan menarik perhatian mereka, dan mereka selalu bisa mundur jika mereka belum bisa melakukannya. Banyak orang terjebak pada versi lama. Menghentikan program mereka bukanlah jalan yang harus ditempuh.
isanae
4
Plan B terdengar solid. Dengan keuntungan tambahan yang dapat Anda berikan komentar di unit test mengapa itu sudah usang. Menambahkan komentar ke kode sumber tidak akan membantu keterbacaan dalam monolit besar
dwana
53
Itu terdengar seperti unicorn yang benar-benar jahat. Anda memiliki sedikit perangkat lunak yang mengkompilasi dengan baik, melewati semua tes, dan Anda telah mengirimkannya ke pelanggan. Lalu suatu hari, Anda memeriksa perangkat lunak lagi dan itu tidak akan membangun, bahkan pada platform pengembangan yang sama persis. Anda sekarang dipaksa untuk memodifikasi kode yang sebelumnya lulus pengujian formal, atau melakukan peretasan jahat seperti memutar kembali jam komputer.
Simon B
6
Buatlah @ Deprecated_RemoveMe_2018_06_01 dan kemudian pada 2018-06-01 hapus anotasi itu sendiri. Voila, semua kode Anda menggunakan anotasi tidak akan lagi dikompilasi! (karena anotasi tidak ditemukan)
user253751
65
Bertahun-tahun di masa depan, pengembang yang baru direkrut akan bertanya: mengapa waktu pada server build diatur ke Januari 2016? Dan pria yang ada di sana selama 10 tahun akan memberitahunya bahwa itu perlu atau bangunannya rusak secara acak. Mendesah.
Wilbert

Jawaban:

62

Saya tidak berpikir ini akan menjadi fitur yang berguna ketika itu benar-benar melarang kompilasi. Ketika pada 01/06/2018 sebagian besar kode tidak akan mengkompilasi yang dikompilasi sehari sebelumnya, tim Anda akan dengan cepat menghapus anotasi itu lagi, kode dibersihkan atau tidak.

Namun, Anda dapat menambahkan beberapa anotasi khusus ke kode seperti

@Deprecated_after_2018_07_31

dan buat alat kecil untuk memindai anotasi tersebut. (Satu liner sederhana dalam grep akan melakukannya, jika Anda tidak ingin menggunakan refleksi). Dalam bahasa lain selain Jawa, komentar standar yang cocok untuk "grepping", atau definisi preprosesor dapat digunakan.

Kemudian jalankan alat itu sesaat sebelum atau setelah tanggal tertentu, dan jika masih menemukan anotasi itu, ingatkan tim untuk segera membersihkan bagian kode tersebut.

Doc Brown
sumber
9
@Bergi: hei, ini hanya contoh, OP dapat menggunakan versi atau tag tanggal, apa pun yang mereka sukai dalam kendali mereka.
Doc Brown
4
Saya tidak melihat adanya keuntungan untuk melakukan ini hanya dengan menggunakan fitur-fitur penghentian normal dan melihat output kompiler pada tanggal tertentu. Sepertinya penggunaan waktu pengembang yang buruk untuk mengimplementasikan kembali sesuatu yang sudah ada. Sekalipun Anda sudah mendapatkan satu ton peringatan (yang akan layak untuk Anda selesaikan), pasti Anda dapat meminta kompiler meludahkan semua peringatan ke file teks dan kemudian ambil atau cari.
jpmc26
4
@ jpaugh Saya merekomendasikan untuk tidak tenggelam dalam waktu (catatan, waktu = uang) untuk membangun alat baru untuk melakukan tugas yang sudah dapat Anda lakukan secara efisien dengan alat yang ada, apa pun alat itu.
jpmc26
3
@ jpmc26: Saya melihat dua keuntungan (kecil): tidak mendapatkan ton peringatan penghentian (yang akan menimbulkan risiko mengabaikan yang lebih penting), dan kemungkinan memperkenalkan kriteria penghentian yang berbeda (tanggal, versi, apa pun) untuk bagian kode yang berbeda. Selain itu, OP secara eksplisit meminta penggabungan penghentian dengan suatu tanggal.
Doc Brown
7
Saya akan memberi +1 jika Anda hanya akan menggunakan pesanan YYYY-MM-DD untuk tanggal dalam contoh Anda, karena saya hanya pernah melihat ambigu ?? - ?? - YYYY order menyebabkan rasa sakit dan kesalahpahaman.
mtraceur
284

Ini akan menjadi fitur yang dikenal sebagai bom waktu . JANGAN BUAT BOM WAKTU.

Kode, tidak peduli seberapa baik Anda menyusun dan mendokumentasikannya, akan berubah menjadi kotak hitam hampir-mitos yang tidak dipahami jika ia hidup di luar usia tertentu. Hal terakhir siapa pun di masa depan kebutuhan adalah satu lagi modus kegagalan aneh yang menangkap mereka benar-benar terkejut, pada saat kemungkinan terburuk, dan tanpa obat yang jelas. Sama sekali tidak ada alasan untuk secara sengaja menghasilkan masalah seperti itu.

Lihatlah dengan cara ini: jika Anda terorganisir dan menyadari basis kode Anda cukup bahwa Anda peduli tentang usang dan menindaklanjutinya, maka Anda tidak perlu mekanisme dalam kode untuk mengingatkan Anda. Jika tidak, kemungkinan Anda juga tidak mengetahui aspek-aspek lain dari basis kode, dan mungkin tidak akan dapat merespons alarm tepat waktu dan dengan benar. Dengan kata lain, bom waktu tidak memiliki tujuan yang baik bagi siapa pun. Katakan saja tidak!

Kilian Foth
sumber
74
+1 Ini akan menggigit Anda. Beberapa bulan kemudian. Pada hari Jumat sama seperti Anda sedang mencoba melakukan penyebaran darurat. Dan ini akhir pekan yang panjang, jadi semua orang yang tahu tentang itu ada di luar kantor. Jangan lakukan itu.
Roger Lipscombe
3
Setuju. Usang adalah masalah organisasi, bukan masalah pengkodean. Saya masih bisa memasang Apple] [dan menulis BASIC, tidak ada yang menghentikan saya. Tetapi, apakah saya mau ?
19
Solusi yang tepat, sesuai dengan arahan "terorganisir dan sadar" Anda, adalah meningkatkan bug di sistem pelacakan bug Anda, dengan mengatakan "Hapus <ini dan itu>", dengan kerangka waktu yang disarankan di komentar. Dan kemudian dalam 6 bulan ketika ulasan bug muncul untuk mencari tahu bug apa yang harus diperbaiki pada rilis berikutnya, jika jangka waktu itu sudah dekat, Anda mengatakan "saatnya untuk melakukan bug ini". Ini manajemen proyek dasar.
Lightness Races dengan Monica
1
Bahkan, jika jadwal rilis Anda cukup dapat diprediksi, cukup tonggak saja sekarang.
Lightness Races dengan Monica
13
Lihat komentar isanae untuk alternatif: " Jika Anda ingin orang berhenti menggunakan fitur-fitur usang, lepaskan versi tanpa mereka. Itu akan menarik perhatian mereka, dan mereka selalu dapat memutar kembali jika mereka belum bisa melakukannya. "
Stevoisiak
70

Dalam C # Anda akan menggunakan ObsoleteAttributecara berikut:

  • Di versi 1, Anda mengirim fitur. Metode, kelas, apa pun.
  • Di versi 2, Anda mengirim fitur yang lebih baik yang dimaksudkan untuk menggantikan fitur aslinya. Anda meletakkan atribut Usang pada fitur, set ke "peringatan", dan berikan pesan yang mengatakan "Fitur ini sudah usang. Gunakan fitur yang lebih baik. Dalam versi 3 dari perpustakaan ini, yang akan dirilis pada ini dan itu tanggal, penggunaan fitur ini akan menjadi kesalahan. " Sekarang pengguna fitur masih dapat menggunakannya, tetapi punya waktu untuk memperbarui kode mereka untuk menggunakan fitur baru.
  • Di versi 3, Anda memperbarui atribut menjadi kesalahan daripada peringatan, dan memperbarui pesan untuk mengatakan "Fitur ini sudah usang. Gunakan fitur yang lebih baik. Dalam versi 4 dari perpustakaan ini, yang akan dirilis pada ini dan itu tanggal, fitur ini akan melempar. " Pengguna yang gagal memperhatikan peringatan Anda sebelumnya masih mendapatkan pesan bermanfaat yang memberitahu mereka cara memperbaiki masalah, dan mereka harus memperbaikinya, karena sekarang kode mereka tidak dapat dikompilasi.
  • Di versi 4, Anda mengubah fitur sehingga melemparkan beberapa pengecualian fatal, dan mengubah pesan untuk mengatakan bahwa fitur tersebut akan dihapus sepenuhnya di versi berikutnya.
  • Di versi 5, Anda menghapus fitur sepenuhnya, dan jika pengguna mengeluh, baik hei, Anda memberi mereka tiga siklus rilis peringatan yang adil, dan mereka selalu dapat terus menggunakan versi 2 jika mereka merasa sangat menyukainya.

Idenya di sini adalah untuk membuat perubahan melanggar tanpa rasa sakit mungkin bagi pengguna yang terkena dampak, dan untuk memastikan bahwa mereka dapat terus menggunakan fitur untuk setidaknya satu versi perpustakaan.

Eric Lippert
sumber
2
Saya percaya ini adalah pendekatan yang benar tetapi saya akan mengubah satu hal ... yang akan bertukar "jika pengguna mengeluh" menjadi "ketika pengguna mengeluh"
Liath
10
Menghapus tubuh pada saat yang sama dengan mengubah kesalahan tampaknya aneh. Salah satu kelebihan dari versi kesalahan yang ditinggalkan, adalah bahwa hal itu memungkinkan kode yang dibangun terhadap versi sebelumnya untuk terus berfungsi sambil mencegah kode yang baru dikompilasi dari menggunakannya. Dengan demikian Anda tetap kompatibel dengan ABI, sambil dengan sengaja merusak kompatibilitas API. Tentu saja dunia yang sempurna Anda akan memiliki versi semver style, dll, sehingga Anda tidak akan pernah menjalankan kode baru dengan aplikasi yang sebelumnya dikompilasi, tetapi banyak proyek tidak pernah mencapai yang ideal.
Kevin Cathcart
@KevinCathcart: Itu poin yang bagus; mungkin tahap lain di sana dijamin! Saya akan memperbarui teks.
Eric Lippert
1
Sebenarnya, jika Anda melakukan SemVer, Anda bisa langsung dari yang sudah usang di versi XY0 (setiap penghentian harus menjadi rilis kecil) untuk sepenuhnya dihapus di X + 1.0.0. Saya akan mengatakan itu bagus untuk menunda sedikit lebih jauh, (untuk X + 2.0.0?), Tapi proses lima langkah ini mungkin penyepuhan lily. Langkah selanjutnya setelah "peringatan" harus menjadi "kesalahan fatal" (karena fitur yang sudah usang diganti dengan kode penghasil kesalahan). Karena libfoo.so.2dan libfoo.so.3dapat hidup berdampingan satu sama lain dengan baik, hilir Anda dapat terus menggunakan perpustakaan lama sampai mereka dialihkan.
Monty Harder
@MontyHarder: Tentu. Urutan kejadian yang tepat dapat ditentukan oleh kebutuhan pengembang dan komunitas penggunanya. Poin yang lebih besar adalah bahwa harus ada kebijakan yang matang untuk menangani masalah-masalah versi yang jelas-jelas dikomunikasikan kepada para pemangku kepentingan.
Eric Lippert
24

Anda salah mengerti apa arti "usang". Berarti usang:

dapat digunakan tetapi dianggap usang dan sebaiknya dihindari, biasanya karena telah digantikan.

Kamus Oxford

Menurut definisi, fitur usang masih akan dikompilasi.

Anda ingin menghapus fitur pada tanggal tertentu. Tidak apa-apa. Cara Anda melakukannya adalah menghapusnya pada tanggal itu .

Sampai saat itu, tandai sebagai usang, usang, atau apa pun bahasa pemrograman Anda menyebutnya. Dalam pesan, sertakan tanggal itu akan dihapus dan hal yang menggantikannya. Ini akan menghasilkan peringatan, menunjukkan bahwa pengembang lain harus menghindari penggunaan baru dan harus mengganti penggunaan lama sedapat mungkin. Pengembang itu akan mematuhi atau mengabaikannya, dan seseorang harus berurusan dengan konsekuensi ketika dihapus. (Tergantung situasinya, mungkin Anda atau pengembang yang menggunakannya.)

jpmc26
sumber
Tertarik dengan apa yang tidak disetujui oleh downvoter.
jpmc26
2
+1. Jika Anda menggunakan JIRA untuk pengembangan tangkas, buat tugas dan letakkan di sprint masa depan; beradaptasi untuk apa pun alat dan metodologi manajemen proyek apa pun yang Anda ikuti. Ini paling baik diselesaikan dengan metode non-teknis.
Matius Baca
1
Dan juga pastikan Kelas / Lib tetap dalam dokumentasi sebagai didepresiasi dan / atau dihapus dalam versi Xx
Phil M
12

Jangan lupa bahwa Anda perlu mempertahankan kemampuan untuk membangun dan men-debug versi kode yang lebih lama untuk mendukung versi perangkat lunak yang telah dirilis. Menyabotase bangunan setelah tanggal tertentu berarti Anda juga berisiko mencegah diri Anda melakukan pemeliharaan dan dukungan yang sah di masa depan.

Selain itu, sepertinya solusi sepele untuk mengatur jam mesin saya kembali satu atau dua tahun sebelum dikompilasi.

Ingat, "usang" adalah peringatan bahwa sesuatu akan hilang di masa depan. Saat Anda ingin secara paksa mencegah orang menggunakan API itu, hapus saja kode yang terkait . Tidak ada gunanya meninggalkan kode di basis kode jika beberapa mekanisme membuatnya tidak dapat digunakan. Menghapus kode memberi Anda waktu kompilasi pemeriksaan yang Anda cari, dan tidak memiliki solusi sepele.

Sunting: Saya melihat Anda merujuk ke "kode lama yang tidak digunakan" dalam pertanyaan Anda. Jika kode tersebut benar-benar tidak digunakan , tidak ada gunanya mencabutnya. Hapus saja.

bta
sumber
Jawaban terbaik sejauh ini, mungkin menekankan bahwa menghapus kode adalah cara terbaik untuk menyelesaikan masalah lebih cepat dalam jawaban Anda. Mudah untuk menggulir melewati jawaban dinding teks
Clint
6

Saya belum pernah melihat fitur seperti itu sebelumnya - sebuah anotasi yang mulai berlaku setelah tanggal tertentu.

The @Deprecateddapat cukup, namun. Menangkap peringatan dalam CI, dan membuatnya menolak untuk menerima bangunan jika ada. Ini mengalihkan tanggung jawab dari kompiler ke pipeline build Anda, tetapi memiliki keuntungan bahwa Anda dapat (semi) dengan mudah mengubah pipeline build dengan menambahkan langkah-langkah tambahan.

Perhatikan bahwa jawaban ini tidak sepenuhnya menyelesaikan masalah Anda (mis. Pengembangan lokal di atas mesin pengembang masih akan berhasil, meskipun dengan peringatan) dan mengasumsikan bahwa Anda telah menyiapkan dan menjalankan pipa CI.

Mael
sumber
4

Anda mencari kalender atau daftar agenda .

Alternatif lain adalah dengan menggunakan peringatan kompiler khusus atau pesan kompiler, jika Anda berhasil memiliki sedikit jika ada peringatan dalam basis kode Anda. Jika Anda memiliki terlalu banyak peringatan, Anda harus menghabiskan upaya tambahan (sekitar 15 menit?) Dan harus mengambil peringatan kompiler dalam laporan pembangunan yang diberikan integrasi berkelanjutan Anda pada setiap bangunan.

Pengingat bahwa kode perlu diperbaiki adalah baik dan perlu. Kadang-kadang pengingat ini memiliki tenggat waktu dunia nyata yang ketat, jadi meletakkannya di penghitung waktu mungkin juga diperlukan.

Tujuannya adalah untuk terus-menerus mengingatkan orang bahwa masalah itu ada dan perlu diperbaiki dengan jangka waktu tertentu - fitur yang hanya memecah build pada waktu tertentu tidak hanya tidak melakukan itu, tetapi fitur itu sendiri merupakan masalah yang perlu diperbaiki dengan jangka waktu tertentu.

Peter
sumber
1
Setuju. Tetapi jika ada masalah dan perlu diperbaiki dalam jangka waktu tertentu, maka itu harus menjadi prioritas utama seseorang pada waktu yang tepat. Saya ingat ketika dalam rapat Manajer saya memberi saya "prioritas utama", kemudian berkata, " Ini prioritas nomor satu Anda" (sesuatu yang berbeda). Atasan saya berkata, "Dia tidak dapat memiliki prioritas nomor dua !" Manajer itu terkejut. Kurasa dia mengira ... aku bisa. Merencanakan sesuatu untuk diperbaiki "pada waktu yang tepat" adalah perencanaan untuk kehabisan waktu.
3

Salah satu cara untuk berpikir tentang ini adalah apa yang Anda maksud dengan waktu / tanggal ? Komputer tidak tahu apa konsep-konsep ini: mereka harus diprogram dalam cara apa pun. Ini cukup umum untuk merepresentasikan waktu dalam format UNIX "detik sejak zaman", dan itu umum untuk memasukkan nilai tertentu ke dalam program melalui panggilan OS. Namun, tidak peduli seberapa umum penggunaan ini, penting untuk diingat bahwa ini bukan waktu "aktual": ini hanya representasi logis.

Seperti yang orang lain tunjukkan, jika Anda membuat "tenggat waktu" menggunakan mekanisme ini, itu sepele untuk memberi makan di waktu yang berbeda dan memutus "tenggat waktu" itu. Hal yang sama berlaku untuk mekanisme yang lebih rumit seperti meminta server NTP (bahkan melalui koneksi "aman", karena kami dapat mengganti sertifikat kami sendiri, otoritas sertifikat atau bahkan menambal perpustakaan crypto). Pada awalnya mungkin terlihat bahwa orang-orang tersebut bersalah karena bekerja di sekitar mekanisme Anda, tetapi mungkin itu terjadi secara otomatis dan untuk alasan yang baik . Sebagai contoh, adalah ide yang baik untuk membuat build yang dapat direproduksi , dan alat untuk membantu hal ini dapat secara otomatis mereset / mencegat panggilan sistem non-deterministik tersebut. Libibaketime melakukan hal itu,menyetel semua stempel waktu file ke 1970-01-01 00:00:01, fitur record / replay Qemu memalsukan semua interaksi perangkat keras, dll.

Ini mirip dengan hukum Goodhart : jika Anda membuat perilaku program bergantung pada waktu logis, maka waktu logis berhenti menjadi ukuran yang baik dari waktu "aktual". Dengan kata lain, orang pada umumnya tidak akan mengacaukan jam sistem, tetapi mereka akan melakukannya jika Anda memberi mereka alasan.

Ada representasi waktu logis lainnya: salah satunya adalah versi perangkat lunak (baik aplikasi Anda atau ketergantungan). Ini adalah representasi yang lebih diinginkan untuk "tenggat waktu" daripada misalnya waktu UNIX, karena itu lebih spesifik untuk hal yang Anda pedulikan (mengubah set fitur / API) dan karenanya cenderung menginjak-injak masalah ortogonal (misalnya mengutak-atik waktu UNIX untuk mengatasi batas waktu Anda bisa berakhir dengan memecah file log, tugas cron, cache, dll.).

Seperti yang dikatakan orang lain, jika Anda mengontrol perpustakaan dan ingin "mendorong" perubahan ini, Anda dapat mendorong versi baru yang mencemari fitur (menyebabkan peringatan, untuk membantu konsumen menemukan dan memperbarui penggunaannya), lalu versi baru lainnya yang menghilangkan fitur sepenuhnya. Anda dapat mempublikasikan ini segera setelah satu sama lain jika Anda suka, karena (lagi) versi hanyalah representasi waktu yang logis, mereka tidak perlu terkait dengan waktu "aktual". Versi semantik dapat membantu di sini.

Model alternatif adalah "menarik" perubahan. Ini seperti "paket B" Anda: tambahkan tes ke aplikasi yang menggunakan, yang memeriksa bahwa versi ketergantungan ini setidaknya nilai baru. Seperti biasa, merah / hijau / refactor untuk menyebarkan perubahan ini melalui basis kode. Ini mungkin lebih tepat jika fungsi tidak "buruk" atau "salah", tetapi hanya "cocok untuk kasus penggunaan ini".

Pertanyaan penting dengan pendekatan "tarikan" adalah apakah versi ketergantungan dihitung sebagai "unit" ( fungsionalitas ), dan karenanya layak untuk diuji; atau apakah itu hanya detail implementasi "pribadi", yang seharusnya hanya dilakukan sebagai bagian dari tes unit ( fungsionalitas ) yang sebenarnya. Saya akan mengatakan: jika perbedaan antara versi dependensi benar-benar dihitung sebagai fitur aplikasi Anda, maka lakukan tes (misalnya, memeriksa bahwa versi Python>> = 3.x). Jika tidak, maka jangantambahkan tes (karena akan rapuh, tidak informatif dan terlalu membatasi); jika Anda mengontrol perpustakaan maka turunkan rute "push". Jika Anda tidak mengontrol perpustakaan maka gunakan saja versi apa pun yang disediakan: jika tes Anda lulus maka tidak layak membatasi diri Anda; jika mereka tidak lulus maka itulah "tenggat waktu" Anda di sana!

Ada pendekatan lain, jika Anda ingin mencegah penggunaan fitur dependensi tertentu (misalnya memanggil fungsi-fungsi tertentu yang tidak cocok dengan sisa kode Anda), terutama jika Anda tidak mengontrol ketergantungan: minta standar pengkodean Anda melarang Saya tidak menyarankan penggunaan fitur-fitur ini, dan tambahkan tanda centang pada fitur-fitur Anda

Masing-masing akan berlaku dalam keadaan yang berbeda.

Warbo
sumber
1

Anda mengelola ini di tingkat paket atau perpustakaan. Anda mengontrol paket dan mengontrol visibilitasnya. Anda bebas untuk menarik kembali visibilitas. Saya telah melihat ini secara internal di perusahaan besar dan hanya masuk akal dalam budaya yang menghormati kepemilikan paket bahkan jika paket tersebut bersifat open source atau bebas untuk digunakan.

Ini selalu berantakan karena tim klien tidak ingin mengubah apa pun, jadi Anda sering memerlukan putaran daftar putih saja saat Anda bekerja dengan klien tertentu untuk menyetujui tenggat waktu untuk bermigrasi, mungkin menawarkan dukungan kepada mereka.

Djechlin
sumber
Saya suka bagian dukungan. Semua perubahan terjadi lebih lancar, lebih menyenangkan dan mungkin dengan sedikit kesulitan jika orang yang mempromosikannya menawarkan dukungan. Itu sebagian merupakan efek psikologis: Dukungan yang baik adalah kerja sama; itu semua melibatkan serius. Sebaliknya, perubahan yang dipaksakan dari atas tanpa melibatkan yang bersangkutan membuat mereka merasa diabaikan dan tidak kooperatif. (Meskipun keramahan harus dipasangkan dengan dorongan tanpa henti untuk menyelesaikan perubahan.)
Peter - Reinstate Monica
1

Salah satu persyaratan adalah untuk memperkenalkan gagasan tentang waktu ke dalam bangunan. Dalam C, C ++, atau bahasa lainnya / membangun sistem yang menggunakan C-seperti preprocessor 1 , salah satu bisa memperkenalkan cap waktu melalui mendefinisikan untuk preprocessor pada waktu membangun: CPPFLAGS=-DTIMESTAMP()=$(date '+%s'). Ini kemungkinan akan terjadi di makefile.

Dalam kode kita akan membandingkan token itu dan menyebabkan kesalahan jika waktu habis. Perhatikan bahwa menggunakan fungsi makro menangkap kasus yang tidak didefinisikan seseorang TIMESTAMP.

#if TIMESTAMP() == 0 || TIMESTAMP() > 1520616626
#   error "The time for this feature has run out, sorry"
#endif

Atau, seseorang bisa "mendefinisikan" kode yang dimaksud ketika saatnya tiba. Itu akan memungkinkan program untuk dikompilasi, asalkan tidak ada yang menggunakannya. Katakanlah, kami memiliki tajuk yang mendefinisikan api, "api.h", dan kami tidak mengizinkan panggilan old()setelah waktu tertentu:

//...
void new1();
void new2();
#if TIMESTAMP() < 1520616626
   void old();
#endif
//...

Konstruk serupa mungkin akan menghilangkan old()fungsi tubuh dari beberapa file sumber.

Tentu saja ini bukan bukti bodoh; seseorang dapat dengan mudah mendefinisikan yang lama TIMESTAMPdalam kasus bangunan darurat Jumat malam yang disebutkan di tempat lain. Tapi itu, saya pikir, agak menguntungkan.

Ini jelas hanya berfungsi ketika perpustakaan dikompilasi ulang - setelah itu kode usang tidak ada lagi di perpustakaan. Itu tidak akan mencegah kode klien dari menautkan ke binari usang.


1 C # hanya mendukung definisi sederhana dari simbol preprosesor, tanpa nilai numerik, yang membuat strategi ini tidak dapat dijalankan.

Peter - Pasang kembali Monica
sumber
Perlu dicatat juga bahwa preprocessor define ini akan memaksa semua kode yang digunakan TIMESTAMPuntuk dikompilasi ulang pada setiap build. Ini juga akan melumpuhkan alat seperti ccache. Ini berarti bahwa waktu kompilasi tipikal untuk penambahan bertahap akan meningkat secara signifikan tergantung pada seberapa banyak basis kode dipengaruhi oleh fitur yang ditinggalkan dengan cara ini.
mindriot
@mindriot Itu aspek yang menarik. Saya kira itu benar dengan setiap metode memperkenalkan gagasan waktu ke dalam kode - OP mengatakan secara eksplisit "setelah tanggal tertentu telah berlalu". Seseorang dapat menangani aspek waktu dalam sistem build dan membiarkan kodenya sendiri, benar. Namun OP secara eksplisit meminta "sesuatu dimasukkan ke dalam kode". Solusi saya memiliki keuntungan tidak tergantung pada metode pembangunan tertentu. Itu bisa ditipu, tetapi Anda harus memenuhi satu atau lain cara.
Peter - Pasang kembali Monica
Anda benar sekali. Solusi Anda di sini pada dasarnya adalah satu-satunya yang memberikan solusi praktis untuk pertanyaan aktual OP . Namun demikian saya merasa penting untuk menunjukkan sisi negatifnya. Terserah OP untuk menimbang pro dan kontra. Saya pikir jalan tengah yang sehat bahkan dapat dicapai dengan, katakanlah, membagi TIMESTAMPnilainya dengan, katakanlah, 86400, untuk mendapatkan rincian setiap hari dan dengan demikian lebih sedikit kompilasi ulang.
mindriot
0

Di Visual Studio, Anda bisa mengatur skrip pra-bangun yang melempar kesalahan setelah tanggal tertentu. Ini akan mencegah kompilasi. Berikut skrip yang menampilkan kesalahan pada atau setelah 12 Maret 2018 ( diambil dari sini ):

@ECHO OFF

SET CutOffDate=2018-03-12

REM These indexes assume %DATE% is in format:
REM   Abr MM/DD/YYYY - ex. Sun 01/25/2015
SET TodayYear=%DATE:~10,4%
SET TodayMonth=%DATE:~4,2%
SET TodayDay=%DATE:~7,2%

REM Construct today's date to be in the same format as the CutOffDate.
REM Since the format is a comparable string, it will evaluate date orders.
IF %TodayYear%-%TodayMonth%-%TodayDay% GTR %CutOffDate% (
    ECHO Today is after the cut-off date.
    REM throw an error to prevent compilation
    EXIT /B 2
) ELSE (
    ECHO Today is on or before the cut-off date.
)

Pastikan untuk membaca jawaban lain di halaman ini sebelum menggunakan skrip ini.

pengguna2023861
sumber
-1

Saya mengerti tujuan dari apa yang Anda coba lakukan. Tetapi seperti yang telah disebutkan orang lain, sistem build / compiler mungkin bukan tempat yang tepat untuk menegakkan ini. Saya menyarankan lapisan yang lebih alami untuk menegakkan kebijakan ini adalah variabel SCM atau lingkungan.

Jika Anda melakukan yang terakhir, pada dasarnya tambahkan flag fitur yang menandai menjalankan pra-penghentian. Setiap kali Anda membangun kelas yang sudah usang atau memanggil metode yang sudah usang, periksa tanda fitur. Cukup tentukan satu fungsi statis assertPreDeprecated()dan tambahkan ini ke setiap jalur kode yang sudah usang. Jika sudah diatur, abaikan panggilan panggilan. Jika tidak ada pengecualian. Setelah tanggal berlalu, batalkan flag fitur di lingkungan runtime. Setiap panggilan lama yang ditinggalkan ke kode akan muncul di log runtime.

Untuk solusi berbasis SCM, saya akan menganggap Anda menggunakan git dan git-flow. (Jika tidak, logikanya mudah disesuaikan dengan VCS lain). Buat cabang baru postDeprecated. Di cabang itu hapus semua kode yang sudah tidak digunakan lagi, dan mulailah bekerja untuk menghapus referensi apa pun hingga kompilasi. Setiap perubahan normal terus dilakukan ke mastercabang. Terus gabungkan setiap perubahan kode terkait yang tidak usang masterkembali ke dalam postDeprecateduntuk meminimalkan tantangan integrasi.

Setelah tanggal penghentian berakhir, buat preDeprecatedcabang baru dari master. Kemudian bergabung postDeprecatedkembali master. Dengan asumsi rilis Anda keluar dari mastercabang, Anda sekarang harus menggunakan cabang pasca-ditinggalkan setelah tanggal. Jika ada keadaan darurat, atau Anda tidak dapat memberikan hasil dalam waktu, Anda selalu dapat mengembalikan ke preDeprecated, dan membuat perubahan yang diperlukan pada cabang itu.

pengguna79126
sumber
7
Pendekatan itu terdengar seperti mimpi buruk logistik. Jika Anda mulai mempertahankan cabang paralel duplikat hampir, Anda akan menghabiskan seluruh waktu Anda untuk melakukannya. Total limbah.
Lightness Races dengan Monica
6
Saya tidak bisa setuju bahwa mempertahankan cabang paralel, menggunakan satu hanya untuk menghapus fungsi banyak versi usang sebelum Anda benar-benar ingin menghapusnya dari produk, dengan cara apa pun "standar industri". Apa tujuan dari itu? Ya, VCS dapat secara otomatis melakukan beberapa penggabungan, tetapi penggabungan harus dilakukan dengan mata pengembang untuk menyelesaikan konflik logis (dan apa yang terjadi ketika Anda mendapatkan konflik yang bahkan tidak dapat diselesaikan secara leksikal?). Memiliki sistem build secara sewenang-wenang menggabungkan setiap hari untuk ini hanyalah ... sia-sia. Hapus fitur ketika saatnya untuk menghapusnya.
Lightness Races dengan Monica
3
Karena ada alasan bagus untuk mempertahankan cabang rilis (backporting patches penting). Tidak ada alasan bagus untuk mempertahankan cabang "sesuatu yang mungkin saya lakukan di masa depan". Itu di atas kepala, tanpa manfaat. Sederhana seperti itu.
Lightness Races dengan Monica
4
Di mana saya mendapatkannya? Ini secara harfiah definisi penghinaan. Anda mencela sesuatu yang mungkin Anda hapus di masa depan. Dengan demikian tidak ada kecurangan, tidak ada gerakan dari tiang gawang, dan tentu saja tidak ada yang mengada-ada hanya "untuk memenangkan argumen". Ini bukan "kasus penggunaan buku bercabang tentang SCM" di organisasi mana pun yang saya inginkan! Saya kira kita harus setuju untuk tidak setuju. Selamat malam!
Lightness Races dengan Monica
2
@ cahaya - Ada banyak banyak alasan mengapa kode yang secara resmi mencela bukan hanya "hal yang bisa kita lakukan setiap kali kita melakukannya". Mungkin kode yang ditinggalkan menggunakan perpustakaan, di mana dukungan resmi sedang dijatuhkan. Mungkin kode yang ditinggalkan adalah IP yang lisensinya kedaluwarsa setelah tanggal yang tetap. Mungkin setelah tanggal yang diberikan, ada peraturan baru, dan kode tidak sesuai. Solusi Anda baik-baik saja dan baik jika Anda tinggal di menara gading. Tapi org dunia nyata berurusan dengan situasi semacam ini sepanjang waktu. Perangkat lunak perlu memenuhi kebutuhan bisnis, bukan sebaliknya.
user79126