aboutsummaryrefslogtreecommitdiff
path: root/src/phorkie/Forker.php
blob: da545a72c1eb590b4bedd98d9b35208800e3d438 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
<?php
namespace phorkie;

class Forker
{
    public function forkLocal($repo)
    {
        $new = $this->fork($repo->gitDir);

        \copy($repo->gitDir . '/description', $new->gitDir . '/description');
        $new->getVc()
            ->getCommand('config')
            ->addArgument('remote.origin.title')
            ->addArgument(file_get_contents($repo->gitDir . '/description'))
            ->execute();

        $this->index($new);

        $not = new Notificator();
        $not->create($new);

        return $new;
    }

    public function forkRemote($cloneUrl, $originalUrl, $title = null)
    {
        $new = $this->fork($cloneUrl);

        $new->getVc()
            ->getCommand('config')
            ->addArgument('remote.origin.title')
            ->addArgument($title)
            ->execute();
        if ($originalUrl != $cloneUrl) {
            $new->getVc()
                ->getCommand('config')
                ->addArgument('remote.origin.homepage')
                ->addArgument($originalUrl)
                ->execute();
        }

        if ($title === null) {
            $title = 'Fork of ' . $originalUrl;
        }
        file_put_contents($new->gitDir . '/description', $title);

        $this->index($new);

        $not = new Notificator();
        $not->create($new);

        return $new;
    }


    protected function fork($pathOrUrl)
    {
        $rs = new Repositories();
        $new = $rs->createNew();
        $vc = $new->getVc();

        //VersionControl_Git wants an existing dir, git clone not
        \rmdir($new->gitDir);

        $cmd = $vc->getCommand('clone')
            //this should be setOption, but it fails with a = between name and value
            ->addArgument('--separate-git-dir')
            ->addArgument(
                $GLOBALS['phorkie']['cfg']['gitdir'] . '/' . $new->id . '.git'
            )
            ->addArgument($pathOrUrl)
            ->addArgument($new->workDir);
        try {
            $cmd->execute();
        } catch (\Exception $e) {
            //clean up, we've got no workdir otherwise
            $new->delete();
            throw $e;
        }

        $rs = new Repository_Setup($new);
        $rs->afterInit();

        //update info for dumb git HTTP transport
        //the post-update hook should do that IMO, but does not somehow
        $vc->getCommand('update-server-info')->execute();

        return $new;
    }

    protected function index($repo)
    {
        $db = new Database();
        $db->getIndexer()->addRepo($repo);
    }
}

?>