Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
| 1 | <?php |
||
| 8 | class UGitRepository extends GitRepository { |
||
| 9 | |||
| 10 | /** |
||
| 11 | * Runs command. |
||
| 12 | * |
||
| 13 | * @param |
||
| 14 | * string|array |
||
| 15 | * @return self |
||
| 16 | * @throws Cz\Git\GitException |
||
| 17 | */ |
||
| 18 | protected function run($cmd/*, $options = NULL*/){ |
||
| 19 | $args = func_get_args (); |
||
| 20 | $cmd = $this->_processCommand ( $args ); |
||
| 21 | exec ( $cmd . ' 2>&1', $output, $ret ); |
||
| 22 | |||
| 23 | if ($ret !== 0) { |
||
| 24 | throw new GitException ( "Command '$cmd' failed (exit-code $ret).", $ret ); |
||
| 25 | } |
||
| 26 | |||
| 27 | return $this; |
||
| 28 | } |
||
| 29 | |||
| 30 | protected function _processCommand(array $args) { |
||
| 31 | $cmd = array (); |
||
| 32 | |||
| 33 | $programName = array_shift ( $args ); |
||
| 34 | |||
| 35 | foreach ( $args as $arg ) { |
||
| 36 | if (is_array ( $arg )) { |
||
| 37 | foreach ( $arg as $key => $value ) { |
||
| 38 | $_c = ''; |
||
| 39 | |||
| 40 | if (is_string ( $key )) { |
||
| 41 | $_c = "$key "; |
||
| 42 | } |
||
| 43 | if (is_array ( $value )) { |
||
| 44 | foreach ( $value as $v ) { |
||
| 45 | $cmd [] = $_c . escapeshellarg ( $v ); |
||
| 46 | } |
||
| 47 | } else { |
||
| 48 | $cmd [] = $_c . escapeshellarg ( $value ); |
||
| 49 | } |
||
| 50 | } |
||
| 51 | } elseif (is_scalar ( $arg ) && ! is_bool ( $arg )) { |
||
| 52 | $cmd [] = escapeshellarg ( $arg ); |
||
| 53 | } |
||
| 54 | } |
||
| 55 | return "$programName " . implode ( ' ', $cmd ); |
||
| 56 | } |
||
| 57 | |||
| 58 | /** |
||
| 59 | * Returns list of untracked files in repo. |
||
| 60 | * |
||
| 61 | * @return string[]|NULL NULL => no files untracked |
||
| 62 | */ |
||
| 63 | public function getUntrackedFiles() { |
||
| 64 | return $this->extractFromCommand ( 'git ls-files --others --exclude-standard', function ($value) { |
||
| 65 | return trim ( $value ); |
||
| 66 | } ); |
||
| 67 | } |
||
| 68 | |||
| 69 | /** |
||
| 70 | * Returns list of modified files in repo. |
||
| 71 | * |
||
| 72 | * @return string[]|NULL NULL => no files modified |
||
| 73 | */ |
||
| 74 | public function getModifiedFiles() { |
||
| 75 | try { |
||
| 76 | return $this->extractFromCommand ( 'git diff --name-status HEAD', function ($array) { |
||
| 77 | $array = trim ( preg_replace ( '!\s+!', ' ', $array ) ); |
||
| 78 | return explode ( ' ', $array ); |
||
| 79 | } ); |
||
| 80 | } catch ( \Cz\Git\GitException $e ) { |
||
| 81 | return [ ]; |
||
| 82 | } |
||
| 83 | } |
||
| 84 | |||
| 85 | public function getChangesInFile($filename) { |
||
| 86 | try { |
||
| 87 | $output = $this->extractFromCommand ( 'git diff ' . $filename ); |
||
| 88 | if (is_array ( $output )) |
||
| 89 | return implode ( '\r\n', $output ); |
||
| 90 | return $output; |
||
| 91 | } catch ( \Cz\Git\GitException $e ) { |
||
| 92 | return ""; |
||
| 93 | } |
||
| 94 | } |
||
| 95 | |||
| 96 | public function getChangesInCommit($commitHash) { |
||
| 97 | try { |
||
| 98 | $output = $this->extractFromCommand ( "git show {$commitHash}" ); |
||
| 99 | if (is_array ( $output )) |
||
| 100 | return implode ( '\r\n', $output ); |
||
| 101 | return $output; |
||
| 102 | } catch ( \Cz\Git\GitException $e ) { |
||
| 103 | return ""; |
||
| 104 | } |
||
| 105 | } |
||
| 106 | |||
| 107 | /** |
||
| 108 | * Returns the remote URL |
||
| 109 | * |
||
| 110 | * @return string |
||
| 111 | */ |
||
| 112 | public function getRemoteUrl() { |
||
| 113 | try { |
||
| 114 | $values = $this->extractFromCommand ( 'git config --get remote.origin.url', function ($str) { |
||
| 115 | return trim ( $str ); |
||
| 116 | } ); |
||
| 117 | if (isset ( $values )) { |
||
| 118 | return implode ( " ", $values ); |
||
| 119 | } |
||
| 120 | } catch ( \Cz\Git\GitException $e ) { |
||
| 121 | return ""; |
||
| 122 | } |
||
| 123 | return ""; |
||
| 124 | } |
||
| 125 | |||
| 126 | /** |
||
| 127 | * Ignore file(s). |
||
| 128 | * `git update-index --assume-unchanged <file>` |
||
| 129 | * |
||
| 130 | * @param $files string|string[] |
||
| 131 | * @throws Cz\Git\GitException |
||
| 132 | * @return self |
||
| 133 | */ |
||
| 134 | public function ignoreFiles($files) { |
||
| 135 | if (! is_array ( $files )) { |
||
| 136 | $files = func_get_args (); |
||
| 137 | } |
||
| 138 | $this->begin (); |
||
| 139 | $this->run ( 'git reset', NULL, [ "--" => $files ] ); |
||
| 140 | return $this->end (); |
||
| 141 | } |
||
| 142 | |||
| 143 | public function getCommits() { |
||
| 144 | $nonPushed = $this->getNonPushedCommitHash (); |
||
| 145 | try { |
||
| 146 | return $this->extractFromCommand ( 'git log --pretty=format:"%h___%an___%ar___%s___%H"', function ($str) use ($nonPushed) { |
||
| 147 | $array = explode ( "___", $str ); |
||
| 148 | $pushed = true; |
||
| 149 | if (is_array ( $nonPushed )) |
||
| 150 | $pushed = ! in_array ( $array [0], $nonPushed ); |
||
| 151 | return new GitCommit ( $array [0], $array [1], $array [2], $array [3], $array [4], $pushed ); |
||
| 152 | } ); |
||
| 153 | } catch ( \Cz\Git\GitException $e ) { |
||
| 154 | return [ ]; |
||
| 155 | } |
||
| 156 | return [ ]; |
||
| 157 | } |
||
| 158 | |||
| 159 | public function getNonPushedCommitHash() { |
||
| 160 | try { |
||
| 161 | return $this->extractFromCommand ( 'git log origin/master..master --pretty=format:"%h"' ); |
||
| 162 | } catch ( \Cz\Git\GitException $e ) { |
||
| 163 | return [ ]; |
||
| 164 | } |
||
| 165 | return [ ]; |
||
| 166 | } |
||
| 167 | } |
||
| 168 |