예제 #1
0
        /// <inheritdoc/>
        public async Task CloneOrOpenRepository(
            CloneDialogResult cloneDialogResult,
            object progress = null,
            CancellationToken?cancellationToken = null)
        {
            Guard.ArgumentNotNull(cloneDialogResult, nameof(cloneDialogResult));

            var repositoryPath = cloneDialogResult.Path;
            var url            = cloneDialogResult.Url;

            if (DestinationFileExists(repositoryPath))
            {
                throw new InvalidOperationException("Can't clone or open a repository because a file exists at: " + repositoryPath);
            }

            var repositoryUrl = url.ToRepositoryUrl();
            var isDotCom      = HostAddress.IsGitHubDotComUri(repositoryUrl);

            if (DestinationDirectoryExists(repositoryPath))
            {
                if (!IsSolutionInRepository(repositoryPath))
                {
                    teamExplorerServices.OpenRepository(repositoryPath);
                }

                if (isDotCom)
                {
                    await usageTracker.IncrementCounter(x => x.NumberOfGitHubOpens);
                }
                else
                {
                    await usageTracker.IncrementCounter(x => x.NumberOfEnterpriseOpens);
                }
            }
            else
            {
                var cloneUrl = repositoryUrl.ToString();
                await CloneRepository(cloneUrl, repositoryPath, progress, cancellationToken).ConfigureAwait(true);

                if (isDotCom)
                {
                    await usageTracker.IncrementCounter(x => x.NumberOfGitHubClones);
                }
                else
                {
                    await usageTracker.IncrementCounter(x => x.NumberOfEnterpriseClones);
                }
            }

            // Give user a chance to choose a solution
            teamExplorerServices.ShowHomePage();

            // Navigate to context for supported URL types (e.g. /blob/ URLs)
            var context = gitHubContextService.FindContextFromUrl(url);

            if (context != null)
            {
                gitHubContextService.TryNavigateToContext(repositoryPath, context);
            }
        }
예제 #2
0
        async Task <bool> IsDotComOrEnterpriseRepository(LocalRepositoryModel repository)
        {
            var cloneUrl = repository?.CloneUrl;

            if (cloneUrl == null)
            {
                // No active repository or remote
                return(false);
            }

            var isDotCom = HostAddress.IsGitHubDotComUri(cloneUrl.ToRepositoryUrl());

            if (isDotCom)
            {
                // This is a github.com repository
                return(true);
            }

            var connection = await connectionManager.Value.GetConnection(repository);

            if (connection != null)
            {
                // This is an enterprise repository
                return(true);
            }

            return(false);
        }
예제 #3
0
        protected async Task <RepositoryOrigin> GetRepositoryOrigin(UriString uri)
        {
            if (uri == null)
            {
                return(RepositoryOrigin.Other);
            }

            Debug.Assert(apiFactory != null, "apiFactory cannot be null. Did you call the right constructor?");
            SimpleApiClient = await apiFactory.Create(uri);

            var isdotcom = HostAddress.IsGitHubDotComUri(uri.ToRepositoryUrl());

            if (isdotcom)
            {
                return(RepositoryOrigin.DotCom);
            }
            else
            {
                var repo = await SimpleApiClient.GetRepository();

                if ((repo.FullName == ActiveRepoName || repo.Id == 0) && await SimpleApiClient.IsEnterprise())
                {
                    return(RepositoryOrigin.Enterprise);
                }
            }

            return(RepositoryOrigin.Other);
        }
예제 #4
0
        public AccountCacheItem(Account account)
        {
            Login  = account.Login;
            IsUser = (account as User) != null;
            Uri htmlUrl;

            IsEnterprise = Uri.TryCreate(account.HtmlUrl, UriKind.Absolute, out htmlUrl) &&
                           !HostAddress.IsGitHubDotComUri(htmlUrl);
            PrivateRepositoriesInPlanCount = account.Plan != null ? account.Plan.PrivateRepos : 0;
            OwnedPrivateRepositoriesCount  = account.OwnedPrivateRepos;
            AvatarUrl = account.AvatarUrl;
        }
예제 #5
0
        async Task UpdateContent(ILocalRepositoryModel repository)
        {
            log.Debug("UpdateContent called with {CloneUrl}", repository?.CloneUrl);

            LocalRepository = repository;
            Connection      = null;
            Content         = null;
            navigator.Clear();

            if (repository == null)
            {
                log.Debug("Not a git repository: {CloneUrl}", repository?.CloneUrl);
                Content = notAGitRepository;
                return;
            }
            else if (string.IsNullOrWhiteSpace(repository.CloneUrl))
            {
                log.Debug("Not a GitHub repository: {CloneUrl}", repository?.CloneUrl);
                Content = notAGitHubRepository;
                return;
            }

            var repositoryUrl = repository.CloneUrl.ToRepositoryUrl();
            var isDotCom      = HostAddress.IsGitHubDotComUri(repositoryUrl);
            var client        = await apiClientFactory.Create(repository.CloneUrl);

            var isEnterprise = isDotCom ? false : await client.IsEnterprise();

            if ((isDotCom || isEnterprise) && await IsValidRepository(client))
            {
                var hostAddress = HostAddress.Create(repository.CloneUrl);

                Connection = await connectionManager.GetConnection(hostAddress);

                if (Connection?.IsLoggedIn == true)
                {
                    log.Debug("Found a GitHub repository: {CloneUrl}", repository?.CloneUrl);
                    Content = navigator;
                    await ShowDefaultPage();
                }
                else
                {
                    log.Debug("Found a a GitHub repository but not logged in: {CloneUrl}", repository?.CloneUrl);
                    Content = loggedOut;
                }
            }
            else
            {
                log.Debug("Not a GitHub repository: {CloneUrl}", repository?.CloneUrl);
                Content = notAGitHubRepository;
            }
        }
예제 #6
0
        public Account(Octokit.Account account)
        {
            Login  = account.Login;
            IsUser = (account as User) != null;
            Uri htmlUrl;

            IsEnterprise = Uri.TryCreate(account.HtmlUrl, UriKind.Absolute, out htmlUrl) &&
                           !HostAddress.IsGitHubDotComUri(htmlUrl);
            PrivateReposInPlan            = account.Plan != null ? account.Plan.PrivateRepos : 0;
            OwnedPrivateRepos             = account.OwnedPrivateRepos;
            IsOnFreePlan                  = PrivateReposInPlan == 0;
            HasMaximumPrivateRepositories = OwnedPrivateRepos >= PrivateReposInPlan;
        }
        /// <inheritdoc/>
        public async Task CloneOrOpenRepository(
            CloneDialogResult cloneDialogResult,
            object progress = null)
        {
            Guard.ArgumentNotNull(cloneDialogResult, nameof(cloneDialogResult));

            var repositoryPath = cloneDialogResult.Path;
            var url            = cloneDialogResult.Url;

            if (DestinationFileExists(repositoryPath))
            {
                throw new InvalidOperationException("Can't clone or open a repository because a file exists at: " + repositoryPath);
            }

            var repositoryUrl = url.ToRepositoryUrl();
            var isDotCom      = HostAddress.IsGitHubDotComUri(repositoryUrl);

            if (DestinationDirectoryExists(repositoryPath))
            {
                teamExplorerServices.OpenRepository(repositoryPath);

                if (isDotCom)
                {
                    await usageTracker.IncrementCounter(x => x.NumberOfGitHubOpens);
                }
                else
                {
                    await usageTracker.IncrementCounter(x => x.NumberOfEnterpriseOpens);
                }
            }
            else
            {
                var cloneUrl = repositoryUrl.ToString();
                await CloneRepository(cloneUrl, repositoryPath, progress).ConfigureAwait(true);

                if (isDotCom)
                {
                    await usageTracker.IncrementCounter(x => x.NumberOfGitHubClones);
                }
                else
                {
                    await usageTracker.IncrementCounter(x => x.NumberOfEnterpriseClones);
                }
            }

            // Give user a chance to choose a solution
            teamExplorerServices.ShowHomePage();
        }
예제 #8
0
        async Task UpdateContent(ILocalRepositoryModel repository)
        {
            LocalRepository = repository;
            Connection      = null;

            Content = null;

            if (repository == null)
            {
                Content = notAGitRepository;
                return;
            }
            else if (string.IsNullOrWhiteSpace(repository.CloneUrl))
            {
                Content = notAGitHubRepository;
                return;
            }

            var repositoryUrl = repository.CloneUrl.ToRepositoryUrl();
            var isDotCom      = HostAddress.IsGitHubDotComUri(repositoryUrl);
            var client        = await apiClientFactory.Create(repository.CloneUrl);

            var isEnterprise = isDotCom ? false : client.IsEnterprise();

            if ((isDotCom || isEnterprise) && await IsValidRepository(client))
            {
                var hostAddress = HostAddress.Create(repository.CloneUrl);

                Connection = await connectionManager.GetConnection(hostAddress);

                if (Connection != null)
                {
                    navigator.Clear();
                    Content = navigator;
                    await ShowDefaultPage();
                }
                else
                {
                    Content = loggedOut;
                }
            }
            else
            {
                Content = notAGitHubRepository;
            }
        }
        protected async Task <bool> IsAGitHubRepo()
        {
            var uri = ActiveRepoUri;

            if (uri == null)
            {
                return(false);
            }

            SimpleApiClient = apiFactory.Create(uri);

            if (!HostAddress.IsGitHubDotComUri(uri.ToRepositoryUrl()))
            {
                var repo = await SimpleApiClient.GetRepository();

                return(repo.FullName == ActiveRepoName && SimpleApiClient.IsEnterprise());
            }
            return(true);
        }
예제 #10
0
        async Task <Repository> GetRepositoryInternal()
        {
            await sem.WaitAsync();

            try
            {
                if (owner == null)
                {
                    var ownerLogin     = OriginalUrl.Owner;
                    var repositoryName = OriginalUrl.RepositoryName;

                    if (ownerLogin != null && repositoryName != null)
                    {
                        var repo = await client.Repository.Get(ownerLogin, repositoryName);

                        if (repo != null)
                        {
                            hasWiki = await HasWikiInternal(repo);

                            isEnterprise = await IsEnterpriseInternal();

                            repositoryCache = repo;
                        }
                        owner = ownerLogin;
                    }
                }
            }
            // it'll throw if it's private or an enterprise instance requiring authentication
            catch (ApiException apiex)
            {
                if (!HostAddress.IsGitHubDotComUri(OriginalUrl.ToRepositoryUrl()))
                {
                    isEnterprise = apiex.IsGitHubApiException();
                }
            }
            catch {}
            finally
            {
                sem.Release();
            }

            return(repositoryCache);
        }
        protected async Task <bool> IsAGitHubRepo()
        {
            var uri = ActiveRepoUri;

            if (uri == null)
            {
                return(false);
            }

            Debug.Assert(apiFactory != null, "apiFactory cannot be null. Did you call the right constructor?");
            SimpleApiClient = apiFactory.Create(uri);

            var isdotcom = HostAddress.IsGitHubDotComUri(uri.ToRepositoryUrl());

            if (!isdotcom)
            {
                var repo = await SimpleApiClient.GetRepository();

                return((repo.FullName == ActiveRepoName || repo.Id == 0) && SimpleApiClient.IsEnterprise());
            }
            return(isdotcom);
        }
        /// <inheritdoc/>
        public async Task CloneRepository(
            string cloneUrl,
            string repositoryPath,
            object progress = null)
        {
            Guard.ArgumentNotEmptyString(cloneUrl, nameof(cloneUrl));
            Guard.ArgumentNotEmptyString(repositoryPath, nameof(repositoryPath));

            // Switch to a thread pool thread for IO then back to the main thread to call
            // vsGitServices.Clone() as this must be called on the main thread.
            await ThreadingHelper.SwitchToPoolThreadAsync();

            operatingSystem.Directory.CreateDirectory(repositoryPath);
            await ThreadingHelper.SwitchToMainThreadAsync();

            try
            {
                await vsGitServices.Clone(cloneUrl, repositoryPath, true, progress);

                await usageTracker.IncrementCounter(x => x.NumberOfClones);

                var repositoryUrl = new UriString(cloneUrl).ToRepositoryUrl();
                var isDotCom      = HostAddress.IsGitHubDotComUri(repositoryUrl);
                if (isDotCom)
                {
                    await usageTracker.IncrementCounter(x => x.NumberOfGitHubClones);
                }
                else
                {
                    // If it isn't a GitHub URL, assume it's an Enterprise URL
                    await usageTracker.IncrementCounter(x => x.NumberOfEnterpriseClones);
                }
            }
            catch (Exception ex)
            {
                log.Error(ex, "Could not clone {CloneUrl} to {Path}", cloneUrl, repositoryPath);
                throw;
            }
        }
예제 #13
0
        protected async Task <bool> IsGitHubRepo()
        {
            RefreshRepo();

            var uri = ActiveRepo?.CloneUrl;

            if (uri == null)
            {
                return(false);
            }

            SimpleApiClient = await ApiFactory.Create(uri);

            var isdotcom = HostAddress.IsGitHubDotComUri(uri.ToRepositoryUrl());

            if (!isdotcom)
            {
                var repo = await SimpleApiClient.GetRepository();

                return((repo.FullName == ActiveRepo.Name || repo.Id == 0) && SimpleApiClient.IsEnterprise());
            }
            return(isdotcom);
        }
예제 #14
0
        async Task UpdateContent(LocalRepositoryModel repository)
        {
            log.Debug("UpdateContent called with {CloneUrl}", repository?.CloneUrl);

            LocalRepository = repository;
            connectionSubscription?.Dispose();
            connectionSubscription = null;
            Connection             = null;
            Content = null;
            navigator.Clear();

            if (repository == null)
            {
                log.Debug("Not a git repository: {CloneUrl}", repository?.CloneUrl);
                Content = notAGitRepository;
                return;
            }
            else if (string.IsNullOrWhiteSpace(repository.CloneUrl))
            {
                if (repository.HasRemotesButNoOrigin)
                {
                    log.Debug("No origin remote");
                    Content = noRemoteOrigin;
                }
                else
                {
                    log.Debug("Not a GitHub repository: {CloneUrl}", repository?.CloneUrl);
                    Content = notAGitHubRepository;
                }

                return;
            }

            var repositoryUrl = repository.CloneUrl.ToRepositoryUrl();
            var isDotCom      = HostAddress.IsGitHubDotComUri(repositoryUrl);
            var client        = await apiClientFactory.Create(repository.CloneUrl);

            var isEnterprise = isDotCom ? false : await client.IsEnterprise();

            var notGitHubRepo = true;

            if (isDotCom || isEnterprise)
            {
                var hostAddress = HostAddress.Create(repository.CloneUrl);

                notGitHubRepo = false;

                Connection = await connectionManager.GetConnection(hostAddress);

                Connection?.WhenAnyValue(
                    x => x.IsLoggedIn,
                    x => x.IsLoggingIn,
                    (_, __) => Unit.Default)
                .Skip(1)
                .Throttle(TimeSpan.FromMilliseconds(100))
                .ObserveOn(RxApp.MainThreadScheduler)
                .Subscribe(_ => UpdateContent(LocalRepository).Forget());

                if (Connection?.IsLoggedIn == true)
                {
                    if (await IsValidRepository(client) == true)
                    {
                        log.Debug("Found a GitHub repository: {CloneUrl}", repository?.CloneUrl);
                        Content = navigator;
                        await ShowDefaultPage();
                    }
                    else
                    {
                        notGitHubRepo = true;
                    }
                }
                else if (Connection?.IsLoggingIn == true)
                {
                    log.Debug("Found a GitHub repository: {CloneUrl} and logging in", repository?.CloneUrl);
                    Content = null;
                }
                else if (Connection?.ConnectionError != null)
                {
                    log.Debug("Found a GitHub repository: {CloneUrl} with login error", repository?.CloneUrl);
                    loginFailed.Initialize(Connection.ConnectionError.GetUserFriendlyError(ErrorType.LoginFailed));
                    Content = loginFailed;
                }
                else
                {
                    log.Debug("Found a a GitHub repository but not logged in: {CloneUrl}", repository?.CloneUrl);
                    Content = loggedOut;
                }
            }

            if (notGitHubRepo)
            {
                log.Debug("Not a GitHub repository: {CloneUrl}", repository?.CloneUrl);
                Content = notAGitHubRepository;
            }
        }