ANTを使用してSVNでプロジェクトをリファクタリングする

この記事では、SVNリポジトリーの大規模プロジェクトをリファクタリングする1つの実用的な問題を解決するために使用される、ロジックを分離し、antスクリプトでロジックを実装する方法について説明します。

背景

SVNには、15,000ファイルと5,000フォルダーのプロジェクトがあります。 このプロジェクトはほぼ10年前であり、さまざまな資格を持つ数世代の開発者が取り組んできました。 ある時点で、数年前、またはそれよりも早い時期に、プロジェクトのアーキテクチャが「流れ」ました。 コードを編成するためのさまざまな標準でさまざまなモジュールとレイヤーが記述され始め、モジュール間に周期的な依存関係がありました。 その結果、長年にわたってSVNでダンプが形成されました。 プロジェクトは進行中ですが、完全にシャーマニスティックな方法です。

挑戦する

コードを単一のストレージ形式にします。 同時に、各ファイルの変更履歴を保存し、開発プロセスを停止しないでください。

難しさ

SVNの単一のファイルまたはフォルダーから履歴を保存するのは、 svn copyコマンドを使用すると非常に簡単です。 少数のファイルで、すべてを手動で行うことができます。
大規模なプロジェクトを解析することは困難です。 15,000個のファイルを手動で解析しますが、開発者は新しい変更をコミットし、それらもコピーする必要があります。 悪循環。
自動化が必要です。 Skriptik、その時! -プロジェクトを新しい構造に変換します。

結果

タスクが完了し、大規模プログラミングでのカプセル化と呼ばれるANTスクリプトのアプローチが副産物になりました。 アプローチを共有したいと思います。


ソースコード(会社名および製品名なしの大幅に短縮された)は、Googleコードで入手できます


どのようにしてこのようなスクリプトに来たのかという話

私は行動計画を立てました:
  1. 新しい構造を考え出す
  2. プロジェクトのファイルシステムを古い構造から新しい構造にコピーするスクリプトを作成します
  3. 新しい構造のデバッグ、ビルドスクリプトの作成など。 -デバッグには、ファイルシステムでのコピー操作の開始に多くの時間と数十(数百ではないにしても)の時間がかかります。
  4. svn copyでスクリプトを準備するスクリプトを書く
  5. SVNの新しい構造のデバッグ
  6. X時間を発表し、スクリプトを実行して、すべての開発者を新しい構造に移行します。


アクションプランの実装:

パラグラフ1からの新しい構造の説明は、この記事の範囲外です。
コピースクリプトは、bat、bashで記述できます。
私たちはANTビルドツールを使用しているので、そのツールを作成し始めました。
私の場合、ANTスクリプトを記述して最初の成功した結果を得るまでに数週間かかりました。

スクリプトは、この種類のコマンドで構成されていました。
<mkdir dir="@{to}"/> <copy todir="@{to}" overwrite="false"> <fileset dir="@{from}"> <include name="@{include}"/> <include name="@{include}"/> <exclude name="@{include}"/> </fileset> </copy> 


それは非常に長く、読みにくく修正可能であることが判明しました。
彼には1つの利点がありました-彼は働きました。 しかし、私はsvnコピーのために同様のファイルを書かなければなりませんでした...そして、これはやや面倒でした。
よく考えた後、私は別の文章を書く必要があると決めました。 コピーアンドペーストを取り除き、マッピングを別のファイルに入れ、接続されたファイルで実装を隠します。 しかし、ANTでそれを行う方法は? ANTにマクロを使用する!

macrodefディレクティブを使用して、 ant.macrosに新しいタスクを定義します

  <macrodef name="copy_by_pattern"> <attribute name="from"/> <attribute name="to"/> <attribute name="include"/> <sequential> <echo message="copy from dir @{from} to dir @{to} by pattern @{include}"/> <mkdir dir="@{to}"/> <copy todir="@{to}" overwrite="false"> <fileset dir="@{from}"> <include name="@{include}"/> </fileset> </copy> </sequential> </macrodef> 


タスクcopy_by_patternは、インクルードマスクによってファイルをコピーします。

上記のコードはに変換されます

  <copy_by_pattern from="${dir.input.base}/module1" to="${dir.output.base}" include="**"/> <copy_by_pattern from="${dir.input.base}/module2" to="${dir.output.base}" include="**"/> <copy_by_pattern from="${dir.input.base}/module3" to="${dir.output.base}" include="**"/> 


以前と同じように機能するよう努めています。
そして、svn.macrosにsvn copyのcopy_by_patternの実装を記述します

  <macrodef name="copy_by_pattern"> <attribute name="from"/> <attribute name="to"/> <attribute name="include"/> <sequential> <fileset id="localfs" dir="@{from}"> <include name="@{include}"/> </fileset> <local name="out.script"/> <pathconvert property="out.script" refid="localfs" pathsep="${line.separator}"> <chainedmapper> <identitymapper/> <regexpmapper from="@{from}/(.*)" to="${cli.command} @{from}/\1 @{to}/\1" handledirsep="yes"/> </chainedmapper> </pathconvert> <echo file="${script.filename}" message="${out.script}${line.separator}" append="true"/> </sequential> </macrodef> 


このタスクはファイルセットを受け取り、 pathconvertおよびregexpmapperを使用してローカル変数(ANT 1.8に表示)out.scriptを変換ます 。 次に、ファイル$ {script.filename}にsvnコピーを含むスクリプトのフラグメントを表示します

注:バージョン1.8より前のANTでは、 ローカル変数はありませんでした。 変数に値を書き込んだ後は、変更できません。

出力で取得されたsvnコピーを持つスクリプトのフラグメントの例:

svn copy --parents D:\path_old\app.xml D:\path_new\app.xml
svn copy --parents D:\path_old\Cls.java D:\path_new\Cls.java
svn copy --parents D:\path_old\page.jsp D:\path_new\page.jsp
svn copy --parents D:\path_old\js.js D:\path_new\js.js

--parentsキーは、必要なすべての新しいディレクトリを作成します

SVNコピーコマンドノート

彼女には4つのコピーオプションがあります。
WC -> WC: copy and schedule for addition (with history)
WC -> URL: immediately commit a copy of WC to URL
URL -> WC: check out URL into WC, schedule for addition
URL -> URL: complete server-side copy; used to branch and tag


最も便利なオプションはWC-> WC:です。他の全員がすぐにリポジトリにコミットするためです。 15,000のプロジェクトファイルをシャッフルすると、15,000のコミットが作成されます。 WC-> WCオプションを使用すると、保留中のコミットを1つ作成できます。

おわりに

ANTスクリプトを確認します。
ANTスクリプトで多くの繰り返しフラグメントが見られる場合、
それらは、macrodefを使用して新しいタスクに結合できます。
同時に、ロジックを実装から分離できます。

Source: https://habr.com/ru/post/J119013/


All Articles