Пример #1
0
def test_lineinfile_knows_about_ownership(HOME, tmpdir):
    system = getsystemfn(HOME)

    # put the 'AAA' line into my file1.txt
    f1 = HOME + '/file1.txt'
    contents(f1, 'AAA\n')

    # create a fake repo and add it
    tr = TempRepo(tmpdir, 'dotfiles')
    contents(tr.remotepath + '/HOMELY.py',
             """
             from homely.general import lineinfile
             lineinfile('file1.txt', 'AAA')
             lineinfile('file1.txt', 'BBB')
             """)
    system(HOMELY('add') + [tr.url])

    # check that my file1.txt now has both lines
    assert contents(f1) == "AAA\nBBB\n"

    # now remove the repo and do a full update to trigger cleanup
    system(HOMELY('forget') + [tr.url])
    system(HOMELY('update'))

    # run homely update a few more times to confuse it
    system(HOMELY('update'))
    system(HOMELY('update'))

    # check that only the 'BBB' line was removed
    assert contents(f1) == "AAA\n"
Пример #2
0
def test_lineinfile_knows_about_ownership(HOME, tmpdir):
    system = getsystemfn(HOME)

    # put the 'AAA' line into my file1.txt
    f1 = HOME + '/file1.txt'
    contents(f1, 'AAA\n')

    # create a fake repo and add it
    tr = TempRepo(tmpdir, 'dotfiles')
    contents(
        tr.remotepath + '/HOMELY.py', """
             from homely.general import lineinfile
             lineinfile('file1.txt', 'AAA')
             lineinfile('file1.txt', 'BBB')
             """)
    system(HOMELY('add') + [tr.url])

    # check that my file1.txt now has both lines
    assert contents(f1) == "AAA\nBBB\n"

    # now remove the repo and do a full update to trigger cleanup
    system(HOMELY('forget') + [tr.url])
    system(HOMELY('update'))

    # run homely update a few more times to confuse it
    system(HOMELY('update'))
    system(HOMELY('update'))

    # check that only the 'BBB' line was removed
    assert contents(f1) == "AAA\n"
Пример #3
0
def test_homely_remove(tmpdir, HOME):
    system = getsystemfn(HOME)

    def _addfake(name, createfile):
        # create a fake repo and add it
        tr = TempRepo(tmpdir, name)
        tf = os.path.join(HOME, createfile)
        contents(tr.remotepath + '/HOMELY.py',
                 """
                 from homely.files import lineinfile
                 lineinfile('~/%s', 'Hello from %s')
                 """ % (createfile, name))
        assert not os.path.exists(tf)
        system(HOMELY('add') + [tr.url])
        assert contents(tf) == "Hello from %s\n" % name
        return tr

    r1 = _addfake('repo1', 'file1.txt')
    r2 = _addfake('repo2', 'file2.txt')
    r3 = _addfake('repo3', 'file3.txt')

    # check that all the repos are there
    checkrepolist(HOME, system, [r1, r2, r3])
    assert contents(HOME + '/file1.txt', "Hello from repo1\n")
    assert contents(HOME + '/file2.txt', "Hello from repo2\n")
    assert contents(HOME + '/file3.txt', "Hello from repo3\n")

    # Check that the repo can be removed.
    system(HOMELY('forget') + [r1.repoid])
    checkrepolist(HOME, system, [r2, r3])
    assert contents(HOME + '/file1.txt', "Hello from repo1\n")
    assert contents(HOME + '/file2.txt', "Hello from repo2\n")
    assert contents(HOME + '/file3.txt', "Hello from repo3\n")

    # now run an update to make repo1's files go away
    system(HOMELY('update'))
    assert not os.path.exists(HOME + '/file1.txt')
    assert contents(HOME + '/file2.txt', "Hello from repo2\n")
    assert contents(HOME + '/file3.txt', "Hello from repo3\n")

    # Test removing multiple repos, but using local path this time
    # Note that because we don't use --update, the created files will still be
    # sitting around on disk
    system(HOMELY('forget') + ['~/repo2', '~/repo3'])
    checkrepolist(HOME, system, [])
    # repo2 and repo3 are stilling going to hang around on disk
    assert os.path.exists(HOME + '/repo2')
    assert os.path.exists(HOME + '/repo3')
    assert not os.path.exists(HOME + '/file1.txt')
    assert contents(HOME + '/file2.txt', "Hello from repo2\n")
    assert contents(HOME + '/file3.txt', "Hello from repo3\n")
Пример #4
0
def test_homely_remove(tmpdir, HOME):
    system = getsystemfn(HOME)

    def _addfake(name, createfile):
        # create a fake repo and add it
        tr = TempRepo(tmpdir, name)
        tf = os.path.join(HOME, createfile)
        contents(
            tr.remotepath + '/HOMELY.py', """
                 from homely.files import lineinfile
                 lineinfile('~/%s', 'Hello from %s')
                 """ % (createfile, name))
        assert not os.path.exists(tf)
        system(HOMELY('add') + [tr.url])
        assert contents(tf) == "Hello from %s\n" % name
        return tr

    r1 = _addfake('repo1', 'file1.txt')
    r2 = _addfake('repo2', 'file2.txt')
    r3 = _addfake('repo3', 'file3.txt')

    # check that all the repos are there
    checkrepolist(HOME, system, [r1, r2, r3])
    assert contents(HOME + '/file1.txt', "Hello from repo1\n")
    assert contents(HOME + '/file2.txt', "Hello from repo2\n")
    assert contents(HOME + '/file3.txt', "Hello from repo3\n")

    # Check that the repo can be removed.
    system(HOMELY('forget') + [r1.repoid])
    checkrepolist(HOME, system, [r2, r3])
    assert contents(HOME + '/file1.txt', "Hello from repo1\n")
    assert contents(HOME + '/file2.txt', "Hello from repo2\n")
    assert contents(HOME + '/file3.txt', "Hello from repo3\n")

    # now run an update to make repo1's files go away
    system(HOMELY('update'))
    assert not os.path.exists(HOME + '/file1.txt')
    assert contents(HOME + '/file2.txt', "Hello from repo2\n")
    assert contents(HOME + '/file3.txt', "Hello from repo3\n")

    # Test removing multiple repos, but using local path this time
    # Note that because we don't use --update, the created files will still be
    # sitting around on disk
    system(HOMELY('forget') + ['~/repo2', '~/repo3'])
    checkrepolist(HOME, system, [])
    # repo2 and repo3 are stilling going to hang around on disk
    assert os.path.exists(HOME + '/repo2')
    assert os.path.exists(HOME + '/repo3')
    assert not os.path.exists(HOME + '/file1.txt')
    assert contents(HOME + '/file2.txt', "Hello from repo2\n")
    assert contents(HOME + '/file3.txt', "Hello from repo3\n")
Пример #5
0
def test_add_greenfield_repos(tmpdir, HOME):
    """
    Work or at least die with a helpful error message when ...
    """
    from homely._errors import ERR_NO_COMMITS, ERR_NOT_A_REPO, ERR_NO_SCRIPT

    system = getsystemfn(HOME)

    def _repolist():
        cmd = HOMELY('repolist') + ['--format', '%(localpath)s']
        return list(filter(None, system(cmd).strip().split("\n")))

    # Target dir is not a git repo
    notarepo = HOME + '/not_a_repo'
    os.mkdir(notarepo)
    contents(notarepo + '/HOMELY.py', "print('YES')\n")
    output = system(HOMELY('add') + [notarepo], expecterror=1)
    assert ERR_NOT_A_REPO in output
    del notarepo, output
    # this should have resulted in nothing being added to homely
    assert not len(_repolist())

    # Target dir doesn't have any commits
    nocommits = HOME + '/nocommits'
    os.mkdir(nocommits)
    contents(nocommits + '/HOMELY.py', "print('YES')\n")
    system(['git', 'init'], cwd=nocommits)
    assert os.path.exists(nocommits + '/.git')
    output = system(HOMELY('add') + [nocommits], expecterror=1)
    assert ERR_NO_COMMITS in output
    del nocommits, output
    # this should have resulted in nothing being added to homely
    assert not len(_repolist())

    # Target dir doesn't have a HOMELY.py script - when we add a repo that
    # doesn't have a HOMELY.py script we should raise an error and provide
    # instructions on how to write a HOMELY.py script (and not try to do the
    # homely update).
    noscript = HOME + '/noscript'
    os.mkdir(noscript)
    readme = noscript + '/README.md'
    contents(readme, "Hello world!\n")
    system(['git', 'init'], cwd=noscript)
    system(['git', 'config', 'user.name', "fred"], cwd=noscript)
    system(['git', 'config', 'user.email', "fred@example"], cwd=noscript)
    system(['git', 'add', 'README.md'], cwd=noscript)
    system(['git', 'commit', '-m', "Added readme"], cwd=noscript)
    output = system(HOMELY('add') + [noscript], expecterror=1)
    assert ERR_NO_SCRIPT in output
    # the repo should have added to homely
    assert [noscript] == _repolist()
Пример #6
0
def test_add_greenfield_repos(tmpdir, HOME):
    """
    Work or at least die with a helpful error message when ...
    """
    from homely._errors import ERR_NO_COMMITS, ERR_NOT_A_REPO, ERR_NO_SCRIPT

    system = getsystemfn(HOME)

    def _repolist():
        cmd = HOMELY('repolist') + ['--format', '%(localpath)s']
        return list(filter(None, system(cmd).strip().split("\n")))

    # Target dir is not a git repo
    notarepo = HOME + '/not_a_repo'
    os.mkdir(notarepo)
    contents(notarepo + '/HOMELY.py', "print('YES')\n")
    output = system(HOMELY('add') + [notarepo], expecterror=1)
    assert ERR_NOT_A_REPO in output
    del notarepo, output
    # this should have resulted in nothing being added to homely
    assert not len(_repolist())

    # Target dir doesn't have any commits
    nocommits = HOME + '/nocommits'
    os.mkdir(nocommits)
    contents(nocommits + '/HOMELY.py', "print('YES')\n")
    system(['git', 'init'], cwd=nocommits)
    assert os.path.exists(nocommits + '/.git')
    output = system(HOMELY('add') + [nocommits], expecterror=1)
    assert ERR_NO_COMMITS in output
    del nocommits, output
    # this should have resulted in nothing being added to homely
    assert not len(_repolist())

    # Target dir doesn't have a HOMELY.py script - when we add a repo that
    # doesn't have a HOMELY.py script we should raise an error and provide
    # instructions on how to write a HOMELY.py script (and not try to do the
    # homely update).
    noscript = HOME + '/noscript'
    os.mkdir(noscript)
    readme = noscript + '/README.md'
    contents(readme, "Hello world!\n")
    system(['git', 'init'], cwd=noscript)
    system(['git', 'config', 'user.name', "fred"], cwd=noscript)
    system(['git', 'config', 'user.email', "fred@example"], cwd=noscript)
    system(['git', 'add', 'README.md'], cwd=noscript)
    system(['git', 'commit', '-m', "Added readme"], cwd=noscript)
    output = system(HOMELY('add') + [noscript], expecterror=1)
    assert ERR_NO_SCRIPT in output
    # the repo should have added to homely
    assert [noscript] == _repolist()
Пример #7
0
def test_symlink_recreate(HOME, tmpdir):
    system = getsystemfn(HOME)

    def _addfake(name, createfile):
        # create a fake repo and add it
        tr = TempRepo(tmpdir, name)
        tf = os.path.join(tr.remotepath, createfile)
        with open(tf, 'w') as f:
            f.write('hello world')
        contents(
            tr.remotepath + '/HOMELY.py', """
                 from homely.files import symlink
                 symlink('%s', '~/%s')
                 """ % (createfile, createfile))
        system(HOMELY('add') + [tr.url])
        local = '%s/%s' % (tr.suggestedlocal(HOME), createfile)
        assert os.readlink('%s/%s' % (HOME, createfile)) == local

    # add a fake repo
    _addfake('repo1', 'file1.txt')

    # try doing a homely update
    system(HOMELY('update'))
Пример #8
0
def test_symlink_recreate(HOME, tmpdir):
    system = getsystemfn(HOME)

    def _addfake(name, createfile):
        # create a fake repo and add it
        tr = TempRepo(tmpdir, name)
        tf = os.path.join(tr.remotepath, createfile)
        with open(tf, 'w') as f:
            f.write('hello world')
        contents(tr.remotepath + '/HOMELY.py',
                 """
                 from homely.files import symlink
                 symlink('%s', '~/%s')
                 """ % (createfile, createfile))
        system(HOMELY('add') + [tr.url])
        local = '%s/%s' % (tr.suggestedlocal(HOME), createfile)
        assert os.readlink('%s/%s' % (HOME, createfile)) == local

    # add a fake repo
    _addfake('repo1', 'file1.txt')

    # try doing a homely update
    system(HOMELY('update'))
Пример #9
0
def test_homely_update(HOME, tmpdir):
    system = getsystemfn(HOME)

    def _addfake(name, createfile):
        # create a fake repo and add it
        tr = TempRepo(tmpdir, name)
        tf = os.path.join(HOME, createfile)
        contents(
            tr.remotepath + '/HOMELY.py', """
                 from homely.files import lineinfile
                 lineinfile('~/%s', 'Hello from %s')
                 """ % (createfile, name))
        assert not os.path.exists(tf)
        system(HOMELY('add') + [tr.url])
        assert contents(tf) == "Hello from %s\n" % name
        return tr

    template = ("""
                from homely.files import lineinfile
                lineinfile(%r, %r)
                """)

    # add some fake repos
    r1 = _addfake('repo1', 'file1.txt')
    r2 = _addfake('repo2', 'file2.txt')
    r3 = _addfake('repo3', 'file3.txt')

    # update the repos slightly, run an update, ensure all changes have gone
    # through (including cleanup of old content)
    contents(r1.remotepath + '/HOMELY.py', template % ('~/file1.txt', 'AAA'))
    contents(r2.remotepath + '/HOMELY.py', template % ('~/file2.txt', 'AAA'))
    contents(r3.remotepath + '/HOMELY.py', template % ('~/file3.txt', 'AAA'))
    system(HOMELY('update'))
    assert contents(HOME + '/file1.txt') == "AAA\n"
    assert contents(HOME + '/file2.txt') == "AAA\n"
    assert contents(HOME + '/file3.txt') == "AAA\n"

    # modify all the repos again
    contents(r1.remotepath + '/HOMELY.py', template % ('~/file1.txt', 'BBB'))
    contents(r2.remotepath + '/HOMELY.py', template % ('~/file2.txt', 'BBB'))
    contents(r3.remotepath + '/HOMELY.py', template % ('~/file3.txt', 'BBB'))
    # run an update again, but only do it with the 2nd repo
    system(HOMELY('update') + ['~/repo2'])
    # 1st and 3rd repos haven't been rerun
    assert contents(HOME + '/file1.txt') == "AAA\n"
    assert contents(HOME + '/file3.txt') == "AAA\n"
    # NOTE that the cleanup of the 2nd repo doesn't happen when we're doing a
    # single repo
    assert contents(HOME + '/file2.txt') == "AAA\nBBB\n"

    # run an update, but specify all repos - this should be enough to trigger
    # the cleanup
    system(HOMELY('update') + ['~/repo1', '~/repo3', '~/repo2'])
    assert contents(HOME + '/file1.txt') == "BBB\n"
    assert contents(HOME + '/file2.txt') == "BBB\n"
    assert contents(HOME + '/file3.txt') == "BBB\n"

    # modify the repos again, but run update with --nopull so that we don't get
    # any changes
    contents(r1.remotepath + '/HOMELY.py', template % ('~/file1.txt', 'CCC'))
    contents(r2.remotepath + '/HOMELY.py', template % ('~/file2.txt', 'CCC'))
    contents(r3.remotepath + '/HOMELY.py', template % ('~/file3.txt', 'CCC'))
    system(HOMELY('update') + ['~/repo1', '--nopull'])
    assert contents(HOME + '/file1.txt') == "BBB\n"
    assert contents(HOME + '/file2.txt') == "BBB\n"
    assert contents(HOME + '/file3.txt') == "BBB\n"
    system(HOMELY('update') + ['--nopull'])
    assert contents(HOME + '/file1.txt') == "BBB\n"
    assert contents(HOME + '/file2.txt') == "BBB\n"
    assert contents(HOME + '/file3.txt') == "BBB\n"

    # split r1 into multiple sections and just do one of them
    contents(
        r1.remotepath + '/HOMELY.py', """
             from homely.files import lineinfile
             from homely.general import section
             @section
             def partE():
                lineinfile('~/file1.txt', 'EEE')
             @section
             def partF():
                lineinfile('~/file1.txt', 'FFF')
             @section
             def partG():
                lineinfile('~/file1.txt', 'GGG')
             lineinfile('~/file1.txt', 'HHH')
             """)
    system(HOMELY('update') + ['~/repo1', '-o', 'partE'])
    assert contents(HOME + '/file1.txt') == "BBB\nEEE\nHHH\n"
    os.unlink(HOME + '/file1.txt')
    system(HOMELY('update') + ['~/repo1', '-o', 'partF', '-o', 'partG'])
    assert contents(HOME + '/file1.txt') == "FFF\nGGG\nHHH\n"
    system(HOMELY('update') + ['~/repo1', '-o', 'partF', '-o', 'partG'])
    assert contents(HOME + '/file1.txt') == "FFF\nGGG\nHHH\n"

    # ensure that --only isn't allowed with multiple repos
    system(HOMELY('update') + ['~/repo1', '~/repo2', '-o', 'something'],
           expecterror=1)

    # test that cleanup stuff doesn't happen when --only is used
    system(HOMELY('forget') + ['~/repo2', '~/repo3'])
    assert os.path.exists(HOME + '/file2.txt')
    assert os.path.exists(HOME + '/file3.txt')
    # note that this test also proves that you can use --only without naming a
    # repo as long as you only have one repo
    system(HOMELY('update') + ['-o', 'partE'])
    assert contents(HOME + '/file1.txt') == "FFF\nGGG\nHHH\nEEE\n"
    # these files are still hanging around because we keep using --only
    assert os.path.exists(HOME + '/file2.txt')
    assert os.path.exists(HOME + '/file3.txt')

    # finally do an update without --only, and file1 and file2 will be cleaned
    # up
    system(HOMELY('update'))
    assert not os.path.exists(HOME + '/file2.txt')
    assert not os.path.exists(HOME + '/file3.txt')
Пример #10
0
def test_homely_add_repolist(tmpdir, HOME):
    system = getsystemfn(HOME)

    # make a fake repo - create a dir, a folder, and a symlink
    repo1 = TempRepo(tmpdir, 'repo1')
    homedir1 = os.path.join(HOME, 'dir1')
    homelink1 = os.path.join(HOME, 'link1')
    homedir1file = os.path.join(homelink1, 'file.txt')
    assert not os.path.exists(homedir1)
    assert not os.path.islink(homelink1)
    contents(
        repo1.remotepath + '/HOMELY.py', """
             from homely.files import lineinfile, mkdir, symlink
             mkdir('~/dir1')
             symlink('~/dir1', '~/link1')
             lineinfile('~/link1/file.txt', 'Hello World')
             """)

    # add the repo and ensure that everything was created as expected
    system(HOMELY('add') + [repo1.url])

    assert repo1.installedin(HOME)
    assert os.path.isdir(homedir1)
    assert os.path.islink(homelink1)
    assert os.readlink(homelink1) == os.path.realpath(homedir1)
    assert contents(homedir1file) == "Hello World\n"

    # make another repo that creates more things
    repo2 = TempRepo(tmpdir, 'repo2')
    repo2file = os.path.join(HOME, 'file2.txt')
    assert not os.path.exists(repo2file)
    contents(
        repo2.remotepath + '/HOMELY.py', """
             from homely.files import lineinfile
             lineinfile('~/file2.txt', 'Hey There')
             """)
    system(HOMELY('add') + [repo2.url])
    assert repo2.installedin(HOME)
    assert contents(repo2file, "Hey There\n")

    checkrepolist(HOME, system, [repo1, repo2])

    # a 3rd repo, but we're going to clone it into our home dir manually
    repo3 = TempRepo(tmpdir, 'repo3')
    contents(
        repo3.remotepath + '/HOMELY.py', """
             from homely.files import lineinfile
             lineinfile('~/r3.txt', 'From R3')
             """)
    # where would it go in the home dir?
    localrepo3 = os.path.join(HOME, 'repo3')
    # use a Repo instance to clone it into our home dir manually
    from homely._vcs.testhandler import Repo
    Repo.frompath(repo3.url).clonetopath(localrepo3)

    # test adding a repo from the local dir
    assert not os.path.exists(HOME + '/r3.txt')
    system(HOMELY('add') + [localrepo3])
    assert contents(HOME + '/r3.txt') == 'From R3\n'
    checkrepolist(HOME, system, [repo1, repo2, repo3])

    # test that you can't add the same repo again
    system(HOMELY('add') + [repo2.url])
    checkrepolist(HOME, system, [repo1, repo2, repo3])

    # test that adding a repo with something like 'homely add .' doesn't record
    # a stupid path like '.'
    repo4 = TempRepo(tmpdir, 'repo4')
    contents(
        repo4.remotepath + '/HOMELY.py', """
             from homely.files import lineinfile
             lineinfile('~/r4.txt', 'From R4')
             """)
    localrepo4 = os.path.join(HOME, 'repo4')
    # use a Repo instance to clone it into our home dir manually
    from homely._vcs.testhandler import Repo
    Repo.frompath(repo4.url).clonetopath(localrepo4)
    system(HOMELY('add') + ['.'], cwd=localrepo4)
    checkrepolist(HOME, system, [repo1, repo2, repo3, repo4])
Пример #11
0
def test_homely_updatestatus(HOME, tmpdir):
    from homely._utils import RUNFILE, FAILFILE, UpdateStatus, STATUSCODES

    system = getsystemfn(HOME)
    jobstart = getjobstartfn(HOME)

    exit_ok = STATUSCODES[UpdateStatus.OK]
    exit_never = STATUSCODES[UpdateStatus.NEVER]
    exit_paused = STATUSCODES[UpdateStatus.PAUSED]
    exit_failed = STATUSCODES[UpdateStatus.FAILED]
    exit_running = STATUSCODES[UpdateStatus.RUNNING]

    # create a special HOMELY.py script that we can control easily by putting magic files in the
    # right places
    spinfile = HOME + '/spin'
    diefile = HOME + '/diediedie'

    xdir1 = HOME + '/xdir1'
    assert not os.path.isdir(xdir1)

    # verify that homely updatestatus thinks we have never run an update
    system(HOMELY('updatestatus'), expecterror=exit_never)

    # pause autoupdate, and then check the status again
    system(HOMELY('autoupdate') + ['--pause'])
    system(HOMELY('updatestatus'), expecterror=exit_paused)

    # pausing again don't change anything
    system(HOMELY('autoupdate') + ['--pause'])
    system(HOMELY('updatestatus'), expecterror=exit_paused)

    # unpause takes us back to the previous status
    system(HOMELY('autoupdate') + ['--unpause'])
    system(HOMELY('updatestatus'), expecterror=exit_never)

    # add our special repo with our special file
    repo1 = TempRepo(tmpdir, 'repo1')
    contents(repo1.remotepath + '/HOMELY.py',
             """
             import os, time, sys
             from homely.files import mkdir
             while os.path.exists(%(spinfile)r):
                time.sleep(0.01)
             assert not os.path.exists(%(diefile)r), "Incredibly bad things in %(diefile)s"
             mkdir('~/xdir1')
             """ % locals())
    system(HOMELY('add') + [repo1.url])
    assert os.path.isdir(xdir1)

    # verify that homely updatestatus thinks we have run an update
    system(HOMELY('updatestatus'))

    # use the spinfile to make homely update sit in the background while we test some more things
    contents(spinfile, "spin!")
    with jobstart(HOMELY('update')) as job:
        for _ in waitfor('Appearance of RUNFILE %s' % RUNFILE):
            if os.path.exists(RUNFILE):
                break
        # verify that updatestatus says we are currently running
        system(HOMELY('updatestatus'), expecterror=exit_running)

        # remove the spinfile so the background job can finish
        os.unlink(spinfile)

    # verify that no update is currently running, and that the last run was successful
    system(HOMELY('updatestatus'))

    # now touch the errorfile and try a new update
    contents(diefile, "boom!")
    system(HOMELY('update'), expecterror=1)

    # updatestatus should tell us that the previous run failed
    system(HOMELY('updatestatus'), expecterror=exit_failed)

    # the error file should exist
    assert os.path.exists(FAILFILE)
    # grab the name of the OUTFILE
    outfile = system(HOMELY('autoupdate') + ['--outfile']).strip()
    # note that a plain 'homely update' won't create the outfile for us
    assert not os.path.exists(outfile)

    # try and kick off an autoupdate daemon ... it should fail miserably because the previous
    # update has already failed
    system(HOMELY('autoupdate') + ['--daemon'], expecterror=1)

    # use autoupdate --reset to allow automatic updates to resume
    system(HOMELY('autoupdate') + ['--clear'])
    system(HOMELY('updatestatus'), expecterror=exit_ok)

    # try and kick off an autoupdate daemon again ... it should fail miserably because the previous
    # update was too recent
    system(HOMELY('autoupdate') + ['--daemon'], expecterror=1)

    # remove the TIMEFILE so that homely thinks an update has never been run before
    from homely._utils import TIMEFILE
    os.unlink(TIMEFILE)

    try:
        # we use the spinfile to make sure the next autoupdate is going to stall
        contents(spinfile, "spin!")
        contents(diefile, "boom!")
        system(HOMELY('autoupdate') + ['--daemon'])

        # wait for the RUNFILE to appear
        for _ in waitfor('Appearance of RUNFILE'):
            if os.path.exists(RUNFILE):
                break

        # assert that our status is "running"
        system(HOMELY('updatestatus'), expecterror=exit_running)
    finally:
        # remove the spinfile so that the daemon can finish
        os.unlink(spinfile)

    # wait for the runfile to disappear
    for _ in waitfor('Disappearance of RUNFILE %s' % RUNFILE):
        if not os.path.exists(RUNFILE):
            break

    # the autoupdate should have failed because of the diefile
    system(HOMELY('updatestatus'), expecterror=exit_failed)
    with open(outfile) as f:
        assert 'Incredibly bad things' in f.read()

    # let's do this again, but without the diefile
    os.unlink(diefile)
    system(HOMELY('autoupdate') + ['--clear'])
    # we also need to manually remove the timefile
    os.unlink(TIMEFILE)
    try:
        contents(spinfile, "spin!")
        system(HOMELY('autoupdate') + ['--daemon'])
        for _ in waitfor('Appearance of RUNFILE'):
            if os.path.exists(RUNFILE):
                break
        system(HOMELY('updatestatus'), expecterror=exit_running)
    finally:
        os.unlink(spinfile)
    for _ in waitfor('Disappearance of RUNFILE %s' % RUNFILE):
        if not os.path.exists(RUNFILE):
            break

    # updatestatus should show that the update was successful
    system(HOMELY('updatestatus'), expecterror=exit_ok)
Пример #12
0
def test_homely_update(HOME, tmpdir):
    system = getsystemfn(HOME)

    def _addfake(name, createfile):
        # create a fake repo and add it
        tr = TempRepo(tmpdir, name)
        tf = os.path.join(HOME, createfile)
        contents(tr.remotepath + '/HOMELY.py',
                 """
                 from homely.files import lineinfile
                 lineinfile('~/%s', 'Hello from %s')
                 """ % (createfile, name))
        assert not os.path.exists(tf)
        system(HOMELY('add') + [tr.url])
        assert contents(tf) == "Hello from %s\n" % name
        return tr

    template = ("""
                from homely.files import lineinfile
                lineinfile(%r, %r)
                """)

    # add some fake repos
    r1 = _addfake('repo1', 'file1.txt')
    r2 = _addfake('repo2', 'file2.txt')
    r3 = _addfake('repo3', 'file3.txt')

    # update the repos slightly, run an update, ensure all changes have gone
    # through (including cleanup of old content)
    contents(r1.remotepath + '/HOMELY.py', template % ('~/file1.txt', 'AAA'))
    contents(r2.remotepath + '/HOMELY.py', template % ('~/file2.txt', 'AAA'))
    contents(r3.remotepath + '/HOMELY.py', template % ('~/file3.txt', 'AAA'))
    system(HOMELY('update'))
    assert contents(HOME + '/file1.txt') == "AAA\n"
    assert contents(HOME + '/file2.txt') == "AAA\n"
    assert contents(HOME + '/file3.txt') == "AAA\n"

    # modify all the repos again
    contents(r1.remotepath + '/HOMELY.py', template % ('~/file1.txt', 'BBB'))
    contents(r2.remotepath + '/HOMELY.py', template % ('~/file2.txt', 'BBB'))
    contents(r3.remotepath + '/HOMELY.py', template % ('~/file3.txt', 'BBB'))
    # run an update again, but only do it with the 2nd repo
    system(HOMELY('update') + ['~/repo2'])
    # 1st and 3rd repos haven't been rerun
    assert contents(HOME + '/file1.txt') == "AAA\n"
    assert contents(HOME + '/file3.txt') == "AAA\n"
    # NOTE that the cleanup of the 2nd repo doesn't happen when we're doing a
    # single repo
    assert contents(HOME + '/file2.txt') == "AAA\nBBB\n"

    # run an update, but specify all repos - this should be enough to trigger
    # the cleanup
    system(HOMELY('update') + ['~/repo1', '~/repo3', '~/repo2'])
    assert contents(HOME + '/file1.txt') == "BBB\n"
    assert contents(HOME + '/file2.txt') == "BBB\n"
    assert contents(HOME + '/file3.txt') == "BBB\n"

    # modify the repos again, but run update with --nopull so that we don't get
    # any changes
    contents(r1.remotepath + '/HOMELY.py', template % ('~/file1.txt', 'CCC'))
    contents(r2.remotepath + '/HOMELY.py', template % ('~/file2.txt', 'CCC'))
    contents(r3.remotepath + '/HOMELY.py', template % ('~/file3.txt', 'CCC'))
    system(HOMELY('update') + ['~/repo1', '--nopull'])
    assert contents(HOME + '/file1.txt') == "BBB\n"
    assert contents(HOME + '/file2.txt') == "BBB\n"
    assert contents(HOME + '/file3.txt') == "BBB\n"
    system(HOMELY('update') + ['--nopull'])
    assert contents(HOME + '/file1.txt') == "BBB\n"
    assert contents(HOME + '/file2.txt') == "BBB\n"
    assert contents(HOME + '/file3.txt') == "BBB\n"

    # split r1 into multiple sections and just do one of them
    contents(r1.remotepath + '/HOMELY.py',
             """
             from homely.files import lineinfile
             from homely.general import section
             @section
             def partE():
                lineinfile('~/file1.txt', 'EEE')
             @section
             def partF():
                lineinfile('~/file1.txt', 'FFF')
             @section
             def partG():
                lineinfile('~/file1.txt', 'GGG')
             lineinfile('~/file1.txt', 'HHH')
             """)
    system(HOMELY('update') + ['~/repo1', '-o', 'partE'])
    assert contents(HOME + '/file1.txt') == "BBB\nEEE\nHHH\n"
    os.unlink(HOME + '/file1.txt')
    system(HOMELY('update') + ['~/repo1', '-o', 'partF', '-o', 'partG'])
    assert contents(HOME + '/file1.txt') == "FFF\nGGG\nHHH\n"
    system(HOMELY('update') + ['~/repo1', '-o', 'partF', '-o', 'partG'])
    assert contents(HOME + '/file1.txt') == "FFF\nGGG\nHHH\n"

    # ensure that --only isn't allowed with multiple repos
    system(HOMELY('update') + ['~/repo1', '~/repo2', '-o', 'something'], expecterror=1)

    # test that cleanup stuff doesn't happen when --only is used
    system(HOMELY('forget') + ['~/repo2', '~/repo3'])
    assert os.path.exists(HOME + '/file2.txt')
    assert os.path.exists(HOME + '/file3.txt')
    # note that this test also proves that you can use --only without naming a
    # repo as long as you only have one repo
    system(HOMELY('update') + ['-o', 'partE'])
    assert contents(HOME + '/file1.txt') == "FFF\nGGG\nHHH\nEEE\n"
    # these files are still hanging around because we keep using --only
    assert os.path.exists(HOME + '/file2.txt')
    assert os.path.exists(HOME + '/file3.txt')

    # finally do an update without --only, and file1 and file2 will be cleaned
    # up
    system(HOMELY('update'))
    assert not os.path.exists(HOME + '/file2.txt')
    assert not os.path.exists(HOME + '/file3.txt')
Пример #13
0
def test_homely_add_repolist(tmpdir, HOME):
    system = getsystemfn(HOME)

    # make a fake repo - create a dir, a folder, and a symlink
    repo1 = TempRepo(tmpdir, 'repo1')
    homedir1 = os.path.join(HOME, 'dir1')
    homelink1 = os.path.join(HOME, 'link1')
    homedir1file = os.path.join(homelink1, 'file.txt')
    assert not os.path.exists(homedir1)
    assert not os.path.islink(homelink1)
    contents(repo1.remotepath + '/HOMELY.py',
             """
             from homely.files import lineinfile, mkdir, symlink
             mkdir('~/dir1')
             symlink('~/dir1', '~/link1')
             lineinfile('~/link1/file.txt', 'Hello World')
             """)

    # add the repo and ensure that everything was created as expected
    system(HOMELY('add') + [repo1.url])

    assert repo1.installedin(HOME)
    assert os.path.isdir(homedir1)
    assert os.path.islink(homelink1)
    assert os.readlink(homelink1) == os.path.realpath(homedir1)
    assert contents(homedir1file) == "Hello World\n"

    # make another repo that creates more things
    repo2 = TempRepo(tmpdir, 'repo2')
    repo2file = os.path.join(HOME, 'file2.txt')
    assert not os.path.exists(repo2file)
    contents(repo2.remotepath + '/HOMELY.py',
             """
             from homely.files import lineinfile
             lineinfile('~/file2.txt', 'Hey There')
             """)
    system(HOMELY('add') + [repo2.url])
    assert repo2.installedin(HOME)
    assert contents(repo2file, "Hey There\n")

    checkrepolist(HOME, system, [repo1, repo2])

    # a 3rd repo, but we're going to clone it into our home dir manually
    repo3 = TempRepo(tmpdir, 'repo3')
    contents(repo3.remotepath + '/HOMELY.py',
             """
             from homely.files import lineinfile
             lineinfile('~/r3.txt', 'From R3')
             """)
    # where would it go in the home dir?
    localrepo3 = os.path.join(HOME, 'repo3')
    # use a Repo instance to clone it into our home dir manually
    from homely._vcs.testhandler import Repo
    Repo.frompath(repo3.url).clonetopath(localrepo3)

    # test adding a repo from the local dir
    assert not os.path.exists(HOME + '/r3.txt')
    system(HOMELY('add') + [localrepo3])
    assert contents(HOME + '/r3.txt') == 'From R3\n'
    checkrepolist(HOME, system, [repo1, repo2, repo3])

    # test that you can't add the same repo again
    system(HOMELY('add') + [repo2.url])
    checkrepolist(HOME, system, [repo1, repo2, repo3])

    # test that adding a repo with something like 'homely add .' doesn't record
    # a stupid path like '.'
    repo4 = TempRepo(tmpdir, 'repo4')
    contents(repo4.remotepath + '/HOMELY.py',
             """
             from homely.files import lineinfile
             lineinfile('~/r4.txt', 'From R4')
             """)
    localrepo4 = os.path.join(HOME, 'repo4')
    # use a Repo instance to clone it into our home dir manually
    from homely._vcs.testhandler import Repo
    Repo.frompath(repo4.url).clonetopath(localrepo4)
    system(HOMELY('add') + ['.'], cwd=localrepo4)
    checkrepolist(HOME, system, [repo1, repo2, repo3, repo4])